2016-11-24 51 views
3

有人可以帮我解决这个问题。我试图限制张贴绑定参数的行为,但它似乎根本不起作用。当我删除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">[email protected]</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核心问题,有人可以指示pelase吗?

+1

视图模型不应该包含属于数据模型的属性。您查看模型应该包含属性'ID','CategoryId','Description'等 - 即只是想在视图中需要。当正确使用视图模型时,从不需要'[Bind]'属性 –

+3

也不需要为每个属性添加前缀,只需使用:[Bind(“Id”,“CategoryId”,“Description”, “Title”,Prefix = nameof(ProductCreateViewModel.Product))]' –

+0

@StephenMuecke:我遵循MS原创文章DRY(不要重复自己)的原则。但发现文件上传的问题,因为它没有包含在帖子中,所以我添加了一个VM和Model和IFromFile集合。欲了解更多信息,请访问这里的帖子:https://docs.microsoft。com/en-us/aspnet/core/tutorials/first-mvc-app/controller-methods-views – NiL

回答

1

您需要将您的值作为params string[],而不是用逗号分隔的一个string

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

Source

+0

他们都能正常工作。不管怎样,谢谢你,* Prefix = nameof(ProductCreateViewModel.Product)* param! – NiL

2

为什么你使用Bind为你的情况我不太清楚。

只需创建您需要的属性的门卫ViewModelProductCreateStort

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

这样你就不会乱Bind和减少对POST

3

您的PARAMS虽然我是相当新的ASP.NET核心我自己(和未来的这个问题7月中下旬),我就遇到了这个同样的问题。我认为这里的关键是你必须绑定“产品”才能被考虑。绑定“Product.Id”本身看起来不够好。所以这应该工作:

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

当然,哈米德Mosalla的评论是一个更好的选择,如果你所有的绑定属性是嵌套对象(这会导致不知道为什么你需要摆在首位视图模型)上。在我的情况下,我有一个嵌套对象和一个本地属性,所以使用“前缀”解决方案并不是正确的做法。

无论如何,希望这可以帮助别人。