Как установить заголовок ответа HTTP в промежуточном программном обеспечении, который не отбрасывается, когда контроллер MVC Core выдает исключение? - PullRequest
0 голосов
/ 19 февраля 2019

Следующая программа создает простой сайт ASP.NET MVC Core 2.2.0 с двумя маршрутами:

  • /success - возвращает строку «Успешный ответ».
  • /failure - выдает исключение, в результате чего возвращается 500

Кроме того, имеется промежуточное ПО, которое задает заголовок ответа HTTP X-Added-Key / X-Added-Value.Это делается с использованием события OnStarting, которое согласно документации 1015 * «добавляет делегат, который будет вызван непосредственно перед отправкой заголовков ответа клиенту».

Однако,я вижу, что мой HTTP-заголовок ответа стирается, когда MVC обрабатывает исключение для маршрута /failure;промежуточное ПО определенно поражено, но в ответе отсутствует заголовок ответа X-Added-Key HTTP.Я подозреваю, что это делается здесь .

Как мне установить заголовок ответа HTTP, чтобы MVC не отбрасывал его в случае исключения?Мой пример использования здесь заключается в том, что мы хотим вернуть идентификатор запроса, чтобы потребители API могли дать нам ссылку, если они хотели бы сообщить об ошибке, поэтому она должна быть возвращена независимо от того, обнаружил ли контроллер исключение.

using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Threading.Tasks;

namespace ResponseHeadersSanityCheck
{
    internal static class Program
    {
        static void Main(string[] args)
        {
            WebHost.CreateDefaultBuilder(args)
            .UseStartup<Startup>()
            .Build()
            .Run();
        }
    }

    public sealed class ExampleController : Controller
    {
        [HttpGet, Route("success")]
        public string Success() => "Success Response";

        [HttpGet, Route("failure")]
        public string Failure() => throw new Exception("Failure Response");
    }

    public sealed class Startup
    {
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddMvc();
        }

        public void Configure(IApplicationBuilder app)
        {
            app
                .Use(async (HttpContext context, Func<Task> next) =>
                {
                    context.Response.OnStarting(() =>
                    {
                        context.Response.Headers.Add("X-Added-Key", "X-Added-Value");
                        return Task.CompletedTask;
                    });
                    await next();
                })
                .UseMvc();
        }
    }
}

1 Ответ

0 голосов
/ 20 февраля 2019

Вы можете зафиксировать исключение между обработкой промежуточного программного обеспечения.

Попробуйте

app.Use(async (HttpContext context, Func<Task> next) =>
    {
        context.Response.OnStarting(() =>
        {
            context.Response.Headers.Add("X-Added-Key", "X-Added-Value");
            return Task.CompletedTask;
        });
        try
        {
            await next();
        }
        catch (Exception ex)
        {

        }
    }).UseMvc();

Обновление:

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    app.UseDeveloperExceptionPage();
    app.Use(async (HttpContext context, Func<Task> next) =>
        {
            context.Response.OnStarting(() =>
            {
                context.Response.Headers.Add("X-Added-Key", "X-Added-Value");
                return Task.CompletedTask;
            });
            await next();
        }).UseMvc();            
}

Обновление:

app.Use(async (HttpContext context, Func<Task> next) =>
    {
        context.Response.OnStarting(() =>
        {
            context.Response.Headers.Add("X-Added-Key", "X-Added-Value");
            return Task.CompletedTask;
        });
        //await next();
        try
        {
            await next();
        }
        catch (Exception ex)
        {
            context.Response.StatusCode = 500;
        }
    }).UseMvc();
...