Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Issues with MultipartFormDataStreamProvider

I'm trying to follow this tutorial, and I'm realizing that even if I copy and past his code, I'm getting two compile errors in my ApiController.

IEnumerable<HttpContent> bodyparts = Request.Content.ReadAsMultipartAsync(streamProvider);

This tells me that the return of ReadAsMultipartAsync can't be cast to an IEnumerable of HttpContent.

IDictionary<string, string> bodypartFiles = streamProvider.BodyPartFileNames;

And this is telling me that BodyPartFileNames doesn't exist in streamProvider, which seems contrary to the tutorial as well as several other blog posts and StackOverflow questions I've seen.

Anyone have any idea what the deal is?

Full file:

using AsyncFileUpload.Models;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using System.Web.Http;


namespace AsyncFileUpload.Controllers
{
    public class UploadingController : ApiController
    {
        private const string PATH = "C:\\_projects\\learning";

        [HttpPost]
        public async Task<IList<FileDesc>> Post()
        {
            List<FileDesc> result = new List<FileDesc>();
            if (Request.Content.IsMimeMultipartContent())
            {
                try
                {
                    if (!Directory.Exists(PATH))
                    {
                        Directory.CreateDirectory(PATH);
                    }

                    MultipartFormDataStreamProvider streamProvider =
                        new MultipartFormDataStreamProvider(PATH);

                    IEnumerable<HttpContent> bodyparts = Request.Content.ReadAsMultipartAsync(streamProvider);
                    IDictionary<string, string> bodypartFiles = streamProvider.BodyPartFileNames;
                    IList<string> newFiles = new List<string>();

                    foreach (var item in bodypartFiles)
                    {
                        var newName = string.Empty;
                        var file = new FileInfo(item.Value);

                        if (item.Key.Contains("\""))
                        {
                            newName = Path.Combine(file.Directory.ToString(),
                                item.Key.Substring(1, item.Key.Length - 2));
                        }
                        else
                        {
                            newName = Path.Combine(file.Directory.ToString(), item.Key);
                        }

                        File.Move(file.FullName, newName);
                        newFiles.Add(newName);
                    }

                    var uploadedFiles = newFiles.Select(i =>
                        {
                            var fi = new FileInfo(i);
                            return new FileDesc(fi.Name, fi.FullName, fi.Length);
                        }).ToList();

                    result.AddRange(uploadedFiles);
                }
                catch (Exception e)
                {
                    // NOOP
                }
            }
            return result;
        }
    }
}
like image 939
mshubert12 Avatar asked Aug 21 '12 18:08

mshubert12


1 Answers

ReadAsMultipartAsync returns a Task<> object. Take the .Result property (which blocks) or use the await keyword to wait on the task (preferable).

BodyPartFileNames was changed in the RTM release, now use the FileData property.

See: http://www.asp.net/web-api/overview/working-with-http/sending-html-form-data,-part-2

like image 129
Mike Wasson Avatar answered Sep 18 '22 17:09

Mike Wasson