views:

116

answers:

1

I'm getting started with ASP.NET MVC, but would like to explore further. I've walked through the usual "hello, world" examples, and now I'd like to try something a little more complex. Specifically, I want to be able to:

  • upload some XML file,
  • do some simple processing on it, and then
  • allow the user to download a new file with the results of the processing

In this case, the processing I'd like to do is something trivial that proves that I really got the XML file and have examined it. For example, counting the number of <basket> elements is sufficient. After I do the processing, I'd like to stream the results as a new file to the user (say, a text file that just contains the sentence "There were 398 <basket> elements") so that their browser will initiate a download.

What's a good general approach for this?

+1  A: 

To do the upload, you'll need to have a file input and a form that uses an enctype of multipart/form-data. On the server you get an HttpPostedFileBase object from the Request.Files collection element matching your input's tag name. Then you access the stream on the file object and read it.

Once you have the data, you perform your transformation -- here you are reading the count of a particular tag. Then you want to return a FileResult from your action. Since it's really just a string, I'd suggest writing it to a MemoryStream, then rewinding that string and creating a FileResult from it.

<% using (Html.BeginForm("Upload","Controller",FormMethod.Post, new { enctype = "multipart/form-data"))
   { %>
     <label for="uploadFile">File:</label>
     <input type="file" name="uploadFile" id="uploadFile" />
     <input type="submit" value="Upload" />
<% } %>

Code -- since I assume you'll eventually want to do something more complicated, I'll include some (untested/uncompiled) code that does what you described (I think).

public ActionResult Upload()
{
    var file = Request.Files["uploadFile"];
    if (file == null)
    {
        ModelState.AddModelError( "uploadFile", "No file specified" );
        return View();
    }

    var reader = new StreamReader( file.InputStream );

    var doc = XDocument.Load( reader );

    var count = doc.Descendants().Where( n => n.Name == "basket" ).Count();

    var output = new MemoryStream();
    var writer = new StreamWriter( output );

    writer.Write( "{0} baskets", count );
    output.Seek( 0, SeekOrigin.Begin );

    return File( output, "text/plain", "count.txt" );
}
tvanfosson
This is great! I'm going to try this out as soon as I get back from lunch. Thanks for your help.
Kyle Kaitan