gpt4 book ai didi

c# - 包装所有响应

转载 作者:太空狗 更新时间:2023-10-29 23:49:46 25 4
gpt4 key购买 nike

我想包装我所有的 http 响应。
例如,我们有一个返回一些 JSON 数据的操作:

public IActionResult Get() 
{
var res = new
{
MessageBody = "Test",
SomeData = 1
};

return Ok(res);
}

我希望我的回复看起来像:

{    
"StatusCode":200,
"Result":
{
"MessageBody ":"Test",
"SomeData":1
}
}

如果有错误,则响应中必须包含 ErrorMessage 字段。

在mvc 5中我使用了DelegationHandler,但是在asp.net core中这个类没有实现。现在,我们必须使用中间件。

这是 mvc 5 的代码:

public class WrappingHandler : DelegatingHandler
{
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
var response = await base.SendAsync(request, cancellationToken);

return BuildApiResponse(request, response);
}

private static HttpResponseMessage BuildApiResponse(HttpRequestMessage request, HttpResponseMessage response)
{
object content;
string errorMessage = null;

if (response.TryGetContentValue(out content) && !response.IsSuccessStatusCode)
{
HttpError error = content as HttpError;

if (error != null)
{
content = null;
errorMessage = error.Message;

#if DEBUG
errorMessage = string.Concat(errorMessage, error.ExceptionMessage, error.StackTrace);
#endif
}
}

var newResponse = request.CreateResponse(response.StatusCode, new ApiResponse(response.StatusCode, content, errorMessage));

foreach (var header in response.Headers)
{
newResponse.Headers.Add(header.Key, header.Value);
}

return newResponse;
}
}

还有,asp.net core 的中间件。 asp.net core 中没有TryGetContentValueHttpError 等东西。所以,我试图先阅读响应正文:

 public class FormatApiResponseMiddleware
{
private readonly RequestDelegate _next;

public FormatApiResponseMiddleware(RequestDelegate next)
{
_next = next;
}

private bool IsSuccessStatusCode(int statusCode)
{
return (statusCode >= 200) && (statusCode <= 299);

}

public async Task Invoke(HttpContext context)
{
object content = null;
string errorMessage = null;

if (!IsSuccessStatusCode(context.Response.StatusCode))
{
content = null;
//how to get error
}

var body= context.Response.Body;
}
}

但是,Body 流有 CanRead 等于 false 并且我收到无法读取流的错误。如何正确包装响应?

最佳答案

我建议使用 ExceptionHandlerMiddleware作为关于如何实现中间件的模板/示例。

例如,当响应已经开始时,你应该知道大小写

// We can't do anything if the response has already started, just abort.
if (context.Response.HasStarted)
{
_logger.LogWarning("The response has already started, the error handler will not be executed.");
throw;
}

或者如果你想替换它,不要忘记清除当前响应:

context.Response.Clear();

此外,也许您会发现重用它很有用,并实现您自己的错误处理程序而不是完整的中间件。这样您就可以向客户端发送自定义 JSON 错误。为此,定义一个类来表示您的自定义错误:

public class ErrorDto
{
public int Code { get; set; }
public string Message { get; set; }

// other fields

public override string ToString()
{
return JsonConvert.SerializeObject(this);
}
}

然后在Configure方法中注册一个异常处理中间件。注意中间件的注册顺序,确保在 MVC 之前注册例如:

app.UseExceptionHandler(errorApp =>
{
errorApp.Run(async context =>
{
context.Response.StatusCode = 500; // or another Status
context.Response.ContentType = "application/json";

var error = context.Features.Get<IExceptionHandlerFeature>();
if (error != null)
{
var ex = error.Error;

await context.Response.WriteAsync(new ErrorDto()
{
Code = 1, //<your custom code based on Exception Type>,
Message = ex.Message // or your custom message
// … other custom data
}.ToString(), Encoding.UTF8);
}
});
});

关于c# - 包装所有响应,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40058017/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com