Ales Potocnik
Ales Potocnik

Reputation: 3087

MVC3 Razor Editor/Display templates and generics

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

Answers (3)

lstern
lstern

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

Darin Dimitrov
Darin Dimitrov

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

Rob Kent
Rob Kent

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

Related Questions