我想要回复所有的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核心中,这个类没有实现。现在,我们必须使用中间件。
这是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核心中没有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
,我收到无法读取流的错误。如何正确包装回复?
答案 0 :(得分:0)
我建议使用ExceptionHandlerMiddleware
作为模板/示例,说明应该如何实现中间件。
例如,您应该了解案例,当响应已经开始时
.cb-input {
width: 100%;
min-height: 45px;
max-height: 80px;
}
.cb-form {
overflow: hidden;
width: 100%;
height: 100%;
}
.cb-input textarea{
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
padding: 6px 14px 2px 10px;
width: 100%;
height: 100%;
font-family: Roboto;
font-size: 14px;
border: none;
resize: none;
overflow-y: auto;
}
或者如果要替换它,请不要忘记清除当前的响应:
// 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;
}
此外,也许您会发现只是为了重用它,并实现自己的错误处理程序而不是完整的中间件。这样您就可以向客户端发送自定义JSON错误。为此,请定义一个代表您的自定义错误的类:
context.Response.Clear();
然后在public class ErrorDto
{
public int Code { get; set; }
public string Message { get; set; }
// other fields
public override string ToString()
{
return JsonConvert.SerializeObject(this);
}
}
方法中注册异常处理程序中间件。注意中间件的注册顺序,并确保它在MVC之前注册,例如:
Configure