Как реализовать CheckBoxFor в ASP. NET MVC 5? - PullRequest
0 голосов
/ 28 марта 2020

Я пытаюсь понять, как использовать CheckBoxFor в MVC 5. Я новичок в MVC и пытаюсь узнать, как работает Entity Framework, используя первые миграции кода. Вот мой основной класс Запрос:

[KeyAttribute] //One solution said to add this. Made no difference.
public virtual Guid ID { get; set; }


[Required(ErrorMessage = "First Name is required.")] [Display(Name = "First Name:")] [StringLength(25, ErrorMessage = "First Name must not exceed 25 characters.")]
public virtual string FName { get; set; }

[Display(Name = "Middle Initial:")] [StringLength(1, ErrorMessage = "Middle Initial must not exceed 1 character.")]
public virtual string MI { get; set; }

[Required(ErrorMessage = "Last Name is required.")] [Display(Name = "Last Name:")] [StringLength(25, ErrorMessage = "Last Name must not exceed 25 characters.")]
public virtual string LName { get; set; }

[Required(ErrorMessage = "Date of Birth is required.")] [Display(Name = "Date of Birth:")]
public virtual DateTime DOB { get; set; }

[Required(ErrorMessage = "Email is required.")] [Display(Name = "Email:")] [StringLength(25, ErrorMessage = "Email must not exceed 50 characters.")]
public virtual string Email { get; set; }

[Required(ErrorMessage = "Phone Number is required.")] [Display(Name = "Phone Number")] [StringLength(14, ErrorMessage = "Phone number must not exceed 14 characters.")]
public virtual string Phone { get; set; }

[Required(ErrorMessage = "Phone Type selection is required.")] [Display(Name = "Phone Type:")] [StringLength(4, ErrorMessage = "Phone Type selection must not exceed 4 characters.")]
public virtual string PhoneType { get; set; }

[Required(ErrorMessage = "Preferred Contact Method selection is required.")] [Display(Name = "Preferred Contact Method:")] [StringLength(16, ErrorMessage = "Preferred Contact Method selection must not exceed 16 characters.")]
public virtual PrefContactViewModel PrefContactViewModel {get;set;}

[Display(Name = "Preferred Contact Time:")] [StringLength(50, ErrorMessage = "Preferred Contact Time must not exceed 50 characters.")]
public virtual string PrefContactTime { get; set; }
...

Вот мой ViewModel PrefContactViewModel:

public int ID { get; set; }
public string Name { get; set; }
public bool Checked { get; set; }

Вот мой контроллер RequestsController Index Действие:

public ActionResult Index()
{
    var requests = db.Requests.Include(r => r.PrefContactViewModel);
    return View(requests.ToList());
}

Вот здесь тот же контроллер RequestForm Action:

public ActionResult RequestForm()
{
    return View();
}

А вот мой View:

