React+Axios调用ASP.NET API时模型绑定数据为空问题排查
问题:React+Axios POST到ASP.NET API时后端接收数据为空/Null
我用React结合Axios向ASP.NET API发送POST请求,一开始报400 Bad Request,修改后端DTO后请求成功,但API接收的数据全是空或Null,怀疑是模型绑定问题。
前端代码
React组件代码
const defaultImgPath = '/assets/ImgStarter.jpg'; const initialFieldValues = { productName: 'Fried spring rolls', productPrice: 50000, productStatus: 1, productDescription: 'A short description', imagePath: defaultImgPath, imgName: '', ProductImg: null } const ApiUploadImg = () => { const [input, setInput] = useState(initialFieldValues) const handleAddProduct = (e) => { e.preventDefault(); axios.post('http://localhost:5273/api/product', input) .then((response) => { console.log(response); }) .catch((error) => { console.log(error.response); }) return ( <div className='form-uload'> <form className='p-5' onSubmit={handleAddProduct}> <Input inputType="text" labelname="Product name" name="productName" setInput={setInput} input={input} /> <Input inputType="number" labelname="Price" name="productPrice" setInput={setInput} input={input} /> <Input inputType="text" labelname="Status (Is available?)" name="productStatus" setInput={setInput} input={input} /> <Input inputType="text" labelname="Description" name="productDescription" setInput={setInput} input={input} /> <Input inputType="file" labelname="Image" name="productImg" setInput={setInput} input={input} onChange={handlePreviewImg} /> <div> <img src={input.imagePath} className='preview-img' /> </div> <button type='submit' className='form-controls btn btn-primary'>Submit</button> </form> </div> ) }
Input组件代码
const Input = ({ setInput, input, labelname, name, inputType, onChange=null}) => { const [value, setValue] = useState(''); const onChangeHanlder = (e) => { setInput({...input, [name]: e.target.value}) } var id = {name}; return ( <Fragment> <label htmlFor={id} className='font-semibold text-white'> {labelname}: </label> <input id={id} type={inputType} name={name} className='rounded input_form form-control mt-2 w-100' // placeholder={placeholder} onChange={onChange ? onChange : onChangeHanlder} /> </Fragment> ) }
后端代码
API接口代码
[HttpPost] public async Task<IActionResult> Create([FromBody] CreateProductRequestDTO requestDTO) { if(!ModelState.IsValid) { return BadRequest(ModelState); } var productModel = requestDTO.ToProductsFromCreateDTO(); await _productRepo.CreateAsync(productModel); return CreatedAtAction(nameof(GetById), new {id = productModel.Id}, productModel.ToProductDTO()); }
CreateProductRequestDTO的两种方案
public class CreateProductRequestDTO { //方案1 // public string? ProductName {get; set; } = string.Empty; // public int ProductPrice {get; set; } // public bool ProductStatus {get; set; } // public string? ProductDescription {get; set; } = string.Empty; //方案2 public string Name {get; set; } = string.Empty; public int Price {get; set; } public bool Status {get; set; } public string Description {get; set; } = string.Empty; }
请求与响应数据说明
- 请求数据:发送的JSON包含
productName、productPrice、productStatus、productDescription等字段,对应初始值或用户输入 - 响应数据:后端返回201 Created,但DTO中的字段全为默认值(空字符串、0、false)
问题原因分析
- 字段名称完全不匹配:前端发送的JSON字段是小驼峰命名(如
productName),而当前启用的方案2中DTO字段是短命名(Name),ASP.NET模型绑定默认要求字段名称完全匹配,无法自动映射语义相似的字段。 - 初始400错误的根源:方案1的DTO字段是大驼峰前缀命名(
ProductName),和前端的小驼峰productName大小写不匹配,导致模型验证失败,返回400 Bad Request。 - 类型匹配隐患:前端发送的
productStatus是数值1,但DTO中对应字段是bool类型,虽然ASP.NET支持数值到布尔的自动转换,但前提是字段名称匹配,否则转换逻辑不会触发。 - 序列化配置缺失:若未在ASP.NET中配置忽略大小写或自动驼峰映射的序列化规则,会进一步加剧字段名称不匹配导致的绑定失败。
内容的提问来源于stack exchange,提问作者jpesa
相关产品推荐
相关产品推荐

