如何将IFormFile作为ViewModel对象的一部分发送到Web API

时间:2018-08-11 09:20:20

标签: rest api .net-core asp.net-core-2.0

我具有带有以下控制器的.NET Core Web App:

    [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");
    }

控制器调用我的Web API,一切正常,直到我通过html表单上传文件。发生这种情况时,将在客户端的StudentDetailsViewModel的IFormFile属性中拾取该文件,但是当进行API调用时,整个对象为null。 API控制器为:

[HttpPut("{id}")]
public async Task<IActionResult> Put(int? id, [FromBody]StudentViewModel student)
{
    // API operations here
} 

我怀疑我没有正确序列化StudentDetailsViewModel对象,因为我有一个属性IFormFile,它是一个接口。但是,我不确定到底该如何自定义Json.Newsoft对象。

1 个答案:

答案 0 :(得分:3)

要发送IFormFile,您需要使用FromForm,这是删除FromBodyMultipartFormDataContent时的默认设置。

以下是完整的步骤:

  1. 网络应用程序模型

    public class StudentDetailsViewModel
    {
    public int Id { get; set; }
    public string Name { get; set; }
    public IFormFile File { get; set; }
    }
    
  2. Web应用程序控制器

        public async Task<IActionResult> Update(StudentDetailsViewModel vm)
    {
    
        HttpClient client = new HttpClient();
        var putStudentUrl = @"url";
        byte[] data;
        using (var br = new BinaryReader(vm.File.OpenReadStream()))
            data = br.ReadBytes((int)vm.File.OpenReadStream().Length);
        ByteArrayContent bytes = new ByteArrayContent(data);
        MultipartFormDataContent multiContent = new MultipartFormDataContent();
        multiContent.Add(bytes, "file", vm.File.FileName);
        multiContent.Add(new StringContent(vm.Id.ToString()),"Id");
        multiContent.Add(new StringContent(vm.Name), "Name");
        var response = await client.PutAsync(putStudentUrl, multiContent); 
        return RedirectToAction("Index", "Home");
    }
    
  3. Web API模型

        public class StudentViewModel
       {
         public int Id { get; set; }
         public string Name { get; set; }
         public IFormFile File { get; set; }
       }
    
  4. Web API控制器

        [HttpPut("{id}")]
    public async Task<IActionResult> Put(int? id,StudentViewModel student)
    {
        using (var stream = new FileStream(@"file path", FileMode.Create))
        {
            await student.File.CopyToAsync(stream);
        }
        return Ok();
    }
    

    请注意multiContent.Add(bytes, "file", vm.File.FileName);,第二个参数是IFormFile字段的名称。