@model AMYA.Models.Request
<div class="opensans margin-sides">
    @using (Html.BeginForm())
            {
    @Html.AntiForgeryToken()


    @Html.ValidationSummary(false, "", new { @class = "text-danger" })
    <hr />

                //FIRST NAME, MIDDLE INITIAL, LAST NAME
    <div>
        <div class="form-group col-md-5">
            @Html.LabelFor(model => model.FName, htmlAttributes: new { @class = "control-label" })<span class="red">*</span>
            <div>
                @Html.EditorFor(model => model.FName, new { htmlAttributes = new { @class = "form-control" } })
            </div>
        </div>

        <div class="form-group col-md-2">
            @Html.LabelFor(model => model.MI, htmlAttributes: new { @class = "control-label" })
            <div>
                @Html.EditorFor(model => model.MI, new { htmlAttributes = new { @class = "form-control" } })
            </div>
        </div>

        <div class="form-group col-md-5">
            @Html.LabelFor(model => model.LName, htmlAttributes: new { @class = "control-label" })<span class="red">*</span>
            <div>
                @Html.EditorFor(model => model.LName, new { htmlAttributes = new { @class = "form-control" } })
            </div>
        </div>
    </div>

                //DATE OF BIRTH, EMAIL, PHONE NUMBER, PHONE TYPE
    <div>
        <div class="form-group col-md-3">
            @Html.LabelFor(model => model.DOB, htmlAttributes: new { @class = "control-label" })<span class="red">*</span>
            <div class="">
                @Html.EditorFor(model => model.DOB, new { htmlAttributes = new { @class = "form-control" } })
            </div>
        </div>

        <div class="form-group col-md-4">
            @Html.LabelFor(model => model.Email, htmlAttributes: new { @class = "control-label" })<span class="red">*</span>
            <div class="">
                @Html.EditorFor(model => model.Email, new { htmlAttributes = new { @class = "form-control" } })
            </div>
        </div>

        <div class="form-group col-md-3">
            @Html.LabelFor(model => model.Phone, htmlAttributes: new { @class = "control-label" })<span class="red">*</span>
            <div class="">
                @Html.EditorFor(model => model.Phone, new { htmlAttributes = new { @class = "form-control" } })
            </div>
        </div>

        <div class="form-group col-md-2">
            @Html.LabelFor(model => model.PhoneType, htmlAttributes: new { @class = "control-label" })<span class="red">*</span>
            <div class="">
                @Html.CheckBoxFor(model => model.PrefContactViewModel.Checked, new { @class = "form-control" })
            </div>
        </div>
    </div>


    <div class="col-md-6">
            <div class="form-group">
                <div class="">
                    <input type="checkbox" id="PrefContact" name="PrefContact" value="@Request["PrefContact"]" />
                    @*@Html.EditorFor(model => model.PrefContact, new { htmlAttributes = new { @class = "checkbox" } })*@
                    @Html.CheckBoxFor(model => model.PrefContactViewModel.Checked, new { @class = "form-control" })
                </div>
            </div>
    </div>
    <div class="col-md-6">
        <div class="form-group">
            @Html.LabelFor(model => model.PrefContactTime, htmlAttributes: new { @class = "control-label" })
            <div class="">
                @Html.EditorFor(model => model.PrefContactTime, new { htmlAttributes = new { @class = "form-control" } })
            </div>
        </div>
    </div>
...

Мне просто нужно создать флажок для каждого из полей Name в моем ActionForm RequestForm. Я пробовал несколько решений, найденных здесь и в других местах, но я не могу заставить CheckBoxFor работать.

Может кто-нибудь предложить мне некоторое представление о том, как заставить CheckBoxFor заполняться четырьмя вариантами выбора? Или есть способ сделать это, используя обычное поле HTML <input>?

И я получаю в своем представлении следующее: enter image description here

1 Ответ

0 голосов
/ 28 марта 2020

( Обновление: Я написал этот ответ, прежде чем понял, что OP использует List<>, где каждый элемент списка имеет свое собственное поле (т.е. как настраиваемый построитель форм во время выполнения) вместо того, чтобы представлять каждое поле формы как свойство класса модели представления, и этот ответ не совсем подходит для этого сценария - но использование EditorFor вместо CheckBoxFor все равно будет работать в этом случае).

Вы не может использовать IEnumerable<T> в качестве типа c stati для @model представления, поскольку ASP. NET привязка модели (при повторном заполнении модели из тела запроса POST) работает с List<T>, не IEnumerable<T>.

Чтобы использовать привязку модели с List<T>, вам необходимо использовать for( int i = 0; i < list.Count; i++ ) -стиль l oop, вы не можете использовать foreach -стайл l oop, потому что он не предоставляет индекс элемента для использования со свойством индексатора List<T> (хорошо, технически вы можете использовать foreach с .Select( (e, idx) => ... ), но это приводит только к более непродуктивной клавиатуре.

  1. Измените вашу ViewModel на свой собственный класс, а не прямо List<T> в любом случае, потому что это упрощает все остальное (например, добавление заголовка страницы или другого содержимого, не включенного в список).
  2. Используйте for() l oop для визуализации каждого элемента.
  3. Ваша строка @model должна соответствовать фактическому model объекту, переданному в View(Object).

Примерно так:

Действие контроллера:

public class MyViewModel
{
    // this is an example of an additional non-list-item property you'd add to the viewmodel:
    [BindNever] // this is a one-way (server-to-client) property, so use [BindNever]
    public String PageTitle { get; internal set; }

    [Required]
    public List<PrefContactViewModel> MyList { get; set; }
}

public ActionResult RequestForm()
{
    MyViewModel vm = new MyViewModel()
    {
        PageTitle = "My list page!",
        MyList = new List<PrefContactViewModel>
        {
             new PrefContactViewModel { ID = 1, Name = "Call", Checked = false },
             new PrefContactViewModel { ID = 2, Name = "Text", Checked = false },
             new PrefContactViewModel { ID = 3, Name = "Email", Checked = false },
             new PrefContactViewModel { ID = 4, Name = "Traditional Mail", Checked = false },
        }
    };

    return View( vm );
}

Ваш взгляд:

@model MyViewModel
<div class="opensans margin-sides">
@using (Html.BeginForm()) {

    <h1>@this.Model.PageTitle</h1>

    @Html.AntiForgeryToken()
    @Html.ValidationSummary(false, "", new { @class = "text-danger" })
    <hr />

    @for( int i = 0; i < this.Model.MyList.Count; i++ ) {

        <!-- HTML markup removed for readability -->

        @Html.LabelFor( m => m.MyList[i].FName )
        @Html.TextBoxFor( m => m.MyList[i].FName )
        @Html.ValidationMessageFor( m => m.MyList[i].FName )


        @** Checkboxes should be wrapped in a <label> rather than using a separate label so you can't use @LabelFor **@
        <label>@Html.CheckBoxFor( m => m.MyList[i].Checked ) @Html.DisplayNameFor( m => m.MyList[i].Checked )</label>
        @Html.ValidationMessageFor( m => m.MyList[i].Checked )

        @** etc for other members of each list item **@

    } @** for loop **@
} @** </form> **@

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...