Вопрос

I have problems of getting all the form data I've specified in my API Controller.

javascript upload function:

$scope.upload[index] = $upload.upload({
        url: '/api/upload/',
        method: 'POST',
        data: {
            Photographer: $scope.models[index].photographer,
            Description: $scope.models[index].desc
        },
        file: $scope.models[index].file
    })

Form data: Works as I want it to, for each request that is sent it includes my values as i want it to.

------WebKitFormBoundaryzlLjAnm449nw1EvC
Content-Disposition: form-data; name="Photographer"

Scott Johnson
------WebKitFormBoundaryzlLjAnm449nw1EvC
Content-Disposition: form-data; name="Description"

Image taken with a Nikon camerea
------WebKitFormBoundaryzlLjAnm449nw1EvC
Content-Disposition: form-data; name="file"; filename="moxnes.jpg"
Content-Type: image/jpeg

My Web API Controller:

Template from this guide

public class UploadController : ApiController
{
    public async Task < HttpResponseMessage > PostFormData() 
    {
        var root = HttpContext.Current.Server.MapPath("~/App_Data");
        var provider = new MultipartFormDataStreamProvider(root);

        try 
        {
            // Read the form data.
            await Request.Content.ReadAsMultipartAsync(provider);

            // Show all the key-value pairs.
            foreach(var key in provider.FormData.AllKeys) 
            {
                foreach(var val in provider.FormData.GetValues(key)) 
                {
                    var keyValue = string.Format("{0}: {1}", key, val);
                }
            }

            foreach(MultipartFileData fileData in provider.FileData) 
            {
                var fileName = fileData.Headers.ContentDisposition.FileName;
            }
            return Request.CreateResponse(HttpStatusCode.OK);
        } 
        catch (Exception e) 
        {
            return Request.CreateErrorResponse(HttpStatusCode.InternalServerError, e);
        }
    }
}

Here's the problem: The controller can receive multiple request asynchronously and read all the files through this loop: foreach(MultipartFileData fileData in provider.FileData) which works fine, but my other form data values (Phtographer and Description) does only include values from one of the requests (the last request received).

foreach(var key in provider.FormData.AllKeys)

I need to take out each requests form data values. How can I do it, or is there any better way of solving this? Maybe by adding a model as parameter?

Это было полезно?

Решение

I used this along with angular and it worked fine for me:

public partial class UploadController : ApiController
{
    [HttpPost]
    public Task<HttpResponseMessage> PostFormData()
    {
        // Check if the request contains multipart/form-data.
        if (!Request.Content.IsMimeMultipartContent()) {
            throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType);
        }

        string root = HttpContext.Current.Server.MapPath("~/App_Data");
        var provider = new MultipartFormDataStreamProvider(root);

        // Read the form data and return an async task.
        var task = Request.Content.ReadAsMultipartAsync(provider).
            ContinueWith<HttpResponseMessage>(t =>
            {
                if (t.IsFaulted || t.IsCanceled) {
                    Request.CreateErrorResponse(HttpStatusCode.InternalServerError, t.Exception);
                }


                foreach (MultipartFileData file in provider.FileData) {
                    using (StreamReader fileStream = new StreamReader(file.LocalFileName)){
                        if (provider.FormData.AllKeys.AsParallel().Contains("demo")){
                            //read demo key value from form data successfully
                        }
                        else{
                           //failed to read demo key value from form.
                        }
                    }
                }
                return Request.CreateResponse(HttpStatusCode.OK, "OK");
            });

        return task;
    }
...

Другие советы

I've created a MediaTypeFormatter that decodes the multipart/form-data and provides a HttpPostedFileBase via model binding. It makes file uploads as easy as any other API parameters. It currently loads the full file upload into the memory but the formatter can be easily adjusted to also write the uploaded data into a temporary upload directory.

https://gist.github.com/Danielku15/bfc568a19b9e58fd9e80

Simply register the formatter in your API configuration and you're all set to use it in your data transfer models:

Configuration.Formatters.Add(new FormMultipartEncodedMediaTypeFormatter());
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top