为什么Bind属性似乎破坏了我对嵌套对象的模型绑定?

时间:2016-11-24 08:38:15

标签: asp.net-core asp.net-core-mvc

有人可以帮我解决这个问题。我试图限制使用绑定参数动作的发布,但它似乎根本不起作用。当我删除Bind关键字时,一切都开始成为魅力。

以下是代码示例:

查看型号:

public class ProductCreateViewModel
{
    public Product Product { get; set; }
    public ICollection<IFormFile> Images { get; set; }
}

动作:

[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create([Bind("Product.Id,Product.CategoryId,Product.Description,Product.Title")] ProductCreateViewModel productVM)
{
    if (ModelState.IsValid)
    {
        _context.Add(productVM.Product);
        await _context.SaveChangesAsync();
        return RedirectToAction("Index");
    }
    ViewData["CategoryId"] = new SelectList(_context.Categories.Include(c => c.Categories).Where(c => c.ParentCategoryId == null), "Id", "Name", productVM.Product.CategoryId);
    return View(productVM);
}

查看:

@model CatalogWebApp.Models.ProductsViewModels.ProductCreateViewModel

@{
    ViewData["Title"] = "Add Product";
    ViewData["BigPageTitle"] = "Products";
    ViewData["PageBoxTitle"] = "Add New Product";
}

<form asp-action="Create">
    <div class="form-horizontal">
        <div asp-validation-summary="ModelOnly" class="text-danger"></div>
        <div class="form-group">
            <label asp-for="Product.CategoryId" class="col-md-2 control-label"></label>
            <div class="col-md-10">
                <select name="Product.CategoryId" class ="form-control">
                    @foreach(Category item in (ViewBag.CategoryId as SelectList).Items)
                    {
                        <option value="@item.Id">@item.Name</option>
                        if (item.Categories != null && item.Categories.Count > 0)
                        {
                            foreach (var subCat in item.Categories)
                            {
                                <option value="@subCat.Id">--@subCat.Name</option>
                            }
                        }
                    }
                </select>
            </div>
        </div>
        <div class="form-group">
            <label asp-for="Product.Description" class="col-md-2 control-label"></label>
            <div class="col-md-10">
                <input asp-for="Product.Description" class="form-control" />
                <span asp-validation-for="Product.Description" class="text-danger" />
            </div>
        </div>
        <div class="form-group">
            <label asp-for="Product.Title" class="col-md-2 control-label"></label>
            <div class="col-md-10">
                <input asp-for="Product.Title" class="form-control" />
                <span asp-validation-for="Product.Title" class="text-danger" />
            </div>
        </div>
        <div class="form-group">
            <div class="col-md-offset-2 col-md-10">
                <input type="submit" value="Create" class="btn btn-default" />
            </div>
        </div>
    </div>
</form>

<div>
    <a asp-action="Index">Back to List</a>
</div>

@section Scripts {
    @{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
}

有人可能表示我是否有问题,或者只是一个已知的asp.net核心问题?

3 个答案:

答案 0 :(得分:3)

虽然我自己对ASP.NET Core很新(并且在7个月后才讨论这个问题),但我遇到了同样的问题。我认为这里的关键是你必须绑定“产品”才能被考虑。绑定“Product.Id”本身似乎不够好。所以这应该有效:

[Bind("Product,Product.Id,Product.CategoryId,Product.Description,Product.Title")]

当然,如果你的所有绑定属性都在嵌套对象上,那么Hamid Mosalla的注释是一个更好的选择(这会让你想知道为什么你需要一个视图模型)。在我的情况下,我有一个嵌套对象和一个本地属性,所以使用“前缀”解决方案是不正确的。

无论如何,希望这有助于某人。

答案 1 :(得分:2)

我不太清楚你为什么要使用Bind

只需创建仅包含ViewModel所需属性的sepatate ProductCreateStort

然后在控制器签名中使用此ViewModel并从中继承主模型。

通过这种方式,您不会弄乱Bind并限制POST上的参数

答案 2 :(得分:1)

您需要将您的值传递为params string[],而不是以逗号分隔的单个string

[Bind("Product.Id","Product.CategoryId","Product.Description","Product.Title")]

请参阅Source