2012-06-21 12 views
5

Quando il postback ottengo il seguente errore:Impostazione valore predefinito di un Html.DropDownList()

The ViewData item that has the key 'ClosingDateDay' is of type 'System.Int32' but must be of type 'IEnumerable'. Any ideas?

Ecco il mio controller:

CompetitionEditViewModel viewModel = new CompetitionEditViewModel 
{ 
    ClosingDate = competition.CloseDate, 
    Description = competition.Description, 
    DescriptionHeading = competition.DescriptionHeading, 
    ImageAssetId = competition.ImageAssetId, 
    IsActive = competition.IsActive, 
    MainHeading = competition.MainHeading, 
    TermsAndConditions = competition.TermsAndConditions, 
    UrlSlug = competition.UrlSlug 
}; 

viewModel.ClosingDateMonthOptions = new List<SelectListItem>(); 
for (int i = 1; i <= 12; i++) 
{ 
    string monthName = new DateTime(2000, i, 1).ToString("MMMM"); 
    ((List<SelectListItem>)viewModel.ClosingDateMonthOptions).Add(new SelectListItem { Text = monthName, Value = i.ToString() }); 
} 

viewModel.ClosingDateDayOptions = new List<SelectListItem>(); 
for (int i = 1; i <= 31; i++) 
{ 
    ((List<SelectListItem>)viewModel.ClosingDateDayOptions).Add(new SelectListItem { Text = i.ToString().PadLeft(2, '0'), Value = i.ToString() }); 
} 

viewModel.ClosingDateYearOptions = new List<SelectListItem>(); 
for (int i = DateTime.Now.Year; i <= DateTime.Now.Year + 3; i++) 
{ 
    ((List<SelectListItem>)viewModel.ClosingDateYearOptions).Add(new SelectListItem { Text = i.ToString(), Value = i.ToString() }); 
} 

Ed ecco mio punto di vista:

@Html.Uber().LabelFor(x => x.ClosingDateDay, new { @class = "access" }) 
@Html.DropDownListFor(x => x.ClosingDateDay, Model.ClosingDateDayOptions, Model.ClosingDateDay) 

@Html.Uber().LabelFor(x => x.ClosingDateMonth, new { @class = "access" }) 
@Html.DropDownListFor(x => x.ClosingDateMonth, Model.ClosingDateMonthOptions, Model.ClosingDateMonth) 

@Html.Uber().LabelFor(x => x.ClosingDateYear, new { @class = "access" }) 
@Html.DropDownListFor(x => x.ClosingDateYear, Model.ClosingDateYearOptions, Model.ClosingDateYear) 
+0

è il tuo secondo frammento di codice manca un '.'? Presumo dal tuo punto di vista che tu abbia 'Model.ClosingDate.Day' e così via come ultimo parametro per i menu a discesa? – Franky

+0

@Franky No, non lo è. Ma sicuramente mi hai appena aiutato a risolvere il problema haha. Grazie. – ediblecode

+0

Felice di aiutare, ma cura di spiegare? – Franky

risposta

9

Quando si costruiscono le classi SelectListItem, impostare la proprietà Selected su true per l'elemento che si desidera inizialmente selezionato.

+0

Con il sovraccarico che sta utilizzando, fornisce il valore selezionato come terzo parametro. – Franky

+3

Non c'è un tale sovraccarico per accettare il "valore predefinito" per un menu a discesa. Come ha detto @tarnbridge, uno degli elementi in 'List ' deve avere ".selected = true". – Tohid

+0

@Tohid Il terzo overload in 'Html.DropDownFor()' è l'altro modo per impostare il valore predefinito. Questo è ciò di cui parla @Franky – ediblecode

1

Quello che ho fatto in uno dei miei progetti e era una sorta di utile, è stato quello di sviluppare più 2 di sovraccarico per
DropDownListFor che accetta selectedValue.

namespace MyMvcApplication.Helpers 
{ 
    public static class ExtensionMethods 
    { 
     public static MvcHtmlString DropDownListFor<TModel, TProperty> 
          (this HtmlHelper<TModel> helper, 
           Expression<Func<TModel, TProperty>> expression, 
           string selectedValue, 
           IEnumerable<SelectListItem> selectList, 
           string optionLabel, 
           object htmlAttributes) 
     { 
      if (string.IsNullOrEmpty(selectedValue)) 
       selectedValue = string.Empty; 
      if (selectList != null) 
      { 
       foreach (SelectListItem sli in selectList) 
       { 
        if (sli.Value.ToLower().Trim() == selectedValue.ToLower().Trim()) 
        { 
         sli.Selected = true; 
         break; 
        } 
       } 
      } 
      else 
      { 
       selectList = new List<SelectListItem>() 
            { new SelectListItem() 
              { Text = "", Value = "", Selected = true } 
            }; 
      } 
      return helper.DropDownListFor(expression, selectList, optionLabel, htmlAttributes); 
     } 


     public static MvcHtmlString DropDownListFor<TModel, TProperty> 
          (this HtmlHelper<TModel> helper, 
           Expression<Func<TModel, TProperty>> expression, 
           string selectedValue, 
           IEnumerable<SelectListItem> selectList, 
           string optionLabel, 
           IDictionary<string, object> htmlAttributes) 
     { 
      if (string.IsNullOrEmpty(selectedValue)) 
       selectedValue = string.Empty; 
      if (selectList != null) 
      { 
       foreach (SelectListItem sli in selectList) 
       { 
        if (sli.Value.ToLower().Trim() == selectedValue.ToLower().Trim()) 
        { 
         sli.Selected = true; 
         break; 
        } 
       } 
      } 
      else 
      { 
       selectList = new List<SelectListItem>() 
            { new SelectListItem() 
              { Text = "", Value = "", Selected = true } 
            }; 
      } 
      return helper.DropDownListFor(expression, selectList, optionLabel, htmlAttributes); 
     } 

    } 
} 

Così nel Visualizzazioni, posso passare una stringa come SelectedValue a DropDownListFor, come:

@using MyMvcApplication.Helpers 

@Html.DropDownListFor(model => model.MyData, 
           "Default Value for DropDownList", //Or Model.MySelectedValue 
           Model.MySelectList, null, mull) 
Problemi correlati