Reputation: 3087
There were a few questions regarding mvc templates and generics however there seems to be none related to what I'm looking for. Consider the following models:
namespace MyNamespace
{
public class ModelBase { /* Not important for example */ }
public class MyModel : ModelBase
{
public string Name { get; set; }
}
public class MyViewModel
{
public IEnumerable<ModelBase> Data { get; set; }
}
}
And a controller:
public class HomeController : Controller
{
public ActionResult Index
{
return View(new MyViewModel { Data = new List<MyModel>() })
}
}
A Razor view Views/Home/Index.cshtml would look like:
@model MyNamespace.MyViewModel
@Html.EditorFor(m => m.Data)
Nothing special there. If I want a display or editor template for that I can create a file under Views/Shared/EditorTemplate or under Views/Home/EditorTemplates called MyModel.cshtml and it finds it correctly.
What if I want to do something different for each implementation of ModelBase when showing a list? Mvc view finder will find List'1.cshtml template correctly in any of above paths. However what I need to do is do a template for List`1[MyModel].cshtml
I can't seem to get the correct file naming. What I've tried so far (relative to this example naming):
If possible I want to avoid writing a custom view finder. The only alternative I can think of for now if I can't get above stuff to work is to just have List`1.cshtml call a partial with naming deduced from List.
Upvotes: 3
Views: 3334
Reputation: 1629
A very late response, useful if someone else bump in this very same question (as I did a few moments ago trying to remember how to do this)
You can use the UIHintAttribute to define the name of the editor
public class MyViewModel
{
[UIHint("MyModel")]
public IEnumerable<ModelBase> Data { get; set; }
}
Upvotes: 7
Reputation: 1038710
You could do this in the main view:
@model MyViewModel
@Html.EditorFor(x => x.Data)
and then have:
~/Views/Shared/EditorTemplates/MyModel.cshtml
:
@model MyModel
...
~/Views/Shared/EditorTemplates/MyOtherModel.cshtml
(where obviously MyOtherModel
derives from ModelBase
):
@model MyOtherModel
...
and so on ... ASP.NET MVC will take care of looping through the Data property and pick the correct template based on the runtime type of each element of this collection.
Upvotes: 0
Reputation: 5193
I haven't checked this code but I would create different Views for each subtype and do something dumb like:
return View(MyModel.GetType().Name, new MyViewModel { Data = new List<MyModel>() })
So that your View matches the name of your type.
Upvotes: 1