How to set up a Web API controller for multipart/form-data

强颜欢笑 提交于 2019-11-26 08:08:00

问题


I am trying to figure this out. I was not getting any useful error messages with my code so I used something else to generate something. I have attached that code after the error message. I have found a tutorial on it but I do not know how to implement it with what I have. This is what I currently have:

public async Task<object> PostFile()
    {
        if (!Request.Content.IsMimeMultipartContent())
            throw new Exception();


        var provider = new MultipartMemoryStreamProvider();
        var result = new { file = new List<object>() };
        var item = new File();

        item.CompanyName = HttpContext.Current.Request.Form[\"companyName\"];
        item.FileDate = HttpContext.Current.Request.Form[\"fileDate\"];
        item.FileLocation = HttpContext.Current.Request.Form[\"fileLocation\"];
        item.FilePlant = HttpContext.Current.Request.Form[\"filePlant\"];
        item.FileTerm = HttpContext.Current.Request.Form[\"fileTerm\"];
        item.FileType = HttpContext.Current.Request.Form[\"fileType\"];

        var manager = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(new ApplicationDbContext()));
        var user = manager.FindById(User.Identity.GetUserId());

        item.FileUploadedBy = user.Name;
        item.FileUploadDate = DateTime.Now;

        await Request.Content.ReadAsMultipartAsync(provider)
         .ContinueWith(async (a) =>
         {
             foreach (var file in provider.Contents)
             {
                 if (file.Headers.ContentLength > 1000)
                 {
                     var filename = file.Headers.ContentDisposition.FileName.Trim(\'\\\"\');
                     var contentType = file.Headers.ContentType.ToString();
                     await file.ReadAsByteArrayAsync().ContinueWith(b => { item.FilePdf = b.Result; });
                 }


             }


         }).Unwrap();

        db.Files.Add(item);
        db.SaveChanges();
        return result;

    }

Error:

Object {message: \"The request entity\'s media type \'multipart/form-data\' is not supported for this resource.\", exceptionMessage: \"No MediaTypeFormatter is available to read an obje…om content with media type \'multipart/form-data\'.\", exceptionType: \"System.Net.Http.UnsupportedMediaTypeException\", stackTrace: \" at System.Net.Http.HttpContentExtensions.ReadAs…atterLogger, CancellationToken cancellationToken)\"}exceptionMessage: \"No MediaTypeFormatter is available to read an object of type \'HttpPostedFileBase\' from content with media type \'multipart/form-data\'.\"exceptionType: \"System.Net.Http.UnsupportedMediaTypeException\"message: \"The request entity\'s media type \'multipart/form-data\' is not supported for this resource.\"stackTrace: \" at System.Net.Http.HttpContentExtensions.ReadAsAsync[T](HttpContent content, Type type, IEnumerable1 formatters, IFormatterLogger formatterLogger, CancellationToken cancellationToken) ↵ at System.Net.Http.HttpContentExtensions.ReadAsAsync(HttpContent content, Type type, IEnumerable1 formatters, IFormatterLogger formatterLogger, CancellationToken cancellationToken)

Code used to generate error message:

    [HttpPost]
    public string UploadFile(HttpPostedFileBase file)
    {

        if (file.ContentLength > 0)
        {
            var fileName = Path.GetFileName(file.FileName);
            var path = Path.Combine(HttpContext.Current.Server.MapPath(\"~/uploads\"), fileName);
            file.SaveAs(path);


        }
        return \"/uploads/\" + file.FileName;
    }

Class:

public class File
{
    public int FileId { get; set; }
    public string FileType { get; set; }
    public string FileDate { get; set; }
    public byte[] FilePdf { get; set; }
    public string FileLocation { get; set; }
    public string FilePlant { get; set; }
    public string FileTerm { get; set; }
    public DateTime? FileUploadDate { get; set; }
    public string FileUploadedBy { get; set; }

    public string CompanyName { get; set; }
    public virtual ApplicationUser User { get; set; }
}

回答1:


I normally use the HttpPostedFileBase parameter only in Mvc Controllers. When dealing with ApiControllers try checking the HttpContext.Current.Request.Files property for incoming files instead:

[HttpPost]
public string UploadFile()
{
    var file = HttpContext.Current.Request.Files.Count > 0 ?
        HttpContext.Current.Request.Files[0] : null;

    if (file != null && file.ContentLength > 0)
    {
        var fileName = Path.GetFileName(file.FileName);

        var path = Path.Combine(
            HttpContext.Current.Server.MapPath("~/uploads"),
            fileName
        );

        file.SaveAs(path);
    }

    return file != null ? "/uploads/" + file.FileName : null;
}



回答2:


This is what solved my problem
Add the following line to WebApiConfig.cs

config.Formatters.XmlFormatter.SupportedMediaTypes.Add(new System.Net.Http.Headers.MediaTypeHeaderValue("multipart/form-data"));



回答3:


You can use something like this

[HttpPost]
public async Task<HttpResponseMessage> AddFile()
{
    if (!Request.Content.IsMimeMultipartContent())
    {
        this.Request.CreateResponse(HttpStatusCode.UnsupportedMediaType);
    }

    string root = HttpContext.Current.Server.MapPath("~/temp/uploads");
    var provider = new MultipartFormDataStreamProvider(root);
    var result = await Request.Content.ReadAsMultipartAsync(provider);

    foreach (var key in provider.FormData.AllKeys)
    {
        foreach (var val in provider.FormData.GetValues(key))
        {
            if (key == "companyName")
            {
                var companyName = val;
            }
        }
    }

    // On upload, files are given a generic name like "BodyPart_26d6abe1-3ae1-416a-9429-b35f15e6e5d5"
    // so this is how you can get the original file name
    var originalFileName = GetDeserializedFileName(result.FileData.First());

    var uploadedFileInfo = new FileInfo(result.FileData.First().LocalFileName);
    string path = result.FileData.First().LocalFileName;

    //Do whatever you want to do with your file here

    return this.Request.CreateResponse(HttpStatusCode.OK, originalFileName );
}

private string GetDeserializedFileName(MultipartFileData fileData)
{
    var fileName = GetFileName(fileData);
    return JsonConvert.DeserializeObject(fileName).ToString();
}

public string GetFileName(MultipartFileData fileData)
{
    return fileData.Headers.ContentDisposition.FileName;
}



回答4:


check ur WebApiConfig and add this

GlobalConfiguration.Configuration.Formatters.XmlFormatter.SupportedMediaTypes.Clear();



回答5:


Perhaps it is late for the party. But there is an alternative solution for this is to use ApiMultipartFormFormatter plugin.

This plugin helps you to receive the multipart/formdata content as ASP.NET Core does.

In the github page, demo is already provided.




回答6:


You're getting HTTP 415 "The request entity's media type 'multipart/form-data' is not supported for this resource." because you haven't mention the correct content type in your request.



来源:https://stackoverflow.com/questions/28369529/how-to-set-up-a-web-api-controller-for-multipart-form-data

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!