CheckBoxList не обновляет модель - PullRequest
2 голосов
/ 29 декабря 2011

Я определил сущность Person:

public partial class Person
{
 public string persID { get; set; }
 public string last_name { get; set; }
 public string driving_licence { get; set; }
}

, где водительские права имеют следующий вид:

public class DrivingLicence
    { 
        public string drivingLicenceValue { get; set; }
        public string drivingLicenceText { get; set; }

        public DrivingLicence(string paValue, string paText)
        {
            drivingLicenceValue = paValue;
            drivingLicenceText = paText;
        }
    }

с хранилищем, где определена эта функция:

public List<DrivingLicence> GetAll()
{
        try
        {
            var drivingLicenceList = new List<DrivingLicence>();

            DrivingLicence oneDrivingLicence = new DrivingLicence("A", "A");
            drivingLicenceList.Add(oneDrivingLicence );

            oneDrivingLicence = new DrivingLicence("B", "B");
            drivingLicenceList.Add(oneDrivingLicence );


            oneDrivingLicence = new DrivingLicence("C", "C");
            drivingLicenceList.Add(oneDrivingLicence );

            oneDrivingLicence = new DrivingLicence("D", "D");
            drivingLicenceList.Add(oneDrivingLicence );

            return drivingLicenceList;
        }
        catch (Exception)
        {
            throw new Exception("An error occured. Failed to Get the list.");
        }
    }

Теперь: я хочу, чтобы водительские права отображались в виде CheckBoxList, и при отправке я хочу, чтобы человеку были назначены проверенные категории водительских прав, например: выбраны категории "A" и "C", в результате нужно указать person.driving_licenceбыть "AC".

Проблема в том, что этого не происходит, человек создан, но свойство drive_licence пусто.Я обратил внимание, что имя флажков совпадает с именем соответствующего свойства (Person.driving_licence).

Это ошибка в настоящем коде?Или я должен изменить сущность Person?Спасибо за совет.

Вот вид модели:

public class PersonFormViewModel
{
    // Properties
    public Person person { get; set; }
    public SelectList DrivingLicenceList { get; set; }
    public string ActionToPerform { get; set; }


    public PersonFormViewModel() { }

    // Constructor
    public PersonFormViewModel(Person pPerson, SelectList pDrivingLicenceList)
    {
        person= pPerson;
        DrivingLicenceList = pDrivingLicenceList;
        if (String.IsNullOrEmpty(person.persID))
        {
            ActionToPerform = "Create";
        }
        else
        {
            ActionToPerform = "Edit";
        }
    }
}

Контроллер:

    //
    // GET: /Person/Create
    [Authorize]
    public ActionResult Create()
    {
        Person person = new Person();
        SelectList drvLicenceList = new SelectList(drvLicenceRepository.GetAll(), "drivingLicenceValue", "drivingLicenceText");
        return View("Create", new PersonFormViewModel(person, drvLicenceList));
    }

    //
    // POST: /Person/Create

    [HttpPost, Authorize]
    public ActionResult Create(PersonFormViewModel model)
    {
         Person person = model.person;
         SelectList drvLicenceList = new SelectList(drvLicenceRepository.GetAll(), "drivingLicenceValue", "drivingLicenceText");

        if (ModelState.IsValid)
        {
            try
            {
                db.Entry(person).State = EntityState.Added;
                db.SaveChanges();
                return RedirectToAction("Details");
            }
            catch (...)
            {
                ...
            }
        }
        return View("Create", new PersonFormViewModel(person, drvLicenceList));
    }

А вид:

@model MyApp.ViewModels.PersonFormViewModel
@{
    ViewBag.Title = "Create";
}

@using (Html.BeginForm())
{

    @Html.ValidationSummary(false, "Errors occured.")
    <fieldset>
        <legend>Fill in your details</legend>
        @Html.LabelFor(model => model.person.last_name)
        @Html.TextBoxFor(model => model.person.last_name)
        @Html.ValidationMessageFor(model => model.person.last_name, "*")
        @Html.HiddenFor(model => model.person.persID)

        @foreach (var ctg in (Model.DrivingLicenceList))
         {
             <input type="checkbox" name="driving_licence" value=ctg.value />@ctg.Text
         }
        <input type="submit" value="Sauvegarder" class="submit" />
    </fieldset>
}

1 Ответ

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

Я бы использовал свойство коллекции для хранения выбранных категорий водительских прав (можно установить несколько флажков => коллекция):

public partial class Person
{
    public string persID { get; set; }
    public string last_name { get; set; }
    public string[] driving_licence { get; set; }
}

и тогда вам нужно будет исправить имя флажка, чтобы он правильно связывался:

@foreach (var ctg in Model.DrivingLicenceList)
{
    <input type="checkbox" name="person.driving_licence" value="@ctg.Value" />
    @ctg.Text
}

, и если вы хотите сохранить выбранные значения, вам необходимо установить свойство флажка соответствующим образом:

@foreach (var ctg in Model.DrivingLicenceList)
{
    <input type="checkbox" name="person.driving_licence" value="@ctg.Value" @((Model.person.driving_licence ?? Enumerable.Empty<string>()).Contains(ctg.Value) ? "checked=\"checked\"" : "") />
    @ctg.Text
}

Как говорится, у нас теперь есть рабочее решение, но это далеко не все, чем я бы доволен и остановился на этом. Отныне мы могли бы начать рефакторинг этого беспорядка, чтобы соответствовать соглашениям об именах C # (такие вещи, как имена свойств начинаются с заглавной буквы, ...), вводить модели реального представления (которые не ссылаются на модели предметной области), настраиваемые помощники HTML, которые будут генерируйте эти списки флажков, чтобы избежать циклов записи в представлениях и флажках жесткого кодирования, ...

...