我有一个负责CRUD操作的简单控制器,一个Pet模型,我使用fetch API向端点发送JavaScript请求。请求的主体是一个包含文件和模型的FormData对象,但这似乎不起作用,因为我得到错误代码“400 Bad Request”。我也用Postman做了同样的事情,结果是一样的。在检查响应体时,在错误部分中,我得到
"errors": {
"model.Name": [
"The Name field is required."
]
}
我想在一个请求中同时发送我的模型和文件。我在网上找到了一些解决方案,但是人们在他们的模型中添加了一个类型为“IFormFile”的额外属性,而我不想接触我的模型并将它们绑定到IFormFile,因为它们也应该在Web环境之外使用。
我有以下模型:
public class Pet
{
public Guid Id { get; set; }
public string Name { get; set; }
}
PetsController中的PUT控制器方法如下所示:
[HttpPut("{id:guid}")]
public ActionResult EditPet(Guid id, [FromForm]Pet model)
{
ArgumentNullCheck(model);
try
{
_logger.LogInformation($"Request recieved to edit pet with id {id}");
//Update model in repo
if (Request.Form.Files.Count != 0)
{
IFormFile file = Request.Form.Files[0];
//Store file locally.
}
return StatusCode(StatusCodes.Status200OK);
}
catch (Exception e)
{
_logger.LogError($"Error: {e.Message} when attempting to edit pet with id {id}");
return UnprocessableEntity();
}
}
我认为这对于PostMan请求来说已经足够了,但为了以防万一,我的fetch请求看起来像这样:
class Pet
{
name : string;
id : string;
constructor()
{
this.name = "";
this.id = "";
}
}
let model = new Pet();
model.id = //some GUID;
model.name = "Cheddar";
let payLoad = new FormData();
payLoad.append("model", JSON.stringify(model));
let file = getFileSomehow();
if (file)
{
payLoad.append("file", file);
}
let response: Response;
try
{
response = await fetch("../Pets/model.id",
{
method: 'PUT',
headers: {
'Content-type': "multipart/form-data"
},
body: payload
});
}
catch (err)
{
console.error(`Error processing update request, ${err}`);
return;
}
我想到的一个变通方法是发送两个单独的请求,但我宁愿保持内容完整,理想情况下-一次性发送它们。任何建议都很感激(:.
1条答案
按热度按时间ccgok5k51#
我找到了解决方案,它包括使用请求。窗体来访问File并反序列化模型的值,该值也是从Request中检索的。因此,考虑到这一点,控制器应该看起来像这样: