html.dropdownlist MVC3 confusion

2020-06-04 04:28发布

问题:

This works for me but how do I do the same thing using html.dropdownlist?

Notice that the value passed is not the value that is shown to the user.

@model IEnumerable<MVR.Models.ViewIndividual>

<h2>Level1</h2>    
<select>
        @foreach (var item in Model) {
        <option value="@item.Case_Number">@item.Patient_Lastname , 
                                          @item.Patient_Firstname
        </option>
}
</select>

回答1:

As always in an ASP.NET MVC application you start by defining a view model:

public class MyViewModel
{
    public string SelectedIndividual { get; set; }
    public SelectList Individuals { get; set; }
}

then you write a controller action that populates this view model from some data source or something:

public ActionResult Index()
{
    // TODO : fetch those from your repository
    var values = new[]
    {
        new { Value = "1", Text = "item 1" },
        new { Value = "2", Text = "item 2" },
        new { Value = "3", Text = "item 3" },
    };

    var model = new MyViewModel
    {
        Individuals = new SelectList(values, "Value", "Text")
    };
    return View(model);
}

and finally you have a strongly typed view using strongly typed helpers:

@model MyViewModel
@Html.DropDownListFor(
    x => x.SelectedIndividual,
    Model.Individuals
)

This being said, because I see that you are not using any view models in your application, you could always try the following ugliness (not recommended, do this at your own risk):

@model IEnumerable<MVR.Models.ViewIndividual>

<h2>Level1</h2>
@Html.DropDownList(
    "SelectedIndividual",
    new SelectList(
        Model.Select(
            x => new { 
                Value = x.Case_Number, 
                Text = string.Format(
                    "{0}, {1}", 
                    x.Patient_Lastname, 
                    x.Patient_Firstname
                ) 
            }
        ), 
        "Value", 
        "Text"
    )
)

Of course such pornography is not something that I would recommend to ever write in a view and I wouldn't recommend even to my worst enemies.

Conclusion: In an ASP.NET MVC application you should always be using view models and strongly typed views with strongly typed helpers (see first part of my answer).



回答2:

Here is the full example

  public class PageModel
    {
        [Display(Name = "Page ID")]
        public Guid ID { get; set; }
        [Display(Name = "Page Type ID")]
        public Guid PageTypeID { get; set; }
        [Display(Name = "Title")]
        public string Title { get; set; }
        [Display(Name = "Page Type Name")]
        public string PageTypeName { get; set; }
        [Display(Name = "Html Content")]
        public string HtmlContent { get; set; }
        public SelectList PageTypeList { get; set; }
    }

the C# code

public ActionResult Edit(Guid id)
{
    var model = db.Pages.Where(p => p.ID == id).FirstOrDefault();


    var typeList = new SelectList(db.PageTypes.OrderBy(s => s.Name).ToList(), "ID", "Name");
    var viewModel = new PageModel { PageTypeList = typeList };
    viewModel.HtmlContent = model.HtmlContent;
    viewModel.ID = model.ID;
    viewModel.PageTypeID = Guid.Parse(model.PageTypeID.ToString());
    viewModel.Title = model.Title;


    return View(viewModel);
}

[HttpPost]
[ValidateInput(false)]
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Edit(PageModel page)
{
    if (ModelState.IsValid)
    {
        var model = db.Pages.Where(p => p.ID == page.ID).FirstOrDefault();
        model.Title = page.Title;
        model.HtmlContent = page.HtmlContent;
        model.PageTypeID = page.PageTypeID;

        db.SaveChanges();
        return RedirectToAction("Index");
    }
    return View(page);
}

and lastly html

@model competestreet.com.Models.PageModel
@{
    ViewBag.Title = "Edit";
    Layout = "~/Views/Shared/_LayoutCMS.cshtml";
}
<script type="text/javascript">
    $(document).ready(function () {
        $('#HtmlContent').ckeditor();
    });
</script>
<script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/ckeditor/ckeditor.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/ckeditor/adapters/jquery.js")" type="text/javascript"></script>
<h2 class="title">
    <span class="text-cms">CM<span>S</span></span></h2>
<div class="box">
    <div class="t">
    </div>
    <div class="c">
        <div class="content">
            <div class="main-holder">
                <div id="sidebar">
                    <ul>
                        <li><a href="@Url.Content("~/Cms/Index")">Home</a></li>
                        <li><a href="@Url.Content("~/Pages/Index")">Pages</a></li>
                    </ul>
                </div>
                <div id="content" style="min-height: 500px;">
                    @using (Html.BeginForm())
                    {
                        @Html.ValidationSummary(true)
                        <fieldset>
                            <legend>Page Type -  @Html.DropDownListFor(x => x.PageTypeID, Model.PageTypeList)
                             @Html.ValidationMessageFor(model => model.PageTypeID)</legend>
                            <div class="editor-label">
                                @Html.LabelFor(model => model.Title)
                            </div>
                            <div class="editor-field">
                                @Html.EditorFor(model => model.Title, new { @class = "text-box" })
                                @Html.ValidationMessageFor(model => model.Title)
                            </div>
                            <div class="clear">
                            </div>
                            <div class="editor-label">
                                @Html.LabelFor(model => model.HtmlContent)
                            </div>
                            <div class="editor-field">
                                @Html.TextAreaFor(model => model.HtmlContent, new { @name = "Editor1", @class = "Editor1" })
                                @Html.ValidationMessageFor(model => model.HtmlContent)
                            </div>
                            <div class="clear">
                            </div>


                            <p>
                                <input type="submit" value="Save" class="input-btn" />
                            </p>
                        </fieldset>
                    }
                    <div>
                        @Html.ActionLink("Back to List", "Index")
                    </div>
                </div>
            </div>
        </div>
    </div>
    <div class="b">
    </div>
</div>