0

这是一个奇怪的问题。我有以下视图文件(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)   
    }
}

... 哪里resultsSystem.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

...其中那串数字是我想通过显示模板呈现的所有Ids 的组合。ISearchMatch

似乎 Razor 只是ISearchMatch使用类中定义的第一个属性来呈现;如果我删除Id属性的定义,我会看到所有Name' 的组合ISearchMatch


有谁知道为什么会这样,以及如何让 Razor 使用我指定的显示模板?

4

2 回答 2

1

你的期望是错误的:

我希望我的显示模板被使用;但事实并非如此。

您看到的输出是简单列出的 ID。我怀疑您的ISearchMatch-interface 确实只公开了Id-property,但这并不重要。重要的是结果实例的实际类型。在您的情况下,以下行:

@Html.DisplayFor(x => results)

可以隐式评估为

HtmlHelper<IEnumerable<KeyValuePair<string, ISearchProvider>>>
    .DisplayFor<IEnumerable<KeyValuePair<string, ISearchProvider>>, IEnumerable<ISiteMatch>>
        (Func<IEnumerable<KeyValuePair<string, ISearchProvider>>, IEnumerable<ISiteMatch>> expression);

看起来很复杂,但基本上它只是对模型和表达式结果的隐式替换。你的模型是 type 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请注意,这有点复杂,例如扩展还跟踪索引并将其应用于输出,以便可以绑定模型以用于回发目的。

于 2014-05-27T10:57:11.940 回答
0

蹩脚的答案是我的视图文件上的“构建操作”Views/Search/DisplayTemplates/SiteSearchMatch.cshtml设置为“无”,而不是“内容”。

这意味着代码在 Visual Studio 中以调试模式运行时运行良好,但在进行任何部署时都无法运行。

只是重申一下;此修复不需要更改代码。只需将“构建操作”改回“内容”即可。

于 2014-05-27T13:09:06.590 回答