2011-12-30 12 views
17

Ho questa linea, a mio avvisoPerché il mio DisplayFor non esegue il looping del mio IEnumerable <DateTime>?

@(Html.DisplayFor(m => m.DaysOfWeek, "_CourseTableDayOfWeek")) 

dove m.DaysOfWeek è un IEnumerable<DateTime>.

C'è il contenuto di _CourseTableDayOfWeek.cshtml:

@model DateTime 
@{ 
    ViewBag.Title = "CourseTableDayOfWeek"; 
} 
<th> 
    @System.Globalization.CultureInfo.CurrentCulture.DateTimeFormat.DayNames[(int) Model.DayOfWeek] 
    <span class="dateString">Model.ToString("G")</span> 
</th> 

e ottengo il seguente errore:

The model item passed into the dictionary is of type ' System.Collections.Generic.List`1[System.DateTime] ', but this dictionary requires a model item of type ' System.DateTime '.

Se rimando al seguente post:

https://stackoverflow.com/a/5652524/277067

Il DisplayFor dovrebbe passare attraverso l'IEnum erable e visualizza il modello per ogni articolo, non dovrebbe?

risposta

23

Non esegue il ciclo perché è stato specificato un nome per il modello di visualizzazione come secondo argomento dell'helper DisplayFor (_CourseTableDayOfWeek).

E loop solo quando si basano su convenzioni cioè

@Html.DisplayFor(m => m.DaysOfWeek) 

e poi dentro ~/Views/Shared/DisplayTemplates/DateTime.cshtml:

@model DateTime 
@{ 
    ViewBag.Title = "CourseTableDayOfWeek"; 
} 
<th> 
    @System.Globalization.CultureInfo.CurrentCulture.DateTimeFormat.DayNames[(int) Model.DayOfWeek] 
    <span class="dateString">Model.ToString("G")</span> 
</th> 

Una volta che si specifica un nome personalizzato per il modello di visualizzazione (sia come secondo argomento della DisplayFor helper o come attributo [UIHint]) non verrà più il ciclo per le proprietà della raccolta e il modello verrà semplicemente passato come modello al modello IEnumerable<T>.

È confuso ma è così. Non mi piace neanche.

+5

Ok, questo è triste, grazie –

+5

idem. Un altro aspetto di questi helper è stato difficile da eseguire il debug e non è affatto chiaro. – core24

+4

Sono appena caduto nella stessa trappola.Questo mi sembra totalmente contro-intuitivo. Spero che questo cambi con MVC 4. –

0

Questo sembra un bug. Le classi Helper Html sono facili da estendere, anche se dopo aver guardato il sorgente MVC, cercando il bug, ho rinunciato e ho sfruttato la premessa che i template funzionano per un singolo oggetto, quindi ho scritto un'estensione HtmlHelper che lo avvolge per te. Ho tirato fuori l'espressione lambda per la mia semplicità, ma puoi facilmente tornare a quello. Questo esempio è solo per un elenco di stringhe.

public static class DisplayTextListExtension 
{ 
    public static MvcHtmlString DisplayForList<TModel>(this HtmlHelper<TModel> html, IEnumerable<string> model, string templateName) 
    { 
     var tempResult = new StringBuilder(); 

     foreach (var item in model) 
     { 
      tempResult.Append(html.DisplayFor(m => item, templateName)); 
     } 

     return MvcHtmlString.Create(tempResult.ToString()); 
    } 
} 

Poi l'utilizzo effettivo assomiglia:

       @Html.DisplayForList(Model.Organizations, "infoBtn") 
-1

Uso FilterUIHint al posto del regolare UIHint, sulla proprietà IEnumerable<T>.

public class MyModel 
{ 
    [FilterUIHint("_CourseTableDayOfWeek")] 
    public IEnumerable<DateTime> DaysOfWeek { get; set; } 
} 

Non c'è bisogno di nient'altro.

@Html.DisplayFor(m => m.DaysOfWeek) 

Questa ora visualizza un "_CourseTableDayOfWeek" EditorTemplate per ogni DateTime in DaysOfWeek.

+0

Non riuscivo a farlo funzionare. Ha semplicemente ignorato FilterUIHint, come se non ci fossero annotazioni. Inoltre hai usato DisplayFor ma hai detto EditorTemplate per ciascuno; è stato un errore o di proposito? – Tod

Problemi correlati