Как создать группу флажков с использованием MVC 4 и View Models (строго типизированный)

Я новичок в мире ASP.NET MVC, и я пытаюсь понять, как отобразить группу флажков, которые строго типизированы для модели представления. В webforms я бы просто использовал элемент checkboxlist, но im потерял немного с MVC.

Я создаю простую форму контакта для бизнеса по планированию свадьбы и должен передавать все флажки, которые пользователь выбирает для моего контроллера.

Флажки формы должны выглядеть так: enter image description here

Ваша помощь будет принята с благодарностью. Спасибо!

Вот что я до сих пор.

КОНТРОЛЛЕР

[HttpPost]
public ActionResult Contact(ContactViewModel ContactVM)
{
    if (!ModelState.IsValid)
    {
        return View(ContactVM);
    }
    else
    {
        //Send email logic

        return RedirectToAction("ContactConfirm");
    }
}

ПРОСМОТР МОДЕЛИ

public class ContactViewModel
{
    [Required]
    public string Name { get; set; }

    [Required]
    public string Phone { get; set; }

    [Required]
    [DataType(DataType.EmailAddress)]
    public string Email { get; set; }

    [Required]
    public string Subject { get; set; }
    public IEnumerable<SelectListItem> SubjectValues
    {
        get
        {
            return new[]
            {
                new SelectListItem { Value = "General Inquiry", Text = "General Inquiry" },
                new SelectListItem { Value = "Full Wedding Package", Text = "Full Wedding Package" },
                new SelectListItem { Value = "Day of Wedding", Text = "Day of Wedding" },
                new SelectListItem { Value = "Hourly Consultation", Text = "Hourly Consultation" }  
            };
        }
    }


    //Not sure what I should do for checkboxes...

}

VIEW

@model NBP.ViewModels.ContactViewModel

@{
    ViewBag.Title = "Contact";
    Layout = "~/Views/Shared/_Layout.cshtml";
}

@using (Html.BeginForm())
{
    <div id="ContactContainer">
        <div><span class="RequiredField">*&nbsp;</span>Your Name:</div>
        <div>
            @Html.TextBoxFor(model => model.Name)
        </div>
        <div><span class="RequiredField">*&nbsp;</span>Your Phone:</div>
        <div>
            @Html.TextBoxFor(model => model.Phone)
        </div>
        <div><span class="RequiredField">*&nbsp;</span>Your Email:</div>
        <div>
            @Html.TextBoxFor(model => model.Email)
        </div>
        <div>Subject:</div>
        <div> 
            @Html.DropDownListFor(model => model.Subject, Model.SubjectValues)
        </div>
        <div>Vendor Assistance:</div>
        <div>

            <!-- CHECKBOXES HERE -->

        </div>
        <div>
            <input id="btnSubmit" type="submit" value="Submit" />
        </div>
    </div>
}

Ответы

Ответ 1

Вы можете обогатить свою модель просмотра:

public class VendorAssistanceViewModel
{
    public string Name { get; set; }
    public bool Checked { get; set; }
}

public class ContactViewModel
{
    public ContactViewModel()
    {
        VendorAssistances = new[]
        {
            new VendorAssistanceViewModel { Name = "DJ/BAND" },
            new VendorAssistanceViewModel { Name = "Officiant" },
            new VendorAssistanceViewModel { Name = "Florist" },
            new VendorAssistanceViewModel { Name = "Photographer" },
            new VendorAssistanceViewModel { Name = "Videographer" },
            new VendorAssistanceViewModel { Name = "Transportation" },
        }.ToList();
    }

    [Required]
    public string Name { get; set; }

    [Required]
    public string Phone { get; set; }

    [Required]
    [DataType(DataType.EmailAddress)]
    public string Email { get; set; }

    [Required]
    public string Subject { get; set; }
    public IEnumerable<SelectListItem> SubjectValues
    {
        get
        {
            return new[]
            {
                new SelectListItem { Value = "General Inquiry", Text = "General Inquiry" },
                new SelectListItem { Value = "Full Wedding Package", Text = "Full Wedding Package" },
                new SelectListItem { Value = "Day of Wedding", Text = "Day of Wedding" },
                new SelectListItem { Value = "Hourly Consultation", Text = "Hourly Consultation" }  
            };
        }
    }

    public IList<VendorAssistanceViewModel> VendorAssistances { get; set; }
}

Контроллер:

public class HomeController : Controller
{
    public ActionResult Index()
    {
        return View(new ContactViewModel());
    }

    [HttpPost]
    public ActionResult Index(ContactViewModel model)
    {
        if (!ModelState.IsValid)
        {
            return View(model);
        }

        //Send email logic
        return RedirectToAction("ContactConfirm");
    }
}

