Validating multiple instances of the same partial view

I have a scenario in which I would like to display data for users and let them change it. For this, I have a form that is set with the current values โ€‹โ€‹of the object. This form is enclosed as a partial view, which in turn is called in a loop depending on how many children my parent has.

I also provide an empty form at the end so that users can create new instances of this child, so, in short, I have something like this:

Change form (partial view):

@model WebPortal.Models.AddressModel

@using (Html.BeginForm("EditAddress", "MerchantDetailsEditor", FormMethod.Post))
{
    @Html.ValidationSummary(true)

    @Html.LabelFor(model => model.StreetNumber, new { id = Model.ID + "_streetnumber_label", Name = Model.ID + "_streetnumber_label", @for = Model.ID + "_streetnumber" })
    @Html.TextBoxFor(address => address.StreetNumber, new { id = Model.ID + "_streetnumber", Name = Model.ID + "_streetnumber"})
    @Html.ValidationMessageFor(address => address.StreetNumber)

Create a form (another partial view)

@model WebPortal.Models.AddressModel
@{
    int counter = 1;
}

@using (Html.BeginForm("AddAddress", "MerchantDetailsEditor", FormMethod.Post))
{
    @Html.ValidationSummary(true)

    @Html.LabelFor(model => model.StreetNumber, new { id = counter + "_streetnumber_label", Name = counter + "_streetnumber_label", @for = counter + "_streetnumber" })
    @Html.TextBoxFor(address => address.StreetNumber, new { id = counter + "_streetnumber", Name = counter + "_streetnumber"})
    @Html.ValidationMessageFor(address => address.StreetNumber)
    counter++;

Which in turn is called like this:

@foreach (WebPortal.Models.AddressModel address in @Model.Addresses)
{
    @Html.Partial("Edit_Form", address)
}
@Html.Partial("Add_Form", new WebPortal.Models.AddressModel())

, , , , , , . , , , ( ) .

, , MVC ID , , , .

, ID Name, .

, , . , , , , . - / .

!

+4
2

. SO, Actions . , :

EDIT ( )

@model WebPortal.Models.AddressModel


@using (Html.BeginForm("EditAddress", "MerchantDetailsEditor", FormMethod.Post))
{
    @Html.ValidationSummary(true)

    @Html.HiddenFor(model => model.ID)

    @Html.LabelFor(model => model.StreetNumber, new { id = Model.ID + "_streetnumber_label" })
    @Html.TextBoxFor(address => address.StreetNumber, new { id = Model.ID + "_streetnumber" })
    @Html.ValidationMessageFor(address => address.StreetNumber)
 ...

( )

@model WebPortal.Models.AddressModel
@{
    int counter = 1;
}

@using (Html.BeginForm("AddAddress", "MerchantDetailsEditor", FormMethod.Post))
{
    @Html.ValidationSummary(true)

    @Html.LabelFor(model => model.StreetNumber, new { id = counter + "_streetnumber_label" })
    @Html.TextBoxFor(address => address.StreetNumber, new { id = counter + "_streetnumber"})
    @Html.ValidationMessageFor(address => address.StreetNumber)
 ...

- , :

<h2>Addresses</h2>
@foreach (WebPortal.Models.AddressModel address in @Model.Addresses)
{
    @Html.Action("_AddressEdit", address)
}

@if (ViewBag.AddressToAdd != null)
{
    @Html.Action("_AddressAdd", (WebPortal.Models.AddressModel)ViewBag.AddressToAdd)
}
else
{
    @Html.Action("_AddressAddNew")
}

. , .

:

 #region Actions
    public ActionResult _AddressEdit(AddressModel addressModel)
    {
        return View("...", addressModel);
    }

    public ActionResult _AddressAdd(AddressModel addressModel)
    {
        return View("...", addressModel);
    }

    public ActionResult _AddressAddNew()
    {
        return View("...");
    }
    #endregion Actions
0

name id . MVC , :

  • HtmlFieldPrefix .

, , .

AddressModel.cshtml( )

@model WebPortal.Models.AddressModel

@Html.LabelFor(model => model.StreetNumber)
@Html.TextBoxFor(address => address.StreetNumber)
@Html.ValidationMessageFor(address => address.StreetNumber)

@for (int i = 0; i < Model.Addresses.Count; i++)
{
    using (Html.BeginForm("EditAddress", "MerchantDetailsEditor"))
    {
        @Html.ValidationSummary(true)    
        <input type="hidden" name="Addresses.Index" value="@i" /> //http://haacked.com/archive/2008/10/23/model-binding-to-a-list.aspx/
        @Html.EditorFor(m => m.Addresses[i]) //uses AddressModel.cshtml
        <input type="submit" value="Edit" />
    }
}

@using (Html.BeginForm("AddAddress", "MerchantDetailsEditor"))
{
    @Html.ValidationSummary(true)
    @Html.EditorFor(m => m.AddAddress)
    <input type="submit" value="Add" />
}

    [HttpPost]
    public ActionResult EditAddress([Bind(Prefix="Addresses")] AddressModel[] i)
    {
         //learn more about BindAttribute here
         http://stackoverflow.com/questions/1317523/how-to-use-bind-prefix
    }

    [HttpPost]
    public ActionResult AddAddress([Bind(Prefix = "AddAddress")] AddressModel i)
    {

    }

HTML

, name id , 0

<form action="/Home/EditAddress" method="post">
  <input type="hidden" name="Addresses.Index" value="0" />
  <label for="Addresses_0__StreetNumber">Street Number</label>
  <input data-val="true" data-val-required="The Street Number field is required." id="Addresses_0__StreetNumber" name="Addresses[0].StreetNumber" type="text" value="" />
  <span class="field-validation-valid" data-valmsg-for="Addresses[0].StreetNumber" data-valmsg-replace="true"></span>
  <input type="submit" value="Edit" />
</form>
0

Source: https://habr.com/ru/post/1535356/


All Articles