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:
@Html.DisplayNameFor(model => model.SiteName)
@Html.DisplayFor(model => model.SiteName)
This is the code that DisplayFor generates nothing:
@Html.DisplayNameFor(model => model.Version.VersionName)
@Html.DisplayFor(model => model.Version.VersionName)
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 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.
Talk1:
If you use "@Model.Version.VersionName" instead of your DisplayFor(), do you see something?
Talk2:
No I already tried that and actually got an Object Ref error instead :)
Talk3:
Ok... So your problem is that Version is null
Talk4:
, yes I realized that the Version was null based on that error but wasn't sure why. The answer below is the resolution to my problem, I had to explicitly load the Version child into my site model.
Solutions1
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);
Talk1:
I ended up using your second suggestion so I could load all my child objects in one line. The syntax is actually db.Sites.Include(s => s.Version).Include(... etc).FirstOrDefault(s => s.Id == id); Thanks again