Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ASP.NET MVC 3 Edit Collection In Model In Same View

I have a simple question.

I have a model that looks like this:

public class AddEditChildProductModel
{
    public string Name {get; set;}
    public string Sku {get;set;}
    ........
    public IEnumerable<AddEditPriceTierModel> PriceTiers {get;set;}
}
public class AddEditPriceTierModel
{
    public int QtyStart {get;set;}
    public int QtyEnd {get;set;}
    ........
}

My question is how do I edit the collection in the same view?

It would seem this would be very simple, maybe I am missing something.

Thanks!!

**Edit**

OK, so I used EditorTemplates, but now I am getting the following error:

The operation failed: The relationship could not be changed because one or more of the foreign-key properties is non-nullable. When a change is made to a relationship, the related foreign-key property is set to a null value. If the foreign-key does not support null values, a new relationship must be defined, the foreign-key property must be assigned another non-null value, or the unrelated object must be deleted.

This is my controller action:

public ActionResult EditChildProduct(AddEditChildProductModel model)
        {
            if (!ModelState.IsValid)
                return PartialView("AddEditChildProduct", model);

            ChildProduct childProduct = productService.GetChildProductByID(model.ID);
            AutoMapper.Mapper.Map<AddEditChildProductModel, ChildProduct>(model, childProduct);
            foreach (var tier in childProduct.PriceTiers)
            {
                tier.ChildProduct = childProduct;
            }
            UnitOfWork.Commit();

            return ListChildProducts(model.ProductID);
        }

Shouldn't this work, as I get the ChildProduct with the related PriceTiers collection and use AutoMapper to map the differences? I maintain hidden fields for the PK and FK fields on the PriceTier.

I am a bit confused.

like image 201
Sam Avatar asked Dec 09 '22 06:12

Sam


1 Answers

You could use editor templates:

@model AddEditChildProductModel
@using (Html.BeginForm())
{
    <div>
        @Html.LabelFor(x => x.Name)
        @Html.EditorFor(x => x.Name)
        @Html.ValidationMessageFor(x => x.Name)
    </div>

    <div>
        @Html.LabelFor(x => x.Sku)
        @Html.EditorFor(x => x.Sku)
        @Html.ValidationMessageFor(x => x.Sku)
    </div>

    <table>
        <thead>
            <tr>
                <th>QtyStart</th>
                <th>QtyEnd</th>
            </tr>
        </thead>
        <tbody>
            @Html.EditorFor(x => x.PriceTiers)
        </tbody>
    </table>

    <input type="submit" value="OK">
}

and then define the editor template which will be rendered for each element of the PriceTiers list (~/Views/Shared/EditorTemplates/AddEditPriceTierModel.cshtml) - the name and location of the editor template is important. You could also put it in ~/Views/SomeController/EditorTemplates/AddEditPriceTierModel.cshtml if the editor template is specific only for a given controller:

@model AddEditPriceTierModel
<tr>
    <td>
        @Html.LabelFor(x => x.QtyStart)
        @Html.EditorFor(x => x.QtyStart)
        @Html.ValidationMessageFor(x => x.QtyStart)
    </td>
    <td>
        @Html.LabelFor(x => x.QtyEnd)
        @Html.EditorFor(x => x.QtyEnd)
        @Html.ValidationMessageFor(x => x.QtyEnd)
    </td>
</tr>

and now your POST controller action signature will look like this:

[HttpPost]
public ActionResult Edit(AddEditChildProductModel model)
{
    ...
}
like image 146
Darin Dimitrov Avatar answered Jan 30 '23 05:01

Darin Dimitrov