我想要实现以下目标:
如果在返回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
答案 0 :(得分: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 :(得分: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
}