#c# #.net-core #asp.net-core-mvc #middleware
#c# #.net-ядро #asp.net-core-mvc #промежуточное программное обеспечение
Вопрос:
С использованием .NET Core, C #.
Я добавил промежуточное программное обеспечение при запуске, чтобы я мог форматировать ответы об ошибках << Это работает! Но, к сожалению, я почему-то, кажется, потерял ответ, когда они не являются ответами на ошибки. Должен ли я прочитать ответ, а затем записать ответ обратно?
public async Task Invoke(HttpContext context)
{
var body = context.Response.Body;
using (var newBody= new MemoryStream())
{
context.Response.Body = newBody;
await _next(context);
if (context.Response.StatusCode != 200 amp;amp; context.Response.StatusCode != 206)
{
context.Response.Body = body;
updatedBody.Seek(0, SeekOrigin.Begin);
var msg= new StreamReader(updatedBody).ReadToEnd();
if (msg.Length > 0) {
context.Response.ContentType = _messageParser.GetFormat();
var response = _messageParser.MakeItPretty(msg);
await context.Response.WriteAsync(response);
}
}
}
}
Комментарии:
1. Вы пропускаете ELSE, когда StatusCode не равен ни 200, ни 206.
2. @jdweng это должен быть ответ
Ответ №1:
Это потому, что вы удаляете newBody
поэтому, когда ответ не является ответом с ошибкой, тогда все тело ответа удаляется и теряется. Вы могли бы создать else
инструкцию и скопировать ответ в оригинал body
:
if (context.Response.StatusCode != 200 amp;amp; context.Response.StatusCode != 206)
{
...
}
else
{
context.Response.Body = body;
newBody.Seek(0, SeekOrigin.Begin);
await newBody.CopyTo(context.response.Body);
}
Или мое личное предпочтение заключается в создании пользовательского ErrorResult, который реализует IActionResult или наследует ObjectResult, где вы можете форматировать сообщение, используя свой объект вместо строки:
public class ErrorResult : ObjectResult
{
public ErrorResult(MyError error)
: base(error)
{
StatusCode = 400;
}
public override Task ExecuteResultAsync(ActionContext context)
{
var messageParser = context.HttpContext.RequestServices.GetService(typeof(IMessageParser));
ContentTypes.Add(messageParser.GetFormat());
<other modifications>
return base.ExecuteResultAsync(context);
}
а затем верните его в контроллеры
...
return new ErrorResult(new MyError(...));
...
Комментарии:
1. Спасибо! Прав ли я, полагая, что мой подход может оказаться довольно дорогостоящим? Используя «ожидание нового тела. Скопируйте в (контекст.ответ. Тело);» Я копирую исходный ответ, и поэтому, если это огромный объем данных, я дублирую его в памяти?
2. Мне нравится пользовательский подход ErrorResult. Спасибо
3. Я остановился на использовании пользовательского подхода ErrorResult, поскольку он намного более легкий.