2014-09-15 3 views
1

Я знаю, что в этой теме уже есть темы, и я последовал за некоторыми из них без успеха.DropDownListFor не выбирает правильное значение

Проблема: У меня есть DropDownListFor, у которого есть список стран. Когда я выбираю страну и отправлю форму, она сохраняется правильно в базе данных, но когда я снова загружаю форму для ее редактирования, она всегда показывает первый элемент. У меня есть другие выпадающие списки, реализованные аналогичным образом, и они работают правильно.

То, что я пытался

  1. Я изменил название свойства, потому что я прочитал, что при использовании ViewBag передать список, чтобы заполнить выпадающий список, он может не выбрать правильное значение. НЕТ успеха.

  2. Я заменил viewbag для объекта в ViewModel. Нет успеха.

Кодекс

Вид:

<div class="input-group col-md-5"> 
    @Html.DropDownListFor(model => Model.CountryCode, new SelectList(Model.Countries, "Alpha2Code", "Name"), new { @class = "form-control" }) 
</div> 

Контроллер:

var userViewModel = await _userLogicLayer.GetUserViewModelAsync(MySession.UserId); 
userViewModel.Countries = LocaleLogicLayer.Countries; 
return View(userViewModel); 

LocaleLogicLayer:

public static class LocaleLogicLayer 
{ 

    public static List<Country> Countries { get; set; } 

    static LocaleLogicLayer() 
    { 
     Countries = new List<Country> 
     { 
      new Country() {Alpha2Code = "PT", Name = "Portugal"}, 
      new Country() {Alpha2Code = "BR", Name = "Brasil"}, 
      new Country() {Alpha2Code = "XX", Name = "Outro"} 
     }; 
    } 
} 

GetUserViewModelAsync

public async Task<UserViewModel> GetUserViewModelAsync(string userId) 
     { 
      var userProfile = await _userProfileRepository.GetAsync(userId); 
      var userViewModel = new UserViewModel(); 

      if (userProfile != null) 
      { 
       userViewModel.Id = userProfile.Id; 
       userViewModel.LinkedInProfile = userProfile.LinkedInProfile; 
       userViewModel.Nif = userProfile.Nif; 
       userViewModel.Bi = userProfile.Bi; 
       userViewModel.Picture = userProfile.Picture; 
       userViewModel.CountryCode = userProfile.CountryCode; 

      } 

     return string.IsNullOrWhiteSpace(userViewModel.Id) ? null : userViewModel; 
    } 

Я ценю вас помочь. Это должна быть очень простая ошибка, но я не нахожу ее. спасибо.

Edit (новый подход)

CountriesX has now a SelectList

Новый DropDownlList

@Html.DropDownListFor(model => model.CountryCode, (SelectList)ViewBag.CountriesX, new { @class = "form-control" }) 

(и до сих пор не работает, так расстраивает)

+0

Какова ценность 'userViewModel.CountryCode' в коде контроллера? – ekad

+0

Если я выбираю Brasil, это «BR», Португалия «PT» и «XX» в остальном случае – sergiommaria

+0

Да, у него есть. Он корректно сохраняет базу данных и также считывает правильное значение. проблема в том, что представление просто игнорирует его. – sergiommaria

ответ

1

Первый аргумент Html.DropDownListFor является лямбда выражение, поэтому вы должны пройти model => model.CountryCode вместо model => Model.CountryCode (обратите внимание на большую и небольшую разницу М). Я также предложил передать экземпляр List<SelectListItem> в качестве второго аргумента метода Html.DropDownListFor и установить его внутри конструктора UserViewModel.

Изменить код класса модели ниже, что вам нужно сделать, это изменить тип Countries собственности List<SelectListItem> и добавить метод-конструктор:

using System.Web.Mvc; 

public class UserViewModel 
{ 
    public UserViewModel() 
    { 
     this.Countries = new List<SelectListItem> 
     { 
      new SelectListItem() { Text = "Portugal", Value = "PT" } 
      new SelectListItem() { Text = "Brasil", Value = "BR" } 
      new SelectListItem() { Text = "Outro", Value = "XX" } 
     }; 
    } 

    public List<SelectListItem> Countries { get; set; } 

    .... // other existing properties 
} 

, то ваш код контроллера должен быть как ниже

var userViewModel = await _userLogicLayer.GetUserViewModelAsync(MySession.UserId); 
return View(userViewModel); 

и ваш взгляд код

<div class="input-group col-md-5"> 
    @Html.DropDownListFor(model => model.CountryCode, Model.Countries, new { @class = "form-control" }) 
</div> 
0

Сначала попробуйте ответить @ ekad, так как это может быть проблемой, и это то, что вам нужно исправить в любом случае. Однако, если он все еще не работает, попробуйте не создавать свои собственные SelectList. SelectList принимает в качестве параметра своего конструктора выбранное значение, которое вы не передаете, то есть ничего не будет выбрано изначально. Если ответа на вопрос @ ekad достаточно, чтобы исправить вашу проблему, то это означает, что Razor помогает вам позади и устанавливает выбранное значение.

В любом случае, хотя, это гораздо лучше, чтобы передать IEnumerable<SelectListItem> в Html.DropDownListFor, который можно создать с помощью:

Model.Countries.Select(m => new SelectListItem { Value = m.Alpha2Code, Text = m.Name }) 

Если вы используете модель представления, то лучше, чтобы переместить это в код действия и на самом деле установите для этого свойства на вашей модели просмотра. Тогда вы можете просто сделать что-то вроде:

Html.DropDownListForm(m => m.CountryCode, Model.CountryChoices) 

Гораздо меньше кода и логики с вашей точки зрения, которая всегда хорошо.

+0

Я пробовал свои предложения и до сих пор не работает :( – sergiommaria

0

Вы не выбираете значение для выпадающего, выбрали его! Попробуйте это ваш HTML:

@Html.DropDownListFor(m => m.CountryCode,null,null) 

и ваш код:

var userViewModel = await _userLogicLayer.GetUserViewModelAsync(MySession.UserId); 
ViewBag.CountryID = new SelectList(LocaleLogicLayer.Countries,"Alpha2Code","Name",userViewModel.CountryCode); 
return View(userViewModel); 
+0

Я обновил свой код (и вопрос) с последними предложениями. Еще один результат ... :( – sergiommaria

+0

Я обновляю свой ответ, пожалуйста, попробуйте изменения. – Yehia

0

После еще несколько часов исследования, я, наконец, нашел решение моей проблемы: То, что я не понимаю, почему аналогичный код работал для других полей, а не для этого. После того, как я привязал его к другому свойству, он работал отлично. Таким образом, я обнаружил, что есть статическое свойство в моем классе базового контроллера назначен следующим образом:

ApplicationController.Locale.CountryCode = countryCode; 
  • этого значение происходит от URL. Таким образом, CountryCode является статическим полем статического класса «Locale», назначенным на моем базовом контроллере, и я никогда не ссылаюсь на него в своем представлении.

Заключение: я получил это хорошо, но может кто-нибудь объяснить мне, почему это происходит? Для меня это бессмысленно.

Примечание: Кажется, нам не нужно передавать выбранный список в выбранном списке. Во всяком случае, это должно быть хорошо для когерентности кодов и не больно. Problem with DropDownListFor SelectedItem

Все посты были ценными, и я улучшил свое окончательное решение на основе этого, благодаря чему вы все за свое время и знания.

Смежные вопросы