我正在尝试使用ajax将Product对象从视图发送到控制器,在发布这个问题之前我已经搜索了很多,但大多数结果显示了如何发送对象数组或文件数组,但在我的情况下,我的主对象包含数组文件和对象数组。 以下是产品和产品变体模型:
public class Product
{
public int Id { get; set; }
public required string Name { get; set; } = string.Empty;
public string Description { get; set; } = string.Empty;
public int SubcategoryId { get; set; }
public virtual Subcategory? Subcategory { get; set; }
public virtual List<ProductImage> Images { get; set; } = new List<ProductImage>();
public virtual IEnumerable<ProductVariant> Variants { get; set; } = new List<ProductVariant>();
[NotMapped]
public IEnumerable<IFormFile> FormFiles { get; set; }
}
public class ProductVariant
{
public int Id { get; set; }
public int ProductId { get; set; }
public required int Quantity { get; set; }
public int MinQuantity { get; set; } = 1;
public int? MaxQuantity { get; set; }
public double? Width { get; set; }
public double? Length { get; set; }
public double? Height { get; set; }
public double? Weight { get; set; }
public required double Price { get; set; }
public double Discount { get; set; } = 0;
public ProductSize? Size { get; set; } // enum
public Gender? Gender { get; set; } // enum
public string? Color { get; set; } = string.Empty;
public string? Material { get; set; } = string.Empty;
public virtual Product? Product { get; set; }
}
当我提交和调试产品变体列表为空而文件和属性填充了数据时 这里是风景
@model DataAccessLayer.Models.Product.Product
@{
ViewData["Title"] = "Create Product";
}
<div class="dash-content">
<div class="page-header mb-3">
<div class="text-center">
<h4>Add New Product</h4>
</div>
</div>
<div class="create-category">
<div asp-action="Create" method="post" class="card" enctype="multipart/form-data" id="form">
<div class="card-body">
<div class="row ">
<div class="col-lg-6 mb-3">
<div class="form-group">
<label asp-for="Name"></label>
<input asp-for="Name" class="form-control" placeholder="Product Name" id="Name">
</div>
</div>
<div class="col-lg-6 col-sm-6 col-12 mb-3">
<div class="form-group">
<label asp-for="Subcategory"></label>
<select asp-for="SubcategoryId" class="form-select" id="SubcategoryId">
<option selected disabled>Select Sucategory</option>
@foreach (Category cat in ViewBag.categories)
{
<optgroup label="@cat.Name">
@foreach (var subcat in cat.Subcategories)
{
<option value="@subcat.Id">@subcat.Name</option>
}
</optgroup>
}
</select>
</div>
</div>
<div class="col-lg-12 mb-3">
<div class="form-group">
<label asp-for="Description"></label>
<textarea asp-for="Description" class="form-control" rows="4" id="Description"></textarea>
</div>
</div>
<div class="col-lg-12 mb-3">
<div class="form-group mb-4">
<label>Product Images</label>
<div class="image-upload">
<input name="files" type="file" multiple accept="image/*" id="inputFiles">
</div>
</div>
</div>
<output></output>
<div class="col-lg-12 my-3 d-flex justify-content-center">
<div class="page-btn">
<a class="btn btn-add Mx-2" onclick="showSection()">Add Product Variant</a>
</div>
</div>
<div class="card-body pt-2 d-none" id="createVariant">
<div class="row gy-3">
<div class="col-lg-4 mb-3">
<div class="form-group">
<label>Quantity</label>
<input type="number" class="form-control" placeholder="Quantity" id="Quantity">
</div>
</div>
<div class="col-lg-4 mb-3">
<div class="form-group">
<label>Min Quantity</label>
<input type="number" class="form-control" placeholder="Min Quantity" id="Min-Quantity">
</div>
</div>
<div class="col-lg-4 mb-3">
<div class="form-group">
<label>Max Quantity</label>
<input type="number" class="form-control" placeholder="Max Quantity" id="Max-Quantity">
</div>
</div>
<div class="col-lg-4 mb-3">
<div class="form-group">
<label>Width</label>
<input type="number" class="form-control" placeholder="Width" id="width">
</div>
</div>
<div class="col-lg-4 mb-3">
<div class="form-group">
<label>Length</label>
<input type="number" class="form-control" placeholder="Length" id="Length">
</div>
</div>
<div class="col-lg-4 mb-3">
<div class="form-group">
<label>Height</label>
<input type="number" class="form-control" placeholder="Height" id="Height">
</div>
</div>
<div class="col-lg-4 mb-3">
<div class="form-group">
<label>Weight</label>
<input type="number" class="form-control" placeholder="Weight" id="Weight">
</div>
</div>
<div class="col-lg-4 mb-3">
<div class="form-group">
<label>Price</label>
<input type="number" class="form-control" placeholder="Price" id="Price">
</div>
</div>
<div class="col-lg-4 mb-3">
<div class="form-group">
<label>Discount</label>
<input type="number" class="form-control" placeholder="Discount" id="Discount">
</div>
</div>
<div class="col-lg-6 mb-3">
<div class="form-group">
<label>Size</label>
<select class="form-select" id="size">
<option selected>Select Size</option>
<option value="S">S</option>
<option value="M">M</option>
<option value="L">L</option>
<option value="XL">XL</option>
<option value="XXL">XXL</option>
<option value="XXXL">XXXL</option>
<option value="XXXXL">XXXXL</option>
<option value="XXXXXL">XXXXXL</option>
</select>
</div>
</div>
<div class="col-lg-6 mb-3">
<div class="form-group">
<label>Gender</label>
<select class="form-select" id="gender">
<option selected>Select Gender</option>
<option value="Male">Male</option>
<option value="Female">Female</option>
</select>
</div>
</div>
<div class="col-lg-6 mb-3">
<div class="form-group">
<label>Color</label>
<input type="text" class="form-control" placeholder="Color" id="Color">
</div>
</div>
<div class="col-lg-6 mb-3">
<div class="form-group">
<label>Material</label>
<input type="text" class="form-control" placeholder="Material" id="Material">
</div>
</div>
<div class="col-lg-12 my-3 d-flex justify-content-center">
<button type="button" class="btn btn-add me-2" onclick="addProductVariant()" id="addBtn">Add Variant</button>
</div>
</div>
</div>
</div>
<button class="btn btn-add mx-2" onclick="addProduct()">Add</button>
</div>
</div>
</div>
<div class="container">
<table class="table table-striped text-center">
<thead>
<tr>
<th>Quantity</th>
<th>Min Quantity</th>
<th>Max Quantity</th>
<th>Width</th>
<th>Length</th>
<th>Height</th>
<th>Weight</th>
<th>Price</th>
<th>Discount</th>
<th>Color</th>
<th>Material</th>
<th>Size</th>
<th>Gender</th>
<th colspan="2">Action</th>
</tr>
</thead>
<tbody id="table-body">
</tbody>
</table>
</div>
</div>
和 JavaScript 代码
function addProduct() {
let product = {
name: document.getElementById("Name").value,
description: document.getElementById("Description").value,
subcategoryId: document.getElementById("SubcategoryId").value,
variants: Variants,
}
var files = Array.from($('#inputFiles')[0].files);
var formData = new FormData();
for (var key in product) {
formData.append(key, product[key]);
}
for (var key in files) {
formData.append("formFiles", files[key]);
}
$.ajax({
url: "/Administration/Product/Create",
type: 'POST',
data: formData,
dataType: "json",
contentType: "multipart/form-data",
processData: false,
contentType: false,
success: function (data) {
console.log(data);
}
});
}
问题是除了产品变体列表为空之外,所有内容都传递给控制器。
产品控制器
public async Task<JsonResult> Create(Product product)
{
if (ModelState.IsValid)
{
UnitOfWork.ProductRepo.Add(product);
UnitOfWork.Save();
return Json("Success");
}
return Json("Fail");
}
ASP.NET 默认序列化行为默认使用 CamelCase,因此您必须使用小写命名 HTML 输入标记,这与 C# 类属性不同:
<div class="form-group">
<label>Quantity</label>
<input type="number" class="form-control" id="quantity">
</div>