This post was migrated from Justin’s personal blog, 'Codethinked.com.' Views, opinions, and colorful expressions should be taken in context, and do not necessarily represent those of Simple Thread (and were written under the influence of dangerous levels of caffeination).

I had not messed around with file uploads in ASP.NET MVC for a while and so when I fired up ASP.NET MVC 1.0 RTM I was pleasantly surprised to find out how easy they had made it! That is all…

Just kidding! I’m going to show you exactly how to do it, and even better, I’m going to show you how to test it! How about that?

Before we start off you need to know that in order for a form to post uploaded files you are going to need to add a particular enctype attribute to the form. In order to do this, we need to create a form tag like this:

<% using (Html.BeginForm("Edit", "Person", FormMethod.Post, new { enctype = "multipart/form-data" })) {%>

Then we just need to add an input of type “file” onto the form along with a submit button. You must be sure to put at “name” attribute on the input. We can also put whatever else we want on the form:

<table>
    <tr>
        <td><input type="file" id="picture" name="picture" /></td>
    </tr>
    <tr>
        <td><input type="submit" value="Upload" /></td>
    </tr>
</table>

Now that we have our form and the html to go into it, we are ready to get this sucker on the server side. In my first attempt to upload a file I tried to put in a model binder in order to upload the file, only to find out that there was already one there! So all we have to do is this:

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Edit(HttpPostedFileBase picture)
{
    if (picture != null)
    {
        picture.SaveAs("C:\wherever\" + picture.FileName);
    }
}

Pretty easy! Now all that is left is to test it. I am going to use Moq 3, and we just need to mock out the file and pass it into the method:

var personPicture = new Mock<HttpPostedFileBase>();
personPicture.Setup(i => i.FileName).Returns("person.jpg");
personPicture.Setup(i => i.InputStream).Returns(new MemoryStream(Encoding.UTF8.GetBytes("")));

var controller = new PersonController();
controller.Edit(personPicture.Object);

personPicture.Verify(p => p.SaveAs("C:\wherever\person.jpg");

Wow. All we had to do was mock out the image, fake a few properties and then call the method on the controller and then verify that the proper method on the picture was called. Simple as that!

Hopefully you already knew about this, but if you didn’t, then I hope that you enjoyed this post!

4 Comments

Khaja Minhajuddin

Wow, they’ve really made uploading a file very easy. I remember reading a blog post by Hanselman which did the same but with a lot of code, of course that was Preview 5 I guess. Good post.

Reply

Leave a Reply

Your email address will not be published. Required fields are marked *