Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
508 views
in Technique[技术] by (71.8m points)

.net - How to bind a selectlist with viewmodel?

I can't get a select list to bind to my ViewModel.

I have a ViewModel which contains a Question entity and a string

   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 = "";
    }
}

this is the controller:

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);
    }

and the code in my view looks like this:

<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>

The View does set the Question entity's Question_Type to the selected value, but when i submit the form, the ValidationMessageFor triggers??

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

What you have is not a view model. It's a hybrid class that you have called view model and in which you have wrapped your domain entity (Question). That's bad, don't do it.

Here's what I would recommend you. Start by designing a real view model which will reflect the requirements of your view (from your current description it's a dropdownlist containing some question types and allowing the user to select some question type from this 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; }
}

then have your controller map between your domain model and your view model. Of course a further improvement would be to use AutoMapper to avoid this mapping all over your controller actions:

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);
}

and then:

<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>

And one final remark: make sure you have gotten rid of any ViewBag/ViewData ugliness and put anything your view needs into the view model. You have shown some categories over there in your controller action which weren't materialized in the view snippet you have shown. If you ever needed them simply put them in your view model, the same way we did with the question types.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...