Вид:

@using (Html.BeginForm())
{
    <div id="ContactContainer">
        <div><span class="RequiredField">*&nbsp;</span>Your Name:</div>
        <div>
            @Html.TextBoxFor(model => model.Name)
        </div>
        <div><span class="RequiredField">*&nbsp;</span>Your Phone:</div>
        <div>
            @Html.TextBoxFor(model => model.Phone)
        </div>
        <div><span class="RequiredField">*&nbsp;</span>Your Email:</div>
        <div>
            @Html.TextBoxFor(model => model.Email)
        </div>
        <div>Subject:</div>
        <div> 
            @Html.DropDownListFor(model => model.Subject, Model.SubjectValues)
        </div>
        <div>Vendor Assistance:</div>
        <div>
            @for (int i = 0; i < Model.VendorAssistances.Count; i++)
            {
                <div>
                    @Html.HiddenFor(x => x.VendorAssistances[i].Name)
                    @Html.CheckBoxFor(x => x.VendorAssistances[i].Checked)
                    @Html.LabelFor(x => x.VendorAssistances[i].Checked, Model.VendorAssistances[i].Name)
                </div>
            }
        </div>
        <div>
            <input id="btnSubmit" type="submit" value="Submit" />
        </div>
    </div>
}

Ответ 2

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

Просмотр модели:

[Display(Name = "Which Credit Cards are Accepted:")]
        public string[] CreditCards { get; set; }

Helper:

public static HtmlString CheckboxGroup<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> propertySelector, Type EnumType)
        {
            var groupName = GetPropertyName(propertySelector);
            var modelValues = ModelMetadata.FromLambdaExpression(propertySelector, htmlHelper.ViewData).Model;//propertySelector.Compile().Invoke(htmlHelper.ViewData.Model);
        StringBuilder literal = new StringBuilder();  

        foreach (var value in Enum.GetValues(EnumType))
        {
            var svalue = value.ToString();
            var builder = new TagBuilder("input");
            builder.GenerateId(groupName);
            builder.Attributes.Add("type", "checkbox");
            builder.Attributes.Add("name", groupName);
            builder.Attributes.Add("value", svalue);
            var contextValues = HttpContext.Current.Request.Form.GetValues(groupName);
            if ((contextValues != null && contextValues.Contains(svalue)) || (modelValues != null && modelValues.ToString().Contains(svalue)))
            {
                builder.Attributes.Add("checked", null);
            }

            literal.Append(String.Format("</br>{1}&nbsp;<span>{0}</span>", svalue.Replace('_', ' '),builder.ToString(TagRenderMode.Normal)));
        }

        return (HtmlString)htmlHelper.Raw(literal.ToString()); 
    }

    private static string GetPropertyName<T, TProperty>(Expression<Func<T, TProperty>> propertySelector)
    {
        var body = propertySelector.Body.ToString();
        var firstIndex = body.IndexOf('.') + 1;
        return body.Substring(firstIndex);
    }

HTML:

@Html.CheckboxGroup(m => m.CreditCards, typeof(VendorCertification.Enums.CreditCardTypes))

Используйте это, если вспомогательные расширения вас пугают:

            <input id="CreditCards" name="CreditCards" type="checkbox" value="Visa" 
            @(Model.CreditCards != null && Model.CreditCards.Contains("Visa") ? "checked=true" : string.Empty)/>
            &nbsp;<span>Visa</span><br />

            <input id="CreditCards" name="CreditCards" type="checkbox" value="MasterCard" 
            @(Model.CreditCards != null && Model.CreditCards.Contains("MasterCard") ? "checked=true" : string.Empty)/>
            &nbsp;<span>MasterCard</span><br />

Ответ 3

Для меня это тоже работает, и я думаю, что это самый простой (чтение предыдущих ответов).

В поле просмотра есть строка [] для флажков.

    public string[] Set { get; set; }

В представлении есть этот код, и вы можете повторять ввод столько раз, сколько вам нужно. имя, идентификатор элемента управления вводом должны соответствовать имени свойства модели viewmodel.

<div class="col-md-3">
  <div class="panel panel-default panel-srcbox">
    <div class="panel-heading">
      <h3 class="panel-title">Set</h3>
    </div>
    <div class="panel-body">
      <div class="form-group-sm">
        <label class="control-label col-xs-3">1</label>
        <div class="col-sm-8">
          <input type="checkbox" id="Set" name="Set" value="1" />
        </div>
        <label class="control-label col-xs-3">2</label>
        <div class="col-sm-8">
          <input type="checkbox" id="Set" name="Set" value="2" />
        </div>
      </div>
    </div>
  </div>
</div>

В методе post заданная переменная представляет собой массив, имеющий проверенные значения.