Rest 如何将文件作为ViewModel对象的一部分发送到Web API
我有带有以下控制器的.NET核心Web应用程序:Rest 如何将文件作为ViewModel对象的一部分发送到Web API,rest,api,.net-core,asp.net-core-2.0,Rest,Api,.net Core,Asp.net Core 2.0,我有带有以下控制器的.NET核心Web应用程序: [HttpPost] public async Task<IActionResult> Update(StudentDetailsViewModel vm) { var tokenNo = HttpContext.Session.GetString("Token"); vm.ID = Convert.ToInt32(HttpContext.Session.G
[HttpPost]
public async Task<IActionResult> Update(StudentDetailsViewModel vm)
{
var tokenNo = HttpContext.Session.GetString("Token");
vm.ID = Convert.ToInt32(HttpContext.Session.GetString("StudentId"));
HttpClient client = new HttpClient();
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", tokenNo);
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
var putStudentUrl = _appSettings.Value.Apis.GSRTCApi.Url + _appSettings.Value.Apis.GSRTCApi.StudentsEndpoint + vm.ID;
var settings = new JsonSerializerSettings();
var stringData = JsonConvert.SerializeObject(vm);
var contentData = new StringContent(stringData, Encoding.UTF8, "application/json");
var response = await client.PutAsync(putStudentUrl, contentData); // contentData);
return RedirectToAction("Index", "Home");
}
[HttpPost]
公共异步任务更新(StudentDetailsViewModel vm)
{
var tokenNo=HttpContext.Session.GetString(“令牌”);
vm.ID=Convert.ToInt32(HttpContext.Session.GetString(“StudentId”);
HttpClient=新的HttpClient();
client.DefaultRequestHeaders.Authorization=新的AuthenticationHeaderValue(“承载者”,令牌号);
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(新的MediaTypeWithQualityHeaderValue(“应用程序/json”);
var putStudentUrl=_-appSettings.Value.api.GSRTCApi.Url+_-appSettings.Value.api.GSRTCApi.StudentsEndpoint+vm.ID;
var settings=new JsonSerializerSettings();
var stringData=JsonConvert.SerializeObject(vm);
var contentData=newstringcontent(stringData,Encoding.UTF8,“application/json”);
var response=await client.PutAsync(putStudentUrl,contentData);//contentData);
返回重定向到操作(“索引”、“主页”);
}
控制器调用我的Web API,一切正常,直到我通过html表单上传文件。发生这种情况时,将在客户端StudentDetailsViewModel的IFormFile属性中拾取该文件,但在进行API调用时,整个对象为null。API控制器是:
[HttpPut("{id}")]
public async Task<IActionResult> Put(int? id, [FromBody]StudentViewModel student)
{
// API operations here
}
[HttpPut(“{id}”)]
公共异步任务Put(int?id,[FromBody]StudentViewModel student)
{
//这里的API操作
}
我怀疑我没有正确序列化StudentDetailsViewModel对象,因为我有一个属性IFormFile,它是一个接口。但是,我不确定如何定制Json.Newsoft对象 要发送
ifformfile
,您需要使用FromForm
,这是从body和MultipartFormDataContent
中删除时的默认值
以下是完整的步骤:
Web应用程序模型
public class StudentDetailsViewModel
{
公共int Id{get;set;}
公共字符串名称{get;set;}
公共文件{get;set;}
}
Web应用程序控制器
public异步任务更新(StudentDetailsViewModel-vm)
{
HttpClient=新的HttpClient();
var putStudentUrl=@“url”;
字节[]数据;
使用(var br=new二进制读取器(vm.File.OpenReadStream())
{
data=br.ReadBytes((int)vm.File.OpenReadStream().Length);
}
ByteArrayContent字节=新的ByteArrayContent(数据);
MultipartFormDataContent multiContent=新的MultipartFormDataContent();
添加(字节,“文件”,vm.file.FileName);
Add(新的StringContent(vm.Id.ToString()),“Id”);
添加(新的StringContent(vm.Name),“Name”);
var response=await client.PutAsync(putStudentUrl,多内容);
返回重定向到操作(“索引”、“主页”);
}
webapi模型
公共类学生视图模型
{
公共int Id{get;set;}
公共字符串名称{get;set;}
公共文件{get;set;}
}
Web API控制器
[HttpPut(“{id}”)]
公共异步任务Put(int?id,StudentViewModel student)
{
使用(var stream=newfilestream(@“文件路径”,FileMode.Create))
{
等待student.File.CopyToAsync(流);
}
返回Ok();
}
注意multiContent.Add(字节,“文件”,vm.file.FileName)代码>,第二个参数是ifformfile
字段的名称。包括模型和调用JS。我没有JS代码只是一个带有asp标记的表单。我有一个虚拟对象属性作为模型的一部分,当我使用[FromForm]而不是[FromBody]时,我无法将其发送到API。此外,它对我来说似乎不是一个非常优雅的解决方案,因为我需要将每一个属性添加到多内容中。对我来说不起作用。我在API控制器上得到415种不受支持的媒体类型。multiContent.Add(字节,“file”,vm.file.FileName)代码>-对我来说很有用,它是一个ByteArrayContent
而不是StreamContent
。尽管不确定StreamContent
是否也能正常工作。