【问题标题】:How to upload file AND model using Web API?如何使用 Web API 上传文件和模型?
【发布时间】:2016-07-02 20:43:30
【问题描述】:

基本上我正在尝试使用 Web API 2 上传图像和枚举。

这是控制器签名:

[HttpPost]
public UploadResponseVm Upload([FromBody]ResImageType type)
{

问题是,每当我尝试发布多部分表单(带有文件和类型)时,我都会收到 415 错误:

{"Message":"请求实体的媒体类型'multipart/form-data'是 此资源不支持。","ExceptionMessage":"否 MediaTypeFormatter 可用于读取类型的对象 来自具有媒体类型的内容的“ResImageType” 'multipart/form-data'。","ExceptionType":"System.Net.Http.UnsupportedMediaTypeException","StackTrace":" 在 System.Net.Http.HttpContentExtensions.ReadAsAsync[T](HttpContent 内容,类型类型,IEnumerable1 formatters, IFormatterLogger formatterLogger, CancellationToken cancellationToken)\r\n at System.Web.Http.ModelBinding.FormatterParameterBinding.ReadContentAsync(HttpRequestMessage request, Type type, IEnumerable1 格式化程序,IFormatterLogger formatterLogger, CancellationToken cancelToken)"}

我什至在我的 startup.cs 类中添加了以下内容:

    config.Formatters.Insert(0, new System.Net.Http.Formatting.JsonMediaTypeFormatter());

如何使用 Web api 控制器上传模型和文件?

【问题讨论】:

    标签: asp.net rest http asp.net-web-api asp.net-web-api2


    【解决方案1】:

    您可以通过在标头请求中添加内容类型来简单地同时添加媒体和枚举。

    Content-Type:application/x-www-form-urlencoded
    

    然后尝试访问文件和枚举

    [HttpPost]
    public UploadResponseVm Upload()
    {
                //Get enum type
                var enumkey = HttpContext.Current.Request.Form.AllKeys.FirstOrDefault(x => x == "enumkey");
                var enumType = Convert.ToInt32(HttpContext.Current.Request.Form[enumkey]).ToEnum<ResImageType>();
    
                //Access files
                var postedFileLst = HttpContext.Current.Request.Files.GetMultiple("fileKey").ToList();
    }
    

    使用扩展方法转换为枚举

    public static T ToEnum<T>(this int param)
    {
                var info = typeof(T);
                if (info.IsEnum)
                {
                    T result = (T)Enum.Parse(typeof(T), param.ToString(), true);
                    return result;
                }
    
                return default(T);
    }
    

    同样使用 curl 验证

    curl --location --request POST '{{hostname}}/api/media/addmedia' \
    --header 'Content-Type: application/x-www-form-urlencoded' \
    --form 'BookLogos=@/path/to/file' \
    --form 'enumkey=1'
    

    【讨论】:

      【解决方案2】:

      没有可以处理/关联到您的ResImageType 对象的格式化程序。我曾经通过使用无参数方法在没有格式化程序的情况下解决了类似的问题,并在方法内部处理了数据。例如:

      public async Task<HttpResponseMessage> PostFormData()
          {
              if (!Request.Content.IsMimeMultipartContent("form-data"))
              {
                  return Request.CreateResponse(HttpStatusCode.BadRequest);
              }
      
                  string upDir= "PathOfDirectory";
      
                  MultipartFormDataStreamProvider streamProvider = new MultipartFormDataStreamProvider(upDir);                
                  MultipartFileStreamProvider multipartFileStreamProvider = await Request.Content.ReadAsMultipartAsync(streamProvider);
      
                  // Loop through files.
                  foreach (MultipartFileData file in streamProvider.FileData)
                  {
                      // Save filepaths to DB or do something else
                  }
                  return Request.CreateResponse(HttpStatusCode.OK);
          }
      

      来自MS Docs的类似解决方案

      另一种可能性是创建一个类似 DTO 的类,用于传输对象并使用格式化程序,例如 MultipartDataMediaFormatter 似乎是合法的(没有尝试过)。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-11-24
        • 2021-08-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-11-01
        • 2021-12-28
        • 1970-01-01
        相关资源
        最近更新 更多