如何通过控制器返回另一个控制器的部分视图?

83

我在Views\ABC文件夹中有一个XXX.cshtml文件,其控制器是ABC

我还在我的DEF控制器中有一个操作方法,返回一个Partialview("XXX" , xyzmodel)

我收到一个"视图未找到"的错误提示。

如何从其他控制器调用该视图

3个回答

168

通常视图属于特定的匹配控制器,支持其数据需求,或者如果在控制器之间共享(因此得名),则视图属于Views/Shared文件夹。

“答案”(但不推荐-请参见下文):

您可以通过指定完整路径(包括扩展名)从另一个控制器引用视图/部分视图,例如:

return PartialView("~/views/ABC/XXX.cshtml", zyxmodel);

或相对路径(没有扩展名),基于@Max Toro的答案


return PartialView("../ABC/XXX", zyxmodel);

但这并不是一个好主意

*注意:这是仅有的两个有效语法,不要使用ABC\\XXXABC/XXX或任何其他变化,因为它们都是相对路径,并且无法找到匹配项。

更好的替代方案:

您可以在视图中使用Html.Renderpartial,但也需要扩展名:

Html.RenderPartial("~/Views/ControllerName/ViewName.cshtml", modeldata);

使用@Html.Partial实现内联Razor语法:

@Html.Partial("~/Views/ControllerName/ViewName.cshtml", modeldata)
你可以使用没有扩展名的 ../controller/view 语法(再次感谢 @Max Toro):
@Html.Partial("../ControllerName/ViewName", modeldata)

注意:显然RenderPartial比Partial略快,但这并不重要。

如果你想实际调用另一个控制器,请使用:

@Html.Action("action", "controller", parameters)

推荐方案:@Html.Action

我个人倾向于使用@Html.Action,因为它允许每个控制器管理自己的视图,而不是从其他控制器交叉引用视图(这会导致大量像意大利面条一样混乱的代码)。

您通常只需传递所需的关键值(就像任何其他视图一样),例如对于您的示例:

@Html.Action("XXX", "ABC", new {id = model.xyzId })

这将执行ABC.XXX操作并在原地呈现结果。这使得视图和控制器保持分开自包含(即可重用)。

2014年9月更新:

我遇到了一种情况,无法使用@Html.Action,但需要根据actioncontroller名称创建视图路径。 为此,我向UrlHelper添加了这个简单的View扩展方法,因此您可以说return PartialView(Url.View("actionName", "controllerName"), modelData)

public static class UrlHelperExtension
{
    /// <summary>
    /// Return a view path based on an action name and controller name
    /// </summary>
    /// <param name="url">Context for extension method</param>
    /// <param name="action">Action name</param>
    /// <param name="controller">Controller name</param>
    /// <returns>A string in the form "~/views/{controller}/{action}.cshtml</returns>
    public static string View(this UrlHelper url, string action, string controller)
    {
        return string.Format("~/Views/{1}/{0}.cshtml", action, controller);
    }
}

4
@Html.Action是一个很好的选择。 - Arman
您推荐的方法会让我从视图中调用服务来检索我的部分模型,这是我想要避免的。 - Raimonds
@Raimonds 既然所有的操作都是在服务器端执行,你为什么要关心呢?尽可能将各个操作隔离开来。 - iCollect.it Ltd

11

控件按以下顺序搜索视图:

  • 首先在共享文件夹中查找
  • 然后在与当前控制器匹配的文件夹中查找(在您的情况下为 Views/DEF)

由于这些位置中都没有 xxx.cshtml,因此控件返回“未找到视图”错误。

解决方案:您可以使用视图的完整路径:

例如

 PartialView("~/views/ABC/XXX.cshtml", zyxmodel);

@TrueBlueAussie 谢谢更正。你讲得很清楚。这不是为了获得“最佳答案”和赞,只是分享......无论如何,感谢你的意见。 :) - Arun Chandran Chackachattil
确实。这就是为什么我也编辑了你的条目以改进它。 - iCollect.it Ltd

6

您可以简单地使用以下方法:

PartialView("../ABC/XXX")

我最初对这个语法持怀疑态度,但它很好用,包括默认控制器操作。你有相应的参考资料吗? - iCollect.it Ltd

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接