Search code examples
c#asp.net-mvcrazordisplay-templates

DisplayTemplate being ignored (covarient interface?)


This is a weird one. I have the following view file (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)   
    }
}

... where results is a System.Collections.Generic.IEnumerable<out T>, and T is ISearchMatch.

I have then defined a display template in Views/Search/DisplayTemplates/SiteSearchMatch.cshtml;

@model SiteSearchMatch
<li>@Html.ActionLink(Model.Name, "details", "site", new { Id = Model.Id }, null)</li>

... and SiteSearchMatch implements ISearchMatch like so;

public class SiteSearchMatch: ISearchMatch
{
    public int Id { get; set; }
    public string Name { get; set; }
}

I'd expect that my display template gets used; but it doesn't. Instead, the output I see being output is;

<li class="dropdown-header">sites</li>
11147166811481897189813271028

... where that string of numbers is the combination of all the Ids of the ISearchMatch's I wanted to render via the display template.

It seems Razor is simply rendering the ISearchMatch using the first attribute defined in the class; if I remove the definition of the Id property, I instead see the combination of all the Name's of the ISearchMatch's.


Does anyone know why this is happening, and how I can get Razor to use the display template I've specified?


Solution

  • The lame answer is that the "Build Action" on my View file Views/Search/DisplayTemplates/SiteSearchMatch.cshtml was set to "None", rather than "Content".

    This meant the code worked fine when running in Debug mode within Visual Studio, but didn't work when any deployment was made.

    Just to reiterate; this fix required no code changes. Simply change the "Build Action" back to "Content".