POST-действие с передачей нулевого ViewModel

Я знаю, что этот вопрос задавался и отвечал десятки раз, но ни одно из решений не помогло мне.

У меня есть следующая ViewModel, которая состоит из модели данных ProductDetail и списка модели данных Product_ProductCategoryAttribute.

public class ProductDetailViewModel
{
    public ProductDetail ProductDetail { get; set; }
    public List<Product_ProductCategoryAttribute> Product_ProductCategoryAttribute { get; set; }
}

На обратной передаче действия я получаю пустую ViewModel.

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit([Bind(Include = "idProductDetail,idProductCategory,idProduct,Name,Description")] ProductDetailViewModel productDetailAll)
    {
        if (ModelState.IsValid)
        {
            ProductDetail productDetail = productDetailAll.ProductDetail;
            db.Entry(productDetail).State = EntityState.Modified;
            db.SaveChanges();

            return RedirectToAction("Index");
        }
        return View(productDetailAll);
    }

Однако, поскольку я считаю, что основная проблема находится где-то внутри представления, я добавлю фрагмент кода представления.

@using (Html.BeginForm("Edit", "ProductDetail", FormMethod.Post))
{
    @Html.AntiForgeryToken()

    <div class="form-horizontal">
        @Html.HiddenFor(model => model.ProductDetail.idProductDetail)

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

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

        @for (int i = 0; i < Model.Product_ProductCategoryAttribute.Count(); i++)
        {
            <div class="form-group">
                <label class="control-label col-md-2">@Model.Product_ProductCategoryAttribute[i].ProductCategoryAttribute.Name</label>
                <div class="col-md-5">
                    @Html.TextBoxFor(model => model.Product_ProductCategoryAttribute[i].Value, new { @class = "form-control" })
                </div>
            </div>
        }

        <div class="form-group">
            <div class="col-md-offset-2 col-md-10">
                <input type="submit" value="Save" class="btn btn-sm btn-default" />
            </div>
        </div>
    </div>
}

HTML, сгенерированный из представленного выше представления, выглядит следующим образом (некоторые части для краткости опущены):

<form action="/Administration/ProductDetail/Edit/4" method="post"><input name="__RequestVerificationToken" type="hidden" value="IS4fstTTjOD4d9FEzyM5yWlvO9xqlOq_AHFx_8_vC079F1iDvucf5wgRIgV4iXH-NGU-u-J8IHBiKT4ApvR3cSLbhw_AntbibEFsD68eUkc1" />
        <input data-val="true" data-val-number="The field idProductDetail must be a number." data-val-required="The idProductDetail field is required." id="ProductDetail_idProductDetail" name="ProductDetail.idProductDetail" type="hidden" value="4" />

        <div class="form-group">
            <label class="control-label col-md-2" for="ProductDetail_Name">Name</label>
            <div class="col-md-10">
                <input htmlAttributes="{ class = form-control }" id="ProductDetail_Name" name="ProductDetail.Name" type="text" value="Čipka i hiljadu šara" />
            </div>
        </div>

        <div class="form-group">
            <label class="control-label col-md-2" for="ProductDetail_Description">Description</label>
            <div class="col-md-10">
                <input htmlAttributes="{ class = form-control }" id="ProductDetail_Description" name="ProductDetail.Description" type="text" value="Šipka i čipka" />
            </div>
        </div>

            <div class="form-group">
                <label class="control-label col-md-2">Veličina</label>
                <div class="col-md-5">
                    <input class="form-control" id="Product_ProductCategoryAttribute_0__Value" name="Product_ProductCategoryAttribute[0].Value" type="text" value="" />
                </div>

            </div>
            <div class="form-group">
                <label class="control-label col-md-2">Širina</label>
                <div class="col-md-5">
                    <input class="form-control" id="Product_ProductCategoryAttribute_1__Value" name="Product_ProductCategoryAttribute[1].Value" type="text" value="" />
                </div>

            </div>
            <div class="form-group">
                <label class="control-label col-md-2">Pakiranje</label>
                <div class="col-md-5">
                    <input class="form-control" id="Product_ProductCategoryAttribute_2__Value" name="Product_ProductCategoryAttribute[2].Value" type="text" value="" />
                </div>

            </div>

        <div class="form-group">
            <div class="col-md-offset-2 col-md-10">
                <input type="submit" value="Save" class="btn btn-sm btn-default" />
            </div>
        </div>
    </div>

Я не уверен, что с соглашением об именах что-то не так, но моя ставка была бы на это.

1 ответ

Решение

Проблема была в автоматически сгенерированном действии Edit контроллера, которое добавило несколько атрибутов [Bind(Include="")], которые были неправильными и которые препятствовали отправке данных на сервер.

Правильный фрагмент будет выглядеть так:

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit (ProductDetailViewModel productDetailAll)
{
    if (ModelState.IsValid)
    {
        ProductDetail productDetail = productDetailAll.ProductDetail;
        db.Entry(productDetail).State = EntityState.Modified;
        db.SaveChanges();

        return RedirectToAction("Index");
    }
    return View(productDetailAll);
}
Другие вопросы по тегам