我的多个控制器操作有一套标准的故障处理行为。通常,我想要:
- 基于路由数据(如ID等)加载对象
- 如果路由数据未指向有效的对象(例如通过URL黑客),则通知用户该问题并返回HTTP 404未找到
- 验证当前用户是否对该对象具有适当的权限
- 如果用户没有权限,则告知用户该问题并返回HTTP 403禁止
- 如果以上步骤成功,则执行与该对象相关的特定动作(即在视图中呈现它)。
这些步骤非常规范化,我希望有可重用代码来实现这种行为。
我目前的解决方案是创建一个辅助方法,类似于以下内容:
public static ActionResult HandleMyObject(this Controller controller,
Func<MyObject,ActionResult> onSuccess) {
var myObject = MyObject.LoadFrom(controller.RouteData).
if ( myObject == null ) return NotFound(controller);
if ( myObject.IsNotAllowed(controller.User)) return NotAllowed(controller);
return onSuccess(myObject);
}
# NotAllowed() is pretty much the same as this
public static NotFound(Controller controller){
controller.HttpContext.Response.StatusCode = 404
# NotFound.aspx is a shared view.
ViewResult result = controller.View("NotFound");
return result;
}
问题在于Controller.View()是受保护的方法,因此无法从helper中访问。我尝试过显式创建一个新的ViewResult实例,但由于不知道可能出现的问题,对需要设置的属性有些谨慎。
在特定的Controller之外创建ViewResult的最佳方法是什么?
GetView()
的View()
公共版本,然后将你的帮助程序保留在单独的类中。你仍然需要将你的控制器传递到你的帮助程序中,这有点尴尬,但它确实允许组合而不是继承。 - devuxer