0

I have the following classes:

public class Widget
{
    public string Name { get; set; }
}

GenericModel

public class GenericModel<T>
{
    public List<T> Data { get; set; }
}

My Controller action is:

    public ActionResult Simple()
    {
        var model = new GenericModel<Widget>()
                        {
                            Data = new List<Widget>
                                       {
                                           new Widget {Name = "a"}
                                       }
                        };
        return View(model);
    }

And my view is:

@model MyApp.GenericModel<MyApp.Widget>

@{
    ViewBag.Title = "Simple";
}

<h2>Simple</h2>
@Html.DisplayFor(m=>m)

I have a file called GenericModel.cshtml in Views/Shared/DisplayTemplate folder:

@model MyApp.GenericModel<MyApp.Widget>

<ul>
@for (int i = 0; i < Model.Data.Count; i++ )
{
    <li>
    @Html.EditorFor(m=> Model.Data[i].Name)
    </li>
}
</ul>

This view can not be found. I see when I print out the name of the type of my model I get "GenericModel1". Seeing that, I renamed my template "GenericModel1.cshtml". This seems like a bit of a hack, is there an easier way to find this display template without resorting to this?

ek_ny
  • 10,153
  • 6
  • 47
  • 60
  • Your view must have the same name as your controller action, unless you specify otherwise. – user1477388 Sep 11 '12 at 13:13
  • @user1477388 My view does-- it's my DisplayTemplate that I'm referring to. – ek_ny Sep 11 '12 at 13:20
  • Have you tried playing with the UIHint attribute? What happens if you decorate the Data property with UIHint pointing to your template? – stephen.vakil Sep 11 '12 at 20:34
  • @stephen.vakil I think I might have figured it out-- @Html.DisplayFor(m=>m, "GenericModel").. which I thought I tried-- this might be similar to using a UI Hint. – ek_ny Sep 11 '12 at 21:12

1 Answers1

0

You have to set it in your viewstart:

@Code
    Layout = "~/Views/Shared/DisplayTemplate.cshtml"
End Code

Note: The above is VB.

You can also pass it via your controller like this:

public ActionResult Simple()
{
    var model = new GenericModel<Widget>()
                    {
                        Data = new List<Widget>
                                   {
                                       new Widget {Name = "a"}
                                   }
                    };
    return View("", "DisplayTemplate", model);
}
user1477388
  • 20,790
  • 32
  • 144
  • 264
  • Thanks but this answer addresses something different- The layout is basically a master page. The issue is not returning a different View for an action, the issue is using the DisplayFor(). The reason this is important is that DisplayFor or EditorFor() will render the proper indexes for databinding my models when I post back to the server. – ek_ny Sep 11 '12 at 15:15
  • 1
    Sorry, I guess I don't understand the problem. If the action is not displaying the correct view, you can specify that here `View("myView", "MyLayout", "MyModel")` and if the view isn't display the correct model, you can specify that `@model MyApp.ModelType` – user1477388 Sep 11 '12 at 15:20
  • I appreciate the effort-- it's a specific problem that relates to a combination of 1) how indexes get "respected" by views when dealing with model binding and collections and 2) How generics and DisplayTemplates relate to each other. – ek_ny Sep 11 '12 at 16:23
  • 2
    The issue is that he has a custom display template for the GenericModel class but DisplayFor is not finding it due to the way classes get named auto-magically at runtime. – stephen.vakil Sep 11 '12 at 20:38