Как связать список выбора с viewmodel? - PullRequest
6 голосов
/ 08 июля 2011

Я не могу получить список выбора для привязки к моей ViewModel.

У меня есть ViewModel, которая содержит сущность Question и строку

   public class QuestionViewModel
{
    public Question Question { get; set; }
    public string RefUrl { get; set; }

    public QuestionViewModel()
    {
    }

    public QuestionViewModel(Question question, string RefUrl)
    {
        this.Question = question;
        this.RefUrl = RefUrl;
    }

    public QuestionViewModel(Question question)
    {
        this.Question = question;
        this.RefUrl = "";
    }
}

это контроллер:

public ActionResult Edit(int id)
    {
        Question question = db.Question.Single(q => q.question_id == id);
        QuestionViewModel qvm = new QuestionViewModel(question);
        ViewBag.category_id = new SelectList(db.Category, "category_id", "category_name", qvm.Question.category_id);
        ViewBag.type_code = new SelectList(db.Question_Type, "type_code", "type_description", qvm.Question.type_code);
        return View(qvm);
    }

и код в моем представлении выглядит следующим образом:

<div class="editor-label">
        @Html.LabelFor(model => model.Question.type_code, "Question_Type")
    </div>
    <div class="editor-field">
        @Html.DropDownListFor(model => Model.Question.Question_Type, (SelectList)ViewBag.type_code)
        @Html.ValidationMessageFor(model => model.Question.type_code)
    </div>

Представление устанавливает вопросительный тип объекта Question на выбранное значение, но при отправке формы ValidationMessageFor вызывает??

1 Ответ

14 голосов
/ 08 июля 2011

То, что у вас есть не модель просмотра . Это гибридный класс, который вы назвали view model и в который вы обернули объект вашего домена (Question). Это плохо, не делай этого.

Вот что я бы порекомендовал вам. Начните с разработки реальной модели представления, которая будет отражать требования вашего представления (из вашего текущего описания это выпадающий список, содержащий некоторые типы вопросов и позволяющий пользователю выбрать какой-либо тип вопроса из этого ddl):

public class QuestionViewModel
{
    [DisplayName("Question_Type")]
    public string SelectedQuestionType { get; set; }

    public IEnumerable<SelectListItem> QuestionTypes { get; set; }

    // didn't see where you are using this on your view
    public string RefUrl { get; set; }
}

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

public ActionResult Edit(int id)
{
    var question = db.Question.Single(q => q.question_id == id);
    var qvm = new QuestionViewModel
    {
        // preselect a value
        SelectedQuestionType = question.type_code,
        QuestionTypes = db.Question_Type.Select(x => new SelectListItem
        {
            Value = x.type_code,
            Text = x.type_description
        })
    };
    return View(qvm);
}

и затем:

<div class="editor-label">
    @Html.LabelFor(x => x.SelectedQuestionType)
</div>
<div class="editor-field">
    @Html.DropDownListFor(
        x => SelectedQuestionType, 
        new SelectList(Model.QuestionTypes, "Value", "Text")
    )
    @Html.ValidationMessageFor(x => x.SelectedQuestionType)
</div>

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...