ExceptionHandling: если метод контроллера возвращает json, вернуть json, если View, то вернуть Redirect - PullRequest
3 голосов
/ 30 апреля 2019

Я бы хотел получить что-то вроде этого:

Если в методе, возвращающем Json, было сгенерировано исключение, тогда возвращается new Json(new { success = false, error = "unknown" });

, но если метод возвращает View, тогда возвращается Redirect

public async Task Invoke(HttpContext ctx)
{
    try
    {
        await next(ctx);
    }
    catch (Exception ex)
    {
        HandleException(ctx, ex);
    }
}

private static void HandleException(HttpContext context, Exception ex)
{
    // some logger
    LoggerService.Log(ex);

    context.Response.Redirect("/Error/ErrorPage");
}

Как определить, куда был отправлен запрос?Я имею в виду, как получить тип метода, к которому был отправлен запрос?

, потому что я хотел бы сделать что-то вроде typeof(targetMethod), чтобы определить, например, JsonResult или нет

Ответы [ 2 ]

3 голосов
/ 30 апреля 2019

Звучит так, будто вы пытаетесь обработать исключение, выданное методом Action. Если это так, ядро ​​ASP.NET имеет встроенную IExceptionFilter, которая подходит для этого:

Фильтр, который запускается после того, как действие сгенерировало исключение.

Для достижения цели создайте CustomExceptionFilter:

public class CustomExceptionFilter : IExceptionFilter
{
    private ILogger<CustomExceptionFilter> _logger;

    public CustomExceptionFilter(ILogger<CustomExceptionFilter> logger)
    {
        this._logger = logger;
    }

    public void OnException(ExceptionContext context)
    {
        var ex = context.Exception;
        var c = (ControllerActionDescriptor) context.ActionDescriptor;

        if(c == null){
            context.Result = new StatusCodeResult(500);
        } else if (typeof(JsonResult) == c.MethodInfo.ReturnType) {
            context.Result = new JsonResult(new { success = false, error = "unknown" });
        } else {
            // Redirect
            this._logger.LogCritical(ex,ex.Message);
            context.Result = new RedirectResult("/Error/ErrorPage");
        }
    }
}

и зарегистрируйте этот фильтр, как показано ниже:

services.AddMvc(opts => {
    opts.Filters.Add(typeof(CustomExceptionFilter));
});

у меня нормально работает.

1 голос
/ 30 апреля 2019

Здесь вам нужно немного подумать:

string methodName = ControllerContext.RouteData.Values["action"].ToString();
Assembly asm = Assembly.GetExecutingAssembly();

var methodInfo = asm.GetTypes()
    .Where(type => typeof(Controller).IsAssignableFrom(type)) //filter controllers
    .SelectMany(type => type.GetMethods())
    .Where(method => method.IsPublic)
    .Where(x => x.DeclaringType != null)
    .Where(x => x.Name == methodName)
    .SingleOrDefault();

if (methodInfo == null)
{
    return null; // Method wasn't found
}

if (typeof(JsonResult) == methodInfo.ReturnType)
{
    // Return JSON
}
else if (typeof(JsonResult) == methodInfo.ReturnType)
{
    // Redirect
}
else
{
    // Exception handling
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...