I've got a couple of questions about the naming convention for the DisplayTemplates and EditorTemplates in MVC 2.
If for example I have a customer object with a child list of account how do I:
Create a display template for the list of accounts, what is the file called?
When I'm doing a foreach( var c in Model.Accounts )
how do I call a display temple while in the foreach loop? When I do Html.DisplayFor( x => x )
inside the foreach x
is the model and not in this case c
.
Thanks in advance.
Yeah, this is one of my favorite features, but it's a bit confusing for some things.
So, creating a template for any class, the name is based on the type's Name property, so for example if you do a <%= model.GetType().Name %> in your view, you can see what I mean. As an example, if your list of accounts is an IList, then the call to .Name on the type would return List`1
. That's a legal file name, so if you put List`1.ascx
in your DisplayTemplates folder, it'll find it and use it. from what I can tell, it won't traverse the class hierarchy, though, so for example if you put an IEnumerable`1.ascx file in there, it won't find it.
To display in a loop, you need to pass in the item variable into the lambda, so in your example:
<% foreach (var c in Accounts){ %>
<li><%= Html.DisplayFor(x => c) %></li>
<%}%>
Hope that helps.
Paul
I realize this question is a bit old, but at least in MVC 3 when you want to have a custom display/edit template using a list you can pass in the name of the template:
Html.DisplayFor(model => model.Account, "AccountList")
then the name of your template would be "AccountList".
Brad Wilsons blog here http://bradwilson.typepad.com/blog/2009/10/aspnet-mvc-2-templates-part-4-custom-object-templates.html has an example about DisplayTemplates and EditorTemplates for Custom Objects, and it discusses issues which may be helpful in resolving your question.
Regarding your first question, it is important that your template resides in a folder which the system looks for matching names in, e.g.
~/Views/ControllerName/DisplayTemplates/TemplateName.aspx & .ascx
~/Views/Shared/DisplayTemplates/TemplateName.aspx & .ascx
(Replace DisplayTemplates with EditorTemplates for the search paths for editor templates.)
The following template names are tried in order:
- TemplateHint from ModelMetadata
- DataTypeName from ModelMetadata
- The name of the type (see notes below)
- If the object is not complex: “String”
- If the object is complex and an interface: “Object”
- If the object is complex and not an interface: Recurse through the inheritance hiearchy for the type, trying every type name
I'm not sure about an answer for your second question. Is it right to assume that var c is actually effectively Account c? And when you are writing Html.DisplayFor(x => x)
you might as well be writing Html.DisplayModelFor(c => c)
? Or do you want to have `Html.DisplayFor(x => x.AccountName), for instance?
When setting up an MVC 3 application, the foreign keys that should allow drop down lists to select an item do not get rendered as drop downs, but as static inputs. This can be resolved by creating a custom display and view for that field.
We will need to start by creating a custom partial view that will live in “~/Views/Shared/DisplayTemplates/UserGuid.cshtml”, and “~/Views/Shared/EditTemplates/UserGuid.cshtml”. The code for one is located below:
@model Guid
@{
incMvcSite.Models.MvcSiteDB db = new incMvcSite.Models.MvcSiteDB();
incMvcSite.Models.SecUser usr = db.SecUsers.Single(u => u.Guid == Model);
}
@usr.Display
This is a display for template that will look up the item in the referenced table and display it. We also need an edit for template as follows:
@model Guid
@{
incMvcSite.Models.MvcSiteDB db = new incMvcSite.Models.MvcSiteDB();
SelectList items = new SelectList(db.SecUsers.OrderBy(i => i.Display).ToList(), "Guid", "Display", Model);
}
@Html.DropDownList("", items)
The edit for template is implemented as a drop down list. Originally, we has used static HTML code, but the problem will appear of implementing a “prefix”. Static HTML code does get handled by HTML helpers, so it’s recommended that you use the HTML.DropDownList().
To force the MVC framework to use the new Display and Edit for templates, we need to annote our model item an add the following line:
[UIHint("UserGuid")]
This will cause MVC to use the Display and Edit templates named “UserGuid”, which are just partial views.
Not sure in previous versions but in MVC5 you can use UIHint to specify which custom display/editor template to use in the model like so,
[UIHint("CustomAccountList")]
public List Accounts{ get; set; }
OR in the view like so
Html.DisplayFor(model => model.Accounts, "CustomAccountList")