簡體   English   中英

有沒有辦法將復選框列表綁定到asp.net mvc中的模型

[英]Is there any way to bind a checkbox list to a model in asp.net mvc

我在這里尋找一種快速簡便的方法來綁定模型中發生回發時的復選框列表項列表。

顯然,現在這樣做的常用方法似乎就是這樣形式form.GetValues("checkboxList")[0].Contains("true"); 這看起來很痛苦而且不完全安全。

有沒有辦法綁定復選框列表(在視圖中使用或不使用幫助程序創建),或者甚至是在UpdateModel(myViewModel, form.ToValueProvider());期間的重要數據數組UpdateModel(myViewModel, form.ToValueProvider()); 在模型中填充IList<string>string[]的階段?

你可以從一個模型開始:

public class MyViewModel
{
    public int Id { get; set; }
    public bool IsChecked { get; set; }
}

然后一個控制器:

public class HomeController : Controller
{
    public ActionResult Index()
    {
        var model = new[] 
        {
            new MyViewModel { Id = 1, IsChecked = false },
            new MyViewModel { Id = 2, IsChecked = true },
            new MyViewModel { Id = 3, IsChecked = false },
        };
        return View(model);
    }

    [HttpPost]
    public ActionResult Index(IEnumerable<MyViewModel> model)
    {
        // TODO: Handle the user selection here
        ...
    }
}

一個視圖( ~/Views/Home/Index.aspx ):

<% using (Html.BeginForm()) { %>
    <%=Html.EditorForModel() %>
    <input type="submit" value="OK" />
<% } %>

最后是相應的編輯器模板:

<%@ Control 
    Language="C#"
    Inherits="System.Web.Mvc.ViewUserControl<AppName.Models.MyViewModel>" %>
<%= Html.HiddenFor(x => x.Id) %>
<%= Html.CheckBoxFor(x => x.IsChecked) %>

現在,當您在POST操作中提交表單時,您將獲得所選值的列表及其ID。

這是快速簡便的方法。 只需在checkbox輸入元素中設置value屬性,並為它們指定相同的name 如果我在一個站點中實現這個,我會創建一個CheckBox幫助器方法,它接受namevalueisChecked參數 ,但這里只是需要html的View:

<% using (Html.BeginForm()) { %>
  <p><input type="checkbox" name="checkboxList" value="Value A" /> Value A</p>
  <p><input type="checkbox" name="checkboxList" value="Value B" /> Value B</p>
  <p><input type="checkbox" name="checkboxList" value="Value C" /> Value C</p>
  <p><input type="checkbox" name="checkboxList" value="Value D" /> Value D</p>
  <p><input type="checkbox" name="checkboxList" value="Value E" /> Value E</p>
  <p><input type="checkbox" name="checkboxList" value="Value F" /> Value F</p>
  <input type="submit" value="OK" />
<% } %>

在您的控制器中:

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Index(IEnumerable<string> checkboxList)
{
    if (checkboxList != null)
    {
        ViewData["Message"] = "You selected " + checkboxList.Aggregate("", (a, b) => a + " " + b);
    }
    else
    {
        ViewData["Message"] = "You didn't select anything.";
    }

    return View();
}

IEnumerable<string>參數(如果需要,可以使它成為IList<string> )將僅包含已檢查項的值。 如果未選中任何框,則它將為null

這可以很好地使用自定義模型綁定器和常規HTML ...

首先,您的Razor語法中的HTML表單:

@using (Html.BeginForm("Action", "Controller", FormMethod.Post)) {
    <ol>
        <li><input type="textbox" name="tBox" value="example of another form element" /></li>

        <li><input type="checkbox" name="cBox" value="1" /> One</li>
        <li><input type="checkbox" name="cBox" value="2" /> Two</li>
        <li><input type="checkbox" name="cBox" value="3" /> Three</li>
        <li><input type="checkbox" name="cBox" value="4" /> Four</li>
        <li><input type="checkbox" name="cBox" value="5" /> Five</li>

        <li><input type="submit" /></li>
    </ol>
}

FormMethod.Post也可以.Get ,對此無關緊要)

然后,在適當的MVC意義上有一個代表你的表單提交的模型對象:

public class CheckboxListExampleModel {
    public string TextboxValue { get; set; }
    public List<int> CheckboxValues { get; set; }
}

還有一個自定義模型綁定器類(我喜歡將它放在綁定的模型中,所以我將重復上面創建的模型來顯示我添加它的位置。將它放在里面也允許綁定器使用私有屬性設置器,是一件好事):

public class CheckboxListExampleModel {
    public string TextboxValue { get; private set; }
    public List<int> CheckboxValues { get; private set; }

    public class Binder : DefaultModelBinder {
        public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) {
            var model = new CheckboxListExampleModel();

            model.TextboxValue = bindingContext.GetValueAsString("tBox");

            string checkboxCsv = bindingContext.GetValueAsString("cBox");
            // checkboxCsv will be a comma-separated list of the 'value' attributes
            //   of all the checkboxes with name "cBox" which were checked
            model.CheckboxValues = checkboxCsv.SplitCsv<int>();

            return model;
        }
    }
}

.GetValueAsString()是一個用於清晰的擴展方法,這里是:

    public static string GetValueAsString(this ModelBindingContext context, string formValueName, bool treatWhitespaceAsNull = true) {
        var providerResult = context.ValueProvider.GetValue(formValueName);
        if (providerResult.IsNotNull() && !providerResult.AttemptedValue.IsNull()) {
            if (treatWhitespaceAsNull && providerResult.AttemptedValue.IsNullOrWhiteSpace()) {
                return null;
            } else {
                return providerResult.AttemptedValue.Trim();
            }
        }
        return null;
    }

.SplitCsv<T>() 也是一種擴展方法,但它是一個常見的需求和雜亂的代碼,我將把它作為讀者的練習。

最后,您處理表單的操作提交:

[HttpPost]
public ActionResult Action([ModelBinder(typeof(CheckboxListExampleModel.Binder))] CheckboxListExampleModel model) {
    // stuff
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM