我试图将“产品规格”列表绑定到我的“添加产品”对话框。提交是使用AJAX进行的。
由于我允许用户以相同的形式上传产品图片,因此我将发送带有“ FormData”对象的AJAX请求,而不是进行序列化。
结果是由于“规格”列表的格式不符合控制器期望的格式,所以无法执行控制器操作。
public class ProductModalViewModel
{
public ProductModalViewModel()
{
Product = new Product();
Specs = new List<Spec>();
}
public Product Product { get; set; }
//Other properties removed for brevity
public List<Spec> Specs { get; set; }
}
<form id="formSaveProduct" onsubmit="SaveProduct(event)" enctype="multipart/form-data">
<input type="hidden" asp-for="Product.Id" />
//Removed other form fields for brevity
<div class="specs-list-group">
<ul class="list-group">
@for (int i = 0; i < Model.Specs.Count(); i++)
{
<li class="list-group-item">
<input type="hidden" asp-for="@Model.Specs[i].Id" />
<div class="row">
<div class="col-5">
<input type="text" asp-for="@Model.Specs[i].Name" />
</div>
<div class="col-5">
<input type="text" asp-for="@Model.Specs[i].Value" />
</div>
</div>
</li>
}
</ul>
</div>
</form>
function SaveProduct(e) {
e.preventDefault(); // prevent standard form submission
$.ajax({
url: "@Url.Action("SaveProduct", "ProductManagement", new { Area = "Admin" })",
method: "post",
data: new FormData($('#formSaveProduct')[0]),
contentType: false,
processData: false,
success: function (result) {
if (result.success) {
$("#exampleModal").modal('toggle');
location.reload();
}
else {
$(".modal-body").html(result);
}
},
error: function (e) {
alert("Error: " + e.status)
}
});
}
[HttpPost]
public ActionResult SaveProduct(ProductModalViewModel model)
{
//Save
}
FormData:
Product.Id: 1
Product.Brand: Browning
Product.Model: Gold Mossy Oak Shadow Grass Blades
Product.ProductNum: 723654
Product.CategoryId: 4
Product.IsActive: true
Product.Overview: This is an overview of the tkjsldfgn jlfdgl-sdfgn lkjgfnjkl dfsngkl kjlngkldf jngjkln kdfjnggf h sd sdfgdf...
Specs[0].Id: 1
Specs[0].Name: Test Spec 1
Specs[0].Value: Test Value 1
Specs[1].Id: 2
Specs[1].Name: Test Spec 2
Specs[1].Value: Test Value 2
Specs[2].Id: 3
Specs[2].Name: Test Spec 3
Specs[2].Value: Test Value 3
在我添加规格列表之前,此表格可以很好地工作。使用FormData对象时,我需要更改哪些内容来绑定列表?
编辑:添加了规范实体以供故障排除参考。
public class Spec
{
[Key]
public int Id { get; set; }
public Spec(string name, string value)
{
Name = name;
Value = value;
}
[Required]
public string Name { get; set; }
[Required]
public string Value { get; set; }
[ForeignKey("Product")]
[Required]
public int ProductId {get; set; }
public virtual Product Product { get; set; }
//Timestamps
public DateTime? Created { get; set; }
public DateTime? Modified { get; set; }
}
答案 0 :(得分:1)
在Controller的操作中修改模型参数以使用[FromForm]
属性:
[HttpPost]
public ActionResult SaveProduct([FromForm]ProductModalViewModel model)
{
//Save
}
您可以阅读有关绑定行为here的更多信息。
更新:
我怀疑您的问题来自两件事:
Spec
类没有无参数的构造函数这是我的建议:
您实际上不应该将实体模型放入视图中。
我建议您创建一个名为SpecDto
的新类,并遵循以下规则
[ForeignKey("Product")]
赞:
public class SpecDto
{
public int Id { get; set; }
[Required]
public string Name { get; set; }
[Required]
public string Value { get; set; }
public int ProductId { get; set; }
public DateTime? Created { get; set; }
public DateTime? Modified { get; set; }
}
您应该对产品执行相同的操作。
然后,您的ViewModel应该看起来像:
public class ProductModalViewModel
{
public ProductModalViewModel()
{
Product = new ProductDto();
Specs = new List<SpecDto>();
}
public ProductDto Product { get; set; }
public List<SpecDto> Specs { get; set; }
}
然后在您的控制器中,将数据从DTO类传输到实体模型。我知道这似乎很乏味,但这是做这些事情的正确方法。如果您的项目很大,请使用AutoMapper传输数据。如果您的项目范围真的很小,那么也许您可能会争辩说要在视图中使用实体模型的情况,但这通常不是一个好主意。