Я управляю ошибкой кодов состояния, используя

app.UseStatusCodePagesWithRedirects("/StatusCodeError/{0}");

Но когда в области возникает ошибка, страница перенаправляется за пределы области и отображает страницу с общей ошибкой. Как убедиться, что страница с ошибкой для конкретной области отображается, если в этой области возникает ошибка?

1
1100010 27 Фев 2021 в 22:27

1 ответ

Лучший ответ

Нет точки расширяемости для изменения поведения app.UseStatusCodePagesWithRedirects, location форматируется внутренне с использованием string.Format и только с одним аргументом, переданным в заполнитель {0} для кода состояния. Таким образом, во время вызова (передача в формате location) у нас нет понимания о area, которое является значением маршрута, доступным только в контексте обработки запроса. Таким образом, вы можете обратиться к источнику для StatusCodePagesExtensions и увидеть, что UseStatusCodePagesWithRedirects просто зависит от перегрузки метода расширения StatusCodePagesExtensions.UseStatusCodePages, вы можете свободно копировать код и изменять его для создания другой версии of UseStatusCodePagesWithRedirects, который принимает формат location, который поддерживает некоторые аргументы из значений маршрута. Вот простой для вас:

public static class StatusCodePagesApplicationBuilderExtensions
{
    public static IApplicationBuilder UseStatusCodePagesWithRouteDataAndRedirects(this IApplicationBuilder app, string locationFormat)
    {
        if (app == null)
        {
            throw new ArgumentNullException(nameof(app));
        }

        var shouldPrependPathBase = locationFormat.StartsWith("~");
        locationFormat = shouldPrependPathBase ? locationFormat.Substring(1) : locationFormat;

        return app.UseStatusCodePages(context =>
        {
            //here is the point we can evaluate for the actual location
            //by replacing the placeholders with route value                
            var location = Regex.Replace(locationFormat, @"\{[^}]+\}", m => {
                //ignore the placeholder for status code
                if (m.Value == "{0}") return m.Value;
                var routeKey = m.Value.Trim('{', '}');                    
                var routeValue = context.HttpContext.GetRouteValue(routeKey);
                return routeValue?.ToString();
            });
            location = string.Format(CultureInfo.InvariantCulture, location, context.HttpContext.Response.StatusCode);
            location = (shouldPrependPathBase ? context.HttpContext.Request.PathBase : PathString.Empty) + location;
            context.HttpContext.Response.Redirect(location);
            return Task.CompletedTask;
        });
    }
}

Теперь вы можете включать любые данные маршрута в формате location, в вашем случае вам просто нужен area, поэтому код будет таким:

app.UseStatusCodePagesWithRouteDataAndRedirects("/{area}/StatusCodeError/{0}");

ПРИМЕЧАНИЕ : будьте осторожны с перенаправлением, вы можете столкнуться с ошибкой вроде слишком много перенаправлений из-за перенаправления на URL-адрес, который, в свою очередь, вызывает цикл перенаправлений.

0
King King 28 Фев 2021 в 18:08