在ASP.NET MVC中的控制器之外创建ViewResults

Cra*_*ker 10 asp.net-mvc controller

我的一些控制器操作具有一组标准的故障处理行为.一般来说,我想:

  • 根据路径数据(ID等)加载对象
    • 如果Route Data未指向有效对象(例如:通过URL hacking),则通知用户该问题并返回HTTP 404 Not Found
  • 验证当前用户是否具有该对象的适当权限
    • 如果用户没有权限,请通知用户该问题并返回HTTP 403 Forbidden
  • 如果上述内容成功,则使用特定于操作的对象执行某些操作(即:在视图中呈现它).

这些步骤是如此标准化,我希望有可重用的代码来实现该行为.

我目前的攻击计划是使用辅助方法来执行以下操作:

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;
}
Run Code Online (Sandbox Code Playgroud)

这里的问题是Controller.View()是一个受保护的方法,因此无法从帮助程序访问.我已经看过明确地创建一个新的ViewResult实例,但是有足够的属性来设置我在不知道陷阱的情况下这么做是很谨慎.

从特定控制器外部创建ViewResult的最佳方法是什么?

det*_*lor 6

刚刚阅读这篇文章,因为我从动作过滤器中遇到了同样的问题.我的解决方案是明确地创建视图操作.这基于受MVC源的受保护View()方法,因此它应填充所需的属性.无论如何,似乎没有问题.

public static NotFound(Controller controller){
    controller.HttpContext.Response.StatusCode = 404;

    ViewResult result = new ViewResult {
            ViewName = "NotFound",
            ViewData = controller.ViewData,
            TempData = controller.TempData
        };
    return result;
}
Run Code Online (Sandbox Code Playgroud)

有点晚了,但这对我有用.


Cra*_*ker 5

在我写这篇文章的时候,我想到了一种方法。

与其将上面的代码放在帮助器中,我可以将它放入 Controller 的子类中,然后为我的实际控制器子类化这个类。这将允许我调用受保护的 View() 方法。

我不太喜欢这个,因为它需要继承才能工作,但它仍然是一种选择。