开发者

In ASP.NET MVC, how can you bind several select lists to an IList<string> collection?

开发者 https://www.devze.com 2023-02-02 00:42 出处:网络
I have a model with a List<string> property.I want to present several select lists that bind to that property.

I have a model with a List<string> property. I want to present several select lists that bind to that property.

For example, supposed my model is named Favories, and I let the user select several favorite colors.

public class Favorites
{
    public List<string> FavoriteColors { get; set;}
}

I tried binding using the indexes to the collection, but I ran into problems, most likely because FavoriteColors was empty. Here's the code that doesn't work (null exception):

@Html.DropDownListFor(m => m.FavoriteColors[0], ColorSelectList, "Select a color (required)")
@Html.DropDownListFor(m => m.FavoriteColors[1], ColorSelectList, "Select a color (optional)")
@Html.DropDownListFor(m => m.FavoriteColors[2], ColorSelectList, "Select a color (optional)")

I realize I could fix this a couple ways.

  1. Populate FavoriteColors with 3 empty values. But this doesn't feel right since my model would have invalid data (empty values) that I'd have to workaround in a bunch of other places in my code.
  2. Change my model so that I have 3 string properties (e.g. FavoriteColor1, FavoriteColor2, FavoriteColor3). Binding would be easier, but I'd still have to work around that deisg开发者_开发问答n with a bunch of code.

Is there a better way?


Here is a simple solution that will work for you using Razor and standard DropDownListFor<T> helpers.

All based on example data and files which you can change to suit your needs:

HomeController.cs

public class HomeController : Controller
    {
        public class FavoriteColorModel
        {
            public List<string> FavoriteColors { get; set; }
        }

        public ActionResult Index()
        {
            ViewBag.ColorList = new[]
                                    {
                                        "Blue",
                                        "Red",
                                        "Green",
                                        "Orange"
                                    };
            var favoriteColors = new FavoriteColorModel()
                                     {
                                         FavoriteColors = new List<string>()
                                                              {
                                                                  "Color1",
                                                                  "Color2",
                                                                  "Color3"
                                                              }
                                     };
            return View(favoriteColors);
        }

        [HttpPost]
        public ActionResult Save(FavoriteColorModel model)
        {
            TempData["SelectedColors"] = model.FavoriteColors;
            return RedirectToAction("Index");
        }
    }

Index.cshtml

@model MvcApplication4.Controllers.HomeController.FavoriteColorModel
@{
    ViewBag.Title = "Index";
    Layout = "~/Views/Shared/_Layout.cshtml";
}

<h2>Index</h2>

@if (TempData["SelectedColors"] != null)
{
    <text>
    You have selected the following colors:<br />
    <ul>
    @foreach (var color in TempData["SelectedColors"] as List<string>)
    {
        <li style="color:@color">@color</li>
    }
    </ul>
    </text>
}

@using (Html.BeginForm("Save", "Home"))
{
    @: Favorite colors:
    for (var index = 0; index < Model.FavoriteColors.Count; index++)
    {
        @Html.DropDownListFor(model => model.FavoriteColors[index], new SelectList(ViewBag.ColorList))
    }
    <br />
    <input type="submit" value="Save" />
}

Your selected colors will appear in a list element upon submit. You can control the amount of colors you wish to save by adding items to the Color1, Color2 array etc.

Peace.


This is how I would do it because I dont like the way MVC handles drop down lists.

   foreach (var ColorArray in m.FavoriteColors)
{ %>

 <select name='colors'>
 <% foreach (var color in ColorArray) 
{%>

  <option><%= color.ToString() %></option>

<% { %>
 </select>
}%>

You could hard code it to just the indexes you want but you get the general idea. Also this would allow you to put in null checks whereever you like to handle those cases selectively.

0

精彩评论

暂无评论...
验证码 换一张
取 消