问题 具有相对路径的ASP.Net MVC和RenderPartial


我一直在玩ASP.NET MVC并且有一个问题。或者也许我担心我这样做错了。只是在一个跛足的地方工作,伸展我的翅膀。对不起,这个问题根本不简洁。

好的,这是场景。当用户访问home / index时,页面应显示产品列表和文章列表。文件布局是这样的(DAL是我的数据访问层):

控制器
    家
        指数

查看
    家
        索引继承自ViewPage
    产品
        List继承自ViewUserControl <IEnumerable <DAL.Product >>
        单个继承自ViewUserControl <DAL.Product>
    文章
        List继承自ViewUserControl <IEnumerable <DAL.Article >>
        单个继承自ViewUserControl <DAL.Article>
Controllers.HomeController.Index produces a View whose ViewData contains two entries, a IEnumerable<DAL.Product> and a IEnumerable<DAL.Article>.

View.Home.Index will use those view entries to call:
Html.RenderPartial("~/Views/Product/List.ascx", ViewData["ProductList"])
and Html.RenderPartial("~/Views/Article/List.ascx", ViewData["ArticleList"])

View.Product.List will call
foreach(Product product in View.Model)
    Html.RenderPartial("Single", product);

View.Article.List does something similar to View.Product.List

然而,这种方法失败了这种方法对我来说很有意义,但也许对这些MVC平台有更多经验的人会认识到更好的方法。

以上在View.Product.List中产生错误。打电话给 Html.RenderPartial("Single",...) 抱怨没有找到“单一”视图。错误表明:

无法找到部分视图“单个”。搜索了以下位置:
〜/浏览/首页/ Single.aspx
〜/浏览/首页/ Single.ascx
〜/查看/共享/ Single.aspx
〜/查看/共享/ Single.ascx

因为我从Product中的视图调用RenderAction(),所以我希望运行时在Views \ Product中查找“Single”视图。然而,似乎查找是相对于调用原始视图(/ Controller / Home invoked / Views / Product)而不是当前视图的控制器。

所以我可以通过更改Views \ Product来解决这个问题,这样:

View.Product.List will call
foreach(Product product in View.Model)
    Html.RenderPartial(“〜/查看/产品/ Single.ascx”, product);

代替

View.Product.List will call
foreach(Product product in View.Model)
    Html.RenderPartial(“单”, product);

这个修复工作,但..我不明白为什么我需要指定视图的完整路径。对于我来说,相对于当前视图的路径而不是原始控制器的视图路径来解释相对名称是有意义的。我想不出任何有用的情况,即相对于控制器的视图而不是当前视图解释名称是有用的(除了在它们相同的典型情况下)。

大约在这个时候我应该有一个问号?强调这实际上是一个问题。


11499
2017-11-10 07:28


起源

偶然发现了寻找相关的东西(我意识到它超过6个月)。但是你提到使用RenderAction(),但是你的所有例子都使用RenderPartial(),这是一个错字吗?我会假设RenderAction(而不是RenderPartial)应该在这种情况下工作? - Simon Fox


答案:


因为我正在调用RenderAction()   从产品中的视图

...

我不明白我为什么需要   指定视图的完整路径。   这对我有意义   要解释的相对名称   相对于当前视图的路径   而不是原来的控制器   查看路径

我认为你误解的部分是缺乏更好或官方术语的“执行地点”。路径与您的视图不相关,甚至不是您所说的“控制器视图”。它们与您的请求URL相关,后者定义了控制器上下文。我可能不是说得很好,但是如果你花了一点时间在Reflector中查看URL和路由是如何解决的,我认为这一切都会落到你的脑海中。


5
2017-11-11 20:33



你说的是有道理的。 - Frank Schwieterman
这种行为是有道理的,但对我来说没有意义,为什么那将是设计。我不认为视图中的代码应该知道从中调用它的路径。 - Frank Schwieterman


[编辑:

我在想,你有2个案例:

  • Home控制器是唯一一个引用产品/文章列表用户控件的控制器
  • 用户控件由多个控制器共享

在第一种情况下,视图用户控件确实属于家庭控制器,将它们放在家庭控制器文件夹中是有意义的。在第二种情况下,将它们放在共享文件夹中是有意义的,因为它们将由控制器共享。

在任何一种情况下,也许您可​​以将它们放在子文件夹中。喜欢Views / Home / Products然后尝试RendarPartial(“产品/单一”),看看会发生什么?我不知道它是否会尝试将其解析为:Home / Product / Single然后Shared / Product / Single或not。如果子文件夹工作,它似乎允许产品和文章的逻辑分离,同时显示它们仍然是家庭控制器的成员或所有控制器共享。

]

查看Steve Sanderson的博客文章:

http://blog.codeville.net/2008/10/14/partial-requests-in-aspnet-mvc/

你正在做的事情没有错,但它确实违反了视图/控制器文件夹名称的惯例。也就是说,想要定义与控制器无关的视图用户控件并嵌套它们似乎是有效的。所以我不知道!

无论如何,该链接只描述了一种方法而不是使用RenderPartial来呈现一个使用控件,它定义了一个RenderPartialRequest方法,该方法呈现控制器动作的返回值(在您的情况下是一个用户控件)。因此,您可以使用返回用户控件的动作列表添加“产品和文章”控制器,然后从“主页/索引”视图中调用这两个操作。这对我来说似乎更直观,但只是一种观点。

他还提到了来自MVC Contrib的子控制器,我很确定希望这样的东西成为ASP.NET MVC版本的一部分。


4
2017-11-11 18:14



RenderPartial(“Product / Single”)将适用于Product View文件夹中的子文件夹。我刚刚将这种技术用于一些部分视图,我希望将其保存在与控制器关联的其余ASPX / ASCX的子文件夹中。 - RichardOD


从查看MVCStoreFront示例来看,这是他们为调用RenderPartial而构建的所有内容的方式

Views
    Shared
        ProductSingle
        ProductList
        ArticleSingle
        ArticleList

然后通过以下方式渲染

<% Html.RenderPartial("ProductSingle", ViewData["ProductList"]); %>
<% Html.RenderPartial("ProductList", product); %>
<% Html.RenderPartial("ArticleSingle", article); %>
<% Html.RenderPartial("ArticleList", ViewData["ArticleList"]); %>

2
2017-11-11 20:56