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

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

我有带有以下 Controller 的 .NET Core Web 应用程序:

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

Controller 调用我的 Web API,一切正常,直到我通过我的 html 表单上传文件。发生这种情况时,会在客户端的 StudentDetailsViewModel 的 IFormFile 属性中获取文件,但在进行 API 调用时,整个对象为空。 API Controller 是:
[HttpPut("{id}")]
public async Task<IActionResult> Put(int? id, [FromBody]StudentViewModel student)
{
    // API operations here
} 

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

最佳答案

发送IFormFile , 你需要使用 FromForm这是删除 FromBody 时的默认值和 MultipartFormDataContent .

以下是完整的步骤:

  • 网络应用模型

  • public class StudentDetailsViewModel
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public IFormFile File { get; set; }
    }
    
  • 网络应用 Controller

  • 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");
    }
    
  • Web API 模型

  • public class StudentViewModel
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public IFormFile File { get; set; }
    }
    
  • Web API Controller

  • [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 的名称 field 。

    关于rest - 如何将 IFormFile 作为 ViewModel 对象的一部分发送到 Web API,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51798265/

    相关文章:

    java - 使用 Spring MVC 创建 Spring Rest Web 服务来处理大型请求和响应

    javascript - 这个 Oauth 请求中我的 JSON 有什么问题?

    java - 如何在 Rest Api 调用中设置多个响应类型

    sql - Dota2 - 是否可以通过 API 将私有(private)比赛信息获取到 sql 数据库中?

    c# - .NET CORE CLI 可以从文件加载参数吗?

    ruby-on-rails - 如何在 Rails REST API 中使用外部提供的 ID?

    javascript - 无法使用 API 的输入替换 Handlebars 变量

    c++ - 在跨平台 C 和 C++ API 中使用字符串的当前最佳实践是什么?

    c# - .net core 2 的编码问题

    c# - HttpClient/HttpRequestMessage 向 header 添加空格