【问题标题】:Display a view from another controller in ASP.NET MVC在 ASP.NET MVC 中显示来自另一个控制器的视图
【发布时间】:2010-10-27 03:54:13
【问题描述】:

是否可以显示另一个控制器的视图?

比如说我有一个CategoriesController 和一个Category/NotFound.aspx 视图。在CategoriesController 中,我可以轻松返回View("NotFound")

现在假设我有一个ProductsController 和一个添加产品的操作和视图。但是,此操作需要我们有一个类别来添加产品。例如,Products/Add/?catid=10

如果我找不到基于catid 的类别,我想从类别控制器显示NotFound 视图,而不是在产品控制器下创建CategoryNotFound 视图。

这是可能的还是我以错误的方式构建事物?有什么好办法吗?

【问题讨论】:

    标签: asp.net asp.net-mvc views controllers


    【解决方案1】:

    是的。默认情况下,ASP.NET MVC 首先检查\Views\[Controller_Dir]\,但之后,如果没有找到视图,它会检查\Views\Shared

    共享目录专门用于跨多个控制器共享视图。只需将您的视图添加到 Shared 子目录即可。

    如果你这样做return View("~/Views/Wherever/SomeDir/MyView.aspx"),你可以返回任何你想要的视图。

    【讨论】:

    • 谢谢,这听起来像是我应该使用的解决方案。我仍然想知道是否可以显示来自另一个控制器的视图。我猜这违反了 MVC 中的某些规则?
    • 在你上面描述的情况下,是的,你应该使用共享文件夹。
    • 是的,这也是可能的。如果您确实返回 View("~/Views/Wherever/SomeDir/MyView.aspx") 您可以返回任何您想要的视图。这本身并不违反任何特定规则,但是,ASP.Net MVC 完全是关于“约定优于配置”。换句话说,该框架是为使用某些约定自动运行而构建的,您应该尽可能利用它。
    • 感谢您的解释。我不知道 Views 可以这样称呼。共享目录当然可以完美运行 :)
    • 我不在 Controller 中,所以我必须使用 new ViewResult { ViewName = "~/Views/Error/Unauthorised.cshtml" }; 并且它有效
    【解决方案2】:

    你可以使用:

    return View("../Category/NotFound", model);
    

    它在 ASP.NET MVC 3 中经过测试,但也应该在 ASP.NET MVC 2 中工作。

    【讨论】:

    • 在 MVC 2 中工作,结果证明这是我正在处理的异常情况的最干净的解决方案。
    • Resharper 会将该链接报告为错误,但它仍然有效。
    • @CodeMonkeyKing - Resharper 7(在 VS2012 中)正确识别格式为 "~/Views/Category/NotFound.cshtml" 的路径。
    • 值得注意的是:此解决方案适用于显示模式,例如如果您有“/Category/NotFound.Mobile.cshtml”视图。
    【解决方案3】:

    是的,这是可能的。 像这样返回一个RedirectToAction() 方法:

    return RedirectToAction("ActionOrViewName", "ControllerName");
    

    【讨论】:

    • 我相信这应该作为 RedirectToAction("ActionOrView", "Controller", null) 否则第二个参数是 routeValues
    • 但在这种情况下,您必须在控制器中实际编写操作,这与 View 解决方案不同。
    • @tobbenb3 与硬编码结果相比,这是一个更好的解决方案。无论哪种方式,您都不应该传入路径字符串。
    【解决方案4】:

    你试过RedirectToAction吗?

    【讨论】:

    • 我会说这是任何不希望查看共享文件夹的人的 MVC,请注意,对于所有其他解决方案(例如使用直接路径),任何人都试图重构视图不必考虑它也在另一个控制器中使用,从而导致不可预测的行为
    • 不重定向怎么样?
    • 比将视图移动到共享文件夹更好的解决方案
    • 此解决方案需要对控制器进行操作,View(directPath) 无需任何操作即可呈现输出。当你添加一个动作时,你需要考虑隐藏它以防止通过 url 直接访问,它会在浏览器历史记录中生成步骤等。但是,是的,这是我要走的路。
    • RedirectToAction 向浏览器发送 302 响应代码。当您尝试显示 404 not found 页面时,这是不合适的。也就是说,这个解决方案似乎有效,但会混淆搜索引擎。
    【解决方案5】:

    是的,你可以。像这样返回一个动作:

    return RedirectToAction("View", "Name of Controller");
    

    一个例子:

    return RedirectToAction("Details/" + id.ToString(), "FullTimeEmployees");
    

    这种方法会调用GET方法

    您也可以像这样将值传递给操作:

    return RedirectToAction("Details/" + id.ToString(), "FullTimeEmployees", new {id = id.ToString(), viewtype = "extended" });
    

    【讨论】:

    • 我将如何使用这种方法发送对象?
    • 看看@Djeroen
    • 您不是在返回视图,而是在调用一个动作。
    【解决方案6】:

    您也可以从JavaScript/jQuery 调用任何控制器。假设您有一个控制器返回 404 或其他一些用户控件/页面。然后,通过某些操作,从您的客户端代码中,您可以调用某个地址来触发您的控制器并以HTML 格式返回结果 您的客户端代码可以获取此返回的结果并将其放在页面中您想要的任何位置...

    【讨论】:

    • 我不知道。这听起来像是我将来可能会使用的东西。是的,mvc 摇滚 :)
    【解决方案7】:

    使用此代码,您可以获得任何控制器:

    var controller = DependencyResolver.Current.GetService<ControllerB>();
    controller.ControllerContext = new ControllerContext(this.Request.RequestContext, 
    controller);
    

    【讨论】:

    • 翻译:使用此代码,您可以获得任何控制器:[code],问候,
    • 虽然此代码可能会回答问题,但提供有关它如何和/或为什么解决问题的额外上下文将提高​​答案的长期价值。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-03-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-13
    相关资源
    最近更新 更多