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

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

Например, когда Account/Add выдает SqlException, я возвращаю Account/Add ответ с сообщением, которое хранится в TempData из промежуточного программного обеспечения исключений. Я уже сделал эти штуки с движком просмотра.

Я нашел этот метод расширения и использование для этой цели, с этим, вы можете вернуть все реализации IActionResult из промежуточного программного обеспечения, отличное расширение. Однако я не мог узнать, как вернуть мое обычное представление, которое находится в папке моих представлений, например Views/Account/Add.

ПО промежуточного слоя исключений

private readonly RequestDelegate _next;

public ExceptionHandler(RequestDelegate next)
{
    _next = next;
}
public async Task Invoke(HttpContext context)
{
    try
    {
        await _next.Invoke(context);
    }
    catch (Exception ex)
    {
        HandleException(context, ex);
    }
}

private void HandleException(HttpContext context, Exception exception)
{
    //handle exception, log it and other stuff...
    //....

    var result = new ViewResult
    {
        ViewName = context.Request.Path.ToString(),
    };
    //WithDanger is an extension method writes message to tempdata
    result.WithDanger("Error", exception.ToString());

    //Extension method
    context.WriteResultAsync(result);
}

Это то, что я пробовал, но это не работает, как я ожидал, он возвращает пустую страницу, кажется, он не запускает механизм просмотра бритвы для создания моей страницы запроса.

Как я могу заставить свое промежуточное ПО возвращать ViewResult с моим существующим представлением?


person ibubi    schedule 06.11.2018    source источник


Ответы (1)


Не хватает пары вещей. Чтобы вернуть представление с использованием относительного пути, вам нужно обрезать ведущую косую черту:

ViewName = context.Request.Path.ToString().TrimStart('/')

Вы также не ожидаете звонка WriteResultAsync. Измените его на что-то вроде

private TaskHandleException(HttpContext context, Exception exception)
{
    //handle exception, log it and other stuff...
    //....

    var result = new ViewResult
    {
        ViewName = context.Request.Path.ToString().TrimStart('/'),
    };
    //WithDanger is an extension method writes message to tempdata
    result.WithDanger("Error", exception.ToString());

    //Extension method
    return context.WriteResultAsync(result);
}

И убедитесь, что вы ожидаете вызова HandleException:

public async Task Invoke(HttpContext context)
{
    try
    {
        await _next.Invoke(context);
    }
    catch (Exception ex)
    {
        await HandleException(context, ex);
    }
}

Это должно сработать :)

person khellang    schedule 06.11.2018
comment
Спасибо, Кристиан, это была моя ошибка, я забыл изменить подписи. :) Однако прямо сейчас я получил ошибку маршрутизации, маршрутизация ищет мое представление внутри Views/Home/Home/ThrowErr вместо Views/Home/ThrowErr. У меня было тестовое действие Home/ThrowErr, просто условно выдает ошибку. (при первом req выдает ошибку, при втором возвращает представление для целей тестирования). У меня есть только маршрутизация mvc по умолчанию. Должен ли я использовать другой путь? - person ibubi; 06.11.2018
comment
Я попытался добавить представление в Views/Account под названием Add.cshtml. Когда я перехожу к /Account/Add и выбрасываю исключение, я получаю представление. Я не уверен, что заставляет его искать в Views/Home/Home .. - person khellang; 06.11.2018
comment
Обратите внимание, что это сработало, когда я использую соглашение о пути ../Controller/Action для ViewName - person ibubi; 07.11.2018