Application是一个带有RAZOR视图引擎的MVC3应用程序。
这里使用的控制器是TestController。 我正在使用嵌套视图。
基本视图(项目列表)是这样的,
//Listing.cshtml
@model ItemsList
@for (int i = 0; i < Model.Items.Count(); i++)
{
@Html.DisplayFor(x => x.Items[i], new { RowPosition = i})
}
这是Item
的模板//Item.cshtml
@model Item
@Html.DisplayFor(x=>x.HeaderText)
@Html.DisplayFor(x=>x, "ItemDetails")
这是项目详细信息的视图
//ItemDetails.cshtml
@model Item
@Html.DisplayFor(x=>x.Description)
所以,我正在尝试将模型从ITEM模板传递到ITEMDETAILS模板。 ItemDetails.cshtml位于“Views \ Test \ DisplayTemplates”下。事实上我已经尝试将它放在文件夹“Views \ Shared”以及“Views \ Shared \ DisplayTemplates”下。但View引擎似乎不是要把它拿起来。
但Microsoft文档here表明视图引擎确实在Controller \ DisplayTemplates文件夹中查找使用TemplateName来获取VIEW。
答案 0 :(得分:5)
这似乎是Display / EditorTemplates的预期行为,可能是为了防止在自定义显示模板中意外无限递归,例如执行(在Item.cshtml
中):
@model Item
@Html.DisplayFor(x => x)
...它将无限地显示Item.cshtml
DisplayTemplate。
显然,在您的示例中,您将项目/模型传递给不同的模板,因此不会导致无限递归。但是,它似乎仍然被框架中的同一个安全防范所抓住。不确定它是否会被归类为“错误”或仅仅是“设计”?
这是DisplayFor/TemplateFor helper:
中的检查// Normally this shouldn't happen, unless someone writes their own custom Object templates which
// don't check to make sure that the object hasn't already been displayed
object visitedObjectsKey = metadata.Model ?? metadata.RealModelType;
if (html.ViewDataContainer.ViewData.TemplateInfo.VisitedObjects.Contains(visitedObjectsKey)) { // DDB #224750
return String.Empty;
}
ViewData.TemplateInfo.VisitedObjects
存储父模板的访问对象/模型。当你跑:
@Html.DisplayFor(x => x.Items[i], new { RowPosition = i})
它呈现您的Item.cshtml
DisplayTemplate,并将项目/模型添加到VisitedObjects
。这意味着当Item.cshtml
尝试显示具有相同项目/模型的另一个子模板时:
@Html.DisplayFor(x => x, "ItemDetails")
项目/模型已经在VisitedObjects
中,因此上面的if语句返回true而不是呈现ItemDetails.cshtml
它只是静默地返回/呈现一个空字符串。
答案 1 :(得分:1)
首先,不要使用for循环。 Display / EditorTemplates能够处理集合。
第二,什么是ItemsList?它是如何定义的?如果它只是命名一个特定的收集类型,那么不要这样做。只需要一个List或者其他东西(除非你需要特殊的项目处理,在这种情况下在你的集合类上实现IEnumerable)。如果转换为使用List
,则可以使用ItemsList.cshtml或只是Item.cshtml另外,主视图中的DisplayFor()是错误的。你不能以这种方式将html属性传递给DisplayTemplates。
答案 2 :(得分:0)
尝试使用@Html.RenderPartial("ItemDetails", item)