c#函数作为参数-重复方法结构
C# Function as parameter - Repeat method structure
我有多个具有不同签名的方法,每个方法都有一个带有自定义日志异常的try-catch块。(多个控制器结构相同).
public class TestController : BaseController
{
public static ActionResult One(int param1, string param2)
{
try
{
// Do something
}
catch (Exception e)
{
LogException(e.Message);
AddModelError(e.Message);
}
return View("ViwName1");
}
public static ActionResult Two(Date param3, bool param4)
{
try
{
// Do something
}
catch (Exception e)
{
LogException(e.Message);
AddModelError(e.Message);
}
return View("ViwName2");
}
}
我想知道是否有一种方法可以避免每个方法的try-catch阻塞,并执行另一个
public class TestController : BaseController
{
public static ActionResult One(int param1, string param2)
{
// Do something (*)
// Call "ActionWithTryCatch" method that has a "function argument" to "Do something (*)"
}
public ActionResult ActionWithTryCatch(MyDelegate del, string viewName)
{
try
{
return del.Invoke();
}
catch (Exception e)
{
LogException(e.Message);
AddModelError(e.Message);
}
return View(viewName);
}
}
我该怎么做呢?我见过使用委托的例子,但我知道那是强类型的,所以没有找到这样做的方法。谢谢!
您所描述的模式接近于面向方面编程(AOP)的一种形式。然而,如果你只是想将特定的Try Catch错误处理逻辑应用到控制器上的所有操作,那么可能不值得你引入整个AOP框架。相反,您可以利用HandleErrorAttribute
或覆盖控制器类的OnException
方法。
例如,你可以这样写你的控制器:
public class TestController
{
private TestService service;
public TestController(TestService service)
{
this.service = service;
}
public ActionResult One(int param1, string param2)
{
this.service.MethodOne(param1, param2);
return View("ViwName1");
}
public ActionResult Two(Date param3, bool param4)
{
this.service.MethodTwo(param3, param4);
return View("ViwName2");
}
protected override void OnException(ExceptionContext filterContext)
{
LogException(filterContext.Exception.Message);
AddModelError(filterContext.Exception.Message);
var errorView = new ViewResult { ViewName = "~/Path/To/Error/View" };
filterContext.Result = errorView;
}
}
如果你想把它抽象出来,那么你可以把覆盖的OnException逻辑移到一个基控制器类中,然后让你所有的控制器都继承自基控制器。
如果你想看到MVC中统一错误处理的其他方法,那么也可以查看这个博客:https://dusted.codes/demystifying-aspnet-mvc-5-error-pages-and-error-logging
根据我的评论,如果你坚持实现你所描述的模式,你可以使用gilmishal的答案的修改版本。
public class TestController
{
private TestService service;
public TestController(TestService service)
{
this.service = service;
}
public ActionResult One(int param1, string param2)
{
return this.ActionWithTryCatch(() => this.service.MethodOne(param1, param2), "ViwName1");
}
public ActionResult Two(Date param3, bool param4)
{
return this.ActionWithTryCatch(() => this.service.MethodTwo(param3, param4), "ViwName2");
}
public IActionResult ActionWithTryCatch(Action action, string viewName)
{
try
{
action.Invoke();
}
catch (Exception e)
{
LogException(e.Message);
AddModelError(e.Message);
}
return View(viewName);
}
}
如果你需要在js中传递参数给这个函数,你创建的这个方法将不能正常工作-所以我假设你只调用无参数的方法。
在这种情况下,你可以用Func<IActionResult>
代替MyDelegate
。
public TResult ActionWithTryCatch<TResult>(Func<TResult> del, string viewName)
{
try
{
return del.Invoke();
}
catch (Exception e)
{
LogException(e.Message);
AddModelError(e.Message);
throw;
}
}
这将更类似于您的javascript实现,并将在unhandledexception时返回500 HTTP结果。
你应该这样调用它,如果你想要IActionResult
返回类型-
ActionWithTryCatch<IActionResult>(MethodThatReturnsIActionResult, viewName);
我建议您查看泛型
- 下划线扩展方法和结构.js子类
- 处理此命名空间 JavaScript 结构的最佳方法是什么?
- 在条件(if)结构的条件语句中是否有定义变量的有效方法
- 将类似JavaScript的结构编译为静态,快速C++的最佳方法是什么?
- 具有 3 种可能性的 if 结构的最佳方法
- 遍历此数组结构的最佳方法
- 在JS中创建类似结构C++的最佳和有效方法
- 有没有办法在IntelliJ中查找JavaScript的方法结构
- 用于提取 javascript (.js) 类和方法结构的库
- Angularjs中ajax的单一方法体系结构
- 引用JSON树结构的分支的最佳方法是什么
- 为所有遵循类似ID结构的HTML对象创建更改侦听器的方法
- JavaScript方法结构之间的差异
- 从视图源下载html的简单方法,同时保留文件夹结构
- 套接字.IO代码结构:在哪里放置方法
- 在Javascript中迭代Json结构以定位谷歌地图标记的正确方法
- 在extjs4中是否有更好的方法使用以下数据结构创建条形图?
- 使用不同数据结构的ajax错误处理方法
- 是否有任何方法可以在我的Mustache.js模板中的嵌套结构中绕过名称冲突
- c#函数作为参数-重复方法结构