Search code examples
c#asp.net-mvchtml-helper

@Html.DisplayFor() is not working with custom model sub-class


So I have a MVC application to manage a list of sites and on my details view none of my sub classes within my model render anything even though the @Html.DisplayNameFor is rendering the label correctly.

Here is the view code that is working fine:

<tr>
    <td>
        <span class="label label-info">@Html.DisplayNameFor(model => model.SiteName)</span>
    </td>

    <td style="text-align: center;">
        @Html.DisplayFor(model => model.SiteName)
    </td>
</tr>

This is the code that DisplayFor generates nothing:

<tr>
    <td>
        <span class="label label-info">@Html.DisplayNameFor(model => model.Version.VersionName)</span>
    </td>

    <td style="text-align: center;">
        @Html.DisplayFor(model => model.Version.VersionName)
    </td>
</tr>

Here is my Site model:

public class Site
{
    public int ID { get; set; }

    [Required]
    [Display(Name = "Link")]
    [DataType(DataType.Url)]
    public string SiteLink { get; set; }

    [Required]
    [Display(Name = "Name")]
    public string SiteName { get; set; }

    public int VersionId { get; set; }

    [ForeignKey("VersionId")]
    public Version Version { get; set; }
}

And my Version class:

public class Version
{
    public int ID { get; set; }

    [Display(Name = "Version")]
    public string VersionName { get; set; }

    public List<Site> Sites { get; set; }
}

Lastly, here is my Details ActionResult method in my controller:

public ActionResult Details(int id = 0)
{
    Site site = db.Sites.Find(id);
    if (site == null)
    {
        return HttpNotFound();
    }
    return View(site);
}

All of my other views are rendering just fine, just this details view seems to be returning nothing for my custom classes.


Solution

  • You need to explicitly load the child (Version):

    Site site = db.Sites.Find(id);
    if (site == null)
    {
        return HttpNotFound();
    }
    db.Entry(site).Reference(p => p.Version).Load(); 
    return View(site);
    

    You could also do

    db.Sites.Include(s => s.Version).FirstOrDefault(s => s.Id == id);
    

    https://msdn.microsoft.com/en-us/data/jj574232.aspx#explicit