0

The Components

  • A form with some values on an asp.net web form
  • A file input (standard HTML5, not asp:File or anything like that)
  • The bluimp jQuery file uploader which I understand is pretty great for this sort of thing but have never used
  • An MVC4 WebAPI controller
  • A knockoutJS viewmodel in the web form's JavaScript (shouldn't matter here but worth mentioning).

The Goal

Basically, I have tiny Excel sheets that I'm uploading to validate, process, turn into business objects, and return as JSON items.

I'd like the following to happen:

  • User types in some data to the form, etc.
  • User adds a file to the form.
  • The file is automatically uploaded (using bluimp control) to the MVC controller along with a form field value that contains text.

Next, on the controller,

  • the text field passed in is sanitized/validated.
  • the file is processed into memory
    • (these are truly tiny and there aren't many of them so I'm thinking we shouldn't need to go to the file system?)
  • The file is then processed using a FileProcessor that uses the stream and is instantiated using the text field.

The Problem

I don't understand these components well enough yet to understand if I'm making a simple mistake aor a complex one.

What I Have so Far

NOTE: Was trying this with a button to explicitly click to send the file, though in the future I'd like to do it automatically.

The form to submit the file:

<form id="fileUploadForm" action="/api/InvoiceDetailsFile/PostForProcessing" method="POST" enctype="multipart/form-data">
    <input type ="hidden" name="clientSiteId" id="clientSiteId" value="3"/>
        <input type="file" id="inpFile" required="required"/>
<input type ="button" id="btnSendFile" title="Send File" value="Send File"/>

</form>

The JavaScript for the Upload (this is likely very wrong):

        $(document).ready(function () {

            'use strict';

            var btnSendFile = $("#btnSendFile");
            var frmFileUpload = $("#fileUploadForm");

            btnSendFile.click(function () {
                console.log('send button clicked');
                frmFileUpload.fileupload("send");
            });
 });

The WebAPI Controller to handle the upload (this is likely very wrong):

    [HttpPost]
    public Task<List<IInvoiceDetailItem>> PostForProcessing(int clientSiteId)
    {
        if (!Request.Content.IsMimeMultipartContent())
        {
            throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType);
        }

        var results = new List<IInvoiceDetailItem>();

        var streamProvider = new MultipartMemoryStreamProvider();
        var task = Request.Content.ReadAsMultipartAsync(streamProvider).ContinueWith(t =>
                {
                    // can I only expect 1 item here?
                    foreach (var item in streamProvider.Contents)
                    {
                        // if it's an Excel Sheet
                        if (item.IsMimeMultipartContent("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"))
                        {
                            try {
                                var workbook = new XLWorkbook(item.ReadAsStreamAsync().Result);

                                // clientSiteId here comes from form value (via constructor?), ContextUser comes from a BaseApi.
                                var processor =
                                    new InvoiceProcessorFactory(clientSiteId, ContextUser) 
                                        .GetInvoiceProcessorInstance();
                                 results = processor.ProcessInvoice(workbook).ToList();
                            }
                            catch (Exception ex)
                            {
                                throw new HttpException(Convert.ToInt32(HttpStatusCode.InternalServerError), "Well, this is a bummer. The invoice processor failed. Please see the inner exception.", ex);
                            }
                        }
                    }

                    return results;
                });
        return task;
    }

I'll continue to update the code samples as I progress but I wanted to get it out there sooner than later since I know I'll be struggling with it.

3
  • just a small correction..you seem to be using a MVC Post attribute on a Web API action... Commented Oct 25, 2013 at 14:50
  • Oops! Fixed, thanks -- will update here too. Commented Oct 25, 2013 at 15:02
  • 1
    I see some issues with your server side code...i believe you do not have an end-to-end flow ready yet for you to easily test..right? if yes, then i would suggest to try testing with System.Net.Http.HttpClient to uploading multipart form data content...The System.Net.Http library has a content called MultipartFormDataContent through which you can simulate a request how a browser would do..this way you can figure out if your server code is good or not... Commented Oct 25, 2013 at 15:20

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.