Search code examples
asp.netasp.net-mvcvb.netasp.net-mvc-4display-templates

DisplayForModel not rendering my iList(of string)


I have a model, which has a few regular properties like strings and integers, and it also have 2 ilist(of string) properties.

I made a DisplayTemplate for these that looks like this and is called ListOfString.vbhtml:

@ModelType List(Of String)
@If Model IsNot nothing And Model.Any Then
    @<ul> 
        @For i As Integer = 0 To Model.Count
            @<li>@Html.Raw(Model(i))</li> 
        Next
    </ul> 
end if

This is how the properties are decorated:

<UIHint("ListOfString")>
<Display(Name:="Options", ResourceType:=GetType(WebText))>
Public Property Options As List(Of String) = New List(Of String)

Then, in my view, I am calling @Html.DisplayForModel(). Expecting all my properties to be written out by the default Display templates, and my custom one for the lists for the properties that are lists.

All the properties that are not IList(of string) are rendered out fine (it's ugly, but that is a separate problem all together).

I tried having the Display Template in the Views/Shared/DisplayTemplates folder in the project base, and in the Area/Views/controllername/DisplayTemplates folder and neither work.

The lists DO have values in them, and the templates are not being rendered because I put plain "hello" in them and it did not show up. So it isn't a case of model binding going wrong.

Am I completely off my rocker in expecting this to work? I was under the impression that this was one of the great things about display templates and whatnot.


Solution

  • I converted this C# Object Display Template linked by Denis to Visual Basic. Like the default object view template, it has a TemplateDepth check, but it's set to 5 instead of 1, and unlike the default, it displays views when metadata.IsComplexType is true.

    @Code
        Dim shouldKnow As Func(Of ModelMetadata, Boolean) =
            Function(metadata) metadata.ShowForDisplay And Not ViewData.TemplateInfo.Visited(metadata)
    End Code
    
    @If ViewData.TemplateInfo.TemplateDepth > 5 Then
        If Model = Nothing Then
            @ViewData.ModelMetadata.NullDisplayText
        Else
            @ViewData.ModelMetadata.SimpleDisplayText
        End If
    Else
        For Each prop In ViewData.ModelMetadata.Properties.Where(shouldKnow)
            If prop.HideSurroundingHtml Then
                @Html.Display(prop.PropertyName)
            Else
                @<div class="control-group">
                    @Code
                        Dim label = Html.Label(prop.PropertyName)
                        If String.IsNullOrEmpty(label.ToHtmlString()) = False Then
                        @<div class="control-label">
                            @label
                        </div>
                        End If
                    End Code
                    <div class="controls">
                        @Html.Display(prop.PropertyName)
                    </div>
                </div>
            End If
        Next
    End If