MVC-3 DropdownList или DropdownListFor - невозможно сохранить значения в контроллере POST - PullRequest
1 голос
/ 05 декабря 2011

Я искал часы (или дни) и пока не нашел решения. Я хочу отредактировать клиента с DropdownListFor для приветствия с заранее выбранным значением.

У меня есть 3 объекта (сначала концепция базы данных, это не мой собственный дизайн ...): клиент, адрес, приветствие

У ЗАКАЗЧИКА есть address_id (f_key), а АДРЕС - salutation_id (f_key). АДРЕС содержит имя и фамилию, например. Внутри объекта SALUTATION есть столбец sal1, который содержит все возможные приветствия.

Теперь я хочу отредактировать своего клиента через ViewModel, которая выглядит следующим образом:

public class CustomerViewModel
{
    public CUSTOMER cust { get; set; }
    public SelectList salutationList { get; set; }

    CustomerRepository repository = new CustomerRepository();

    public CustomerViewModel(int id)
    {
        cust = repository.GetCustomerByIdAsQueryable(id).Single();
        salutationList = new SelectList(repository.GetSalutations(), cust.ADDRESS.SALUTATION.SAL1);
    }
    // Some more
}

Методы CutsomerRepository:

public class CustomerRepository
    {
        private MyEntities db = new MyEntities();

        public IQueryable<CUSTOMER> GetCustomerByIdAsQueryable(int id) {...}

        public IQueryable<CUSTOMER> GetCustomersByName(string firstName, string lastName, int maxCount)  {...}

        public List<string> GetSalutations()
        {
            var salutationList = new List<string>();
            var salutationListQry = from s in db.SALUTATION
                                    select s.SAL1;
            salutationListTemp.AddRange(salutationListQry);
            return salutationList;
        }
        // ...
    }

Это мой метод управления:

[HttpPost]
public ActionResult CustomerData(int id, FormCollection fc)
{
    var vm = new CustomerViewModel(id);
    // Why do I need the following line?
    vm.cust = repository.GetCustomerByIdAsQueryable(id).Single();
    try
    {
        UpdateModel(vm, fc);
        repository.Save();
        return View("CustomerData", vm);
    }
    catch (Exception e)
    {
        return View();
    }
}

И, наконец, часть моего взгляда:

@model WebCRM.ViewModels.CustomerViewModel
@using (Html.BeginForm())
{
    // ...
    <div class="editor-label">
        @Html.Label("Salutation:")
        @Html.DropDownListFor(model => model.cust.ADDRESS.SALUTATION.SAL1, Model.salutationList)
        // @Html.DropDownList("Salutation", Model.salutationList)
    </div>
    <div class="editor-label">
    </div>
    <div class="editor-field">
        @Html.Label("Last name:")
        @Html.EditorFor(model => model.cust.ADDRESS.LASTNAME)
        @Html.ValidationMessageFor(model => model.cust.ADDRESS.LASTNAME)
    </div>
    <p>
        <input type="submit" value="Speichern" />
    </p>
}

Изменение и сохранение фамилий работает нормально. Но при сохранении приветствия оно изменяет значение SAL1 в сущности SALUTATION на то, которое я выбрал в DropdownListFor. Я хочу изменить salutation_id внутри объекта ADDRESS для моего клиента. Почему это не работает?

Другое странное поведение: при удалении отмеченной строки в моем CustomerController я даже не могу изменить и сохранить фамилию. Обычно конструктор CustimerViewModel устанавливает клиента. Итак, почему у меня должна быть строка кода для установки клиента в моей ViewModel? Он продублирован, но должен быть там ...

Заранее спасибо.

1 Ответ

1 голос
/ 05 декабря 2011

Вам нужно иметь свойство Selected в вашем списке.

Я могу показать вам мой рабочий пример:

public static IEnumerable<SelectListItem> GetCountries(short? selectedValue)
    {
        List<SelectListItem> _countries = new List<SelectListItem>();
        _countries.Add(new SelectListItem() { Text = "Select country...", Value = "0", Selected = selectedValue == 0 });
        foreach (var country in ObjectFactory.GetInstance<DataRepository>().GetCountries())
        {
            _countries.Add(new SelectListItem()
            {
                Text = country.Name,
                Value = country.ID.ToString(),
                Selected = selectedValue > 0 && selectedValue.Equals(country.ID)
            });
        }
        return _countries;
    }  

В контроллере я сохраняю это в viewbag:

ViewBag.Countries = CompanyModel.GetCountries(0);

В поле зрения:

@Html.DropDownListFor(m => m.CompanyModel.CountryId, (IEnumerable<SelectListItem>)ViewBag.Countries)
...