【发布时间】:2017-02-24 18:18:15
【问题描述】:
我想包装我所有的 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 核心的中间件。 asp.net core中没有TryGetContentValue、HttpError等东西。所以,我想先阅读响应正文:
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 并且我收到无法读取流的错误。如何正确包装响应?
【问题讨论】:
-
您到底想完成什么?是模型验证吗?异常处理?`
-
@Tseng 我更新了问题,添加了一些细节。
标签: c# asp.net-core asp.net-core-mvc asp.net5