ExceptionHandling:如果控制器方法返回json然后返回json,如果View然后返回Redirect

问题描述 投票:3回答:2

我想要实现这样的目标:

如果在返回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

c# asp.net-core .net-core
2个回答
3
投票

听起来你正试图处理Action方法抛出的异常。如果是这种情况,ASP.NET Core有一个内置的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
投票

你需要在这里反思一下:

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
}
© www.soinside.com 2019 - 2024. All rights reserved.