I’m writing an MVC2 app using DataAnnotations. I have a following Model:
public class FooModel
{
[ScaffoldColumn("false")]
public long FooId { get; set; }
[UIHint("BarTemplate")]
public DateTime? Bar { get; set;}
}
I want to create a custom display template for Bar. I have created following template:
<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<DateTime?>" %>
<div class="display-label">
<span><%: Html.LabelForModel() %></span>
</div>
<div class="display-field">
<span><%: Html.DisplayForModel()%></span>
<%: Html.ActionLink("Some link", "Action", new { id = ??FooId?? }) %>
</div>
Now, my problem is that inside template for Bar I want to access another property from my model. I don’t want to create a separate template for FooModel because than I will have to hardcode all other FooModel properties.
After a brief investigation with a debugger I can see that:
this.ViewData.ModelMetadata.ContainerType
isFooModel(as expected)this.ViewData.TemplateInfohas a
non-public propertyVisitedObjects
(of type
System.Collections.Generic.HashSet<object>)
which contains two elements:
FooModelandDateTime?.
How can I get access to my FooModel? I don’t want to hack my way around using Reflection.
Update:
I’ve accepted mootinator’s answer as it looks to me as the best solution that allows type-safety. I’ve also upvoted Tx3’s answer, as mootinator’s answer builds upon it. Nevertheless, I think that there should be a better support form MVC in those kind of scenarios, which I believe are quite common in real world but missing from sample apps.
Sorry if this suggestion seems daft, I haven’t tried it, but couldn’t you do what Tx3 suggested without having to create a bunch of new classes by defining a generic class to reference whatever type of parent you want?
You could expand that to encapsulate any old type with a
<Parent, Child>typed generic, even.That would also give you the benefit that your strongly typed template would be for
Inherits="System.Web.Mvc.ViewUserControl<ParentedDateTime<FooType>>thus you would not have to explicity name which template to use anywhere. This is more how things are intended to work.