我在ASP.NET MVC项目的Controller内部使用PostSharp方面进行异常处理。简化代码是这样的:
[ExceptionAspect(AspectPriority = 1)]
public ActionResult MarkeSettings()
{
try{
SaveData();
NotifyUser("success");
return RedirectToAction("A");
}
catch(Exception ex){
NotifyUser(ex.Message);
return RedirectToAction("B");
}
}
我的班级ExceptionAspect
继承自OnExceptionAspect
班级。在OnException(MethodExecutionArgs args)
方法中,我设置了args.FlowBehavior = FlowBehavior.Continue;
。
那么,如何摆脱这个try/catch
块并控制程序执行流程并对ReturnRedirectToAction()
采取适当的措施?我读到了Sharing state between advices,但无法弄清楚如何将其应用于我的问题。
答案 0 :(得分:3)
当您将ExceptionAspect
应用于控制器的方法时,它会使用try/catch
块包装该方法,并从引入的catch块中调用OnException(MethodExecutionArgs args)
。
这意味着您可以将常用异常处理代码从catch块移动到方面内的OnException
方法。我想你想在异常发生时将用户重定向到特定的操作。 RedirectToAction
是控制器的受保护方法,返回RedirectToRouteResult
。因此,您需要在RedirectToRouteResult
方法中构造并返回正确的OnException
实例。要更改方法的返回值,请将args.ReturnValue
设置为所需的值,并将args.FlowBehavior
设置为FlowBehavior.Return
。
以下是OnExceptionAspect
实施的示例:
[Serializable]
public class RedirectOnExceptionAttribute : OnExceptionAspect
{
public string ToAction { get; set; }
public override void OnException(MethodExecutionArgs args)
{
// NotifyUser(args.Exception.Message);
args.FlowBehavior = FlowBehavior.Return;
object controller = ((ControllerBase) args.Instance).ControllerContext.RouteData.Values["controller"];
args.ReturnValue = new RedirectToRouteResult(
new RouteValueDictionary
{
{"action", this.ToAction},
{"controller", controller}
});
}
}
应用于控制器方法:
[RedirectOnException(ToAction = "B")]
public ActionResult MarkeSettings()
{
SaveData();
NotifyUser("success");
return RedirectToAction("A");
}