这很奇怪。我有以下视图文件(Views/Search/Submit.cshtml
):
@model IEnumerable<KeyValuePair<string, ISearchProvider>>
@foreach (var provider in Model)
{
var results = provider.Value.Results.Take(10);
if (results.Count() > 0)
{
<text><li class="dropdown-header">@provider.Key</li></text>
@Html.DisplayFor(x => results)
}
}
...其中results
是System.Collections.Generic.IEnumerable<out T>
,T is ISearchMatch
。
然后我在Views/Search/DisplayTemplates/SiteSearchMatch.cshtml
;
@model SiteSearchMatch
<li>@Html.ActionLink(Model.Name, "details", "site", new { Id = Model.Id }, null)</li>
...而SiteSearchMatch
实现ISearchMatch
就像这样;
public class SiteSearchMatch: ISearchMatch
{
public int Id { get; set; }
public string Name { get; set; }
}
我希望我的显示模板得到使用;但事实并非如此。相反,我看到输出的输出是;
<li class="dropdown-header">sites</li>
11147166811481897189813271028
...其中该数字字符串是我想通过显示模板呈现的Id
的所有ISearchMatch
的组合。
似乎Razor只是使用类中定义的第一个属性渲染ISearchMatch
;如果我删除了Id
属性的定义,我会看到Name
的所有ISearchMatch
的组合。
有谁知道为什么会这样,以及我如何让Razor使用我指定的显示模板?
答案 0 :(得分:1)
您的期望是错误的:
我希望我的显示模板得到使用;但它没有。
您看到的输出是简单列出的ID。我怀疑你的ISearchMatch
- 接口只公开Id
- 属性,但这没关系。重要的是结果实例的实际类型。在您的情况下,以下行:
@Html.DisplayFor(x => results)
可以隐式评估为
HtmlHelper<IEnumerable<KeyValuePair<string, ISearchProvider>>>
.DisplayFor<IEnumerable<KeyValuePair<string, ISearchProvider>>, IEnumerable<ISiteMatch>>
(Func<IEnumerable<KeyValuePair<string, ISearchProvider>>, IEnumerable<ISiteMatch>> expression);
看起来很复杂,但基本上它只是对模型和表达式结果的隐式替换。您的模型类型为IEnumerable<KeyValuePair<string, ISearchProvider>>
。这也是lampda表达式输入的类型。结果是IEnumerable<ISiteMatch>
类型。这就是重要的事情!
DisplayFor
实现检查结果类型是否可枚举。如果没有,它将搜索该类型的拟合模板,否则它将遍历元素并对所有元素执行此操作。 1
根据类型名称搜索模板。在您的情况下,模板使用枚举类型的名称,即ISearchMatch
。它没有找到任何显示模板,所以它只是转储属性,导致你看到的内容:
11147166811481897189813271028
要解决此问题,您需要先将结果集转换为正确的类型。你可以用不同的方式做到这一点。您可以投射提供者结果的整个结果:
var results = provider.Value.Results
.Cast<SiteSearchMatch>()
.Take(10);
或者你在lamda表达式中单独投射它们:
@Html.DisplayFor(x => (SiteSearchMatch)results)
重要的是,标量结果类型与显示模板中的模型相同。
1 请注意,这有点复杂,例如,扩展程序还会跟踪索引并将其应用于输出,以便模型可以绑定到回发目的。
答案 1 :(得分:0)
lame 的答案是&#34; Build Action&#34;在我的观看文件Views/Search/DisplayTemplates/SiteSearchMatch.cshtml
上设置为&#34;无&#34;而不是&#34;内容&#34;。
这意味着在Visual Studio中以调试模式运行时代码运行正常,但在进行任何部署时无法正常工作。
重申一下;此修复程序需要否代码更改。只需更改&#34; Build Action&#34;回到&#34;内容&#34;。