254

I am new to MVC 4 and I am trying to implement File Upload Control in my website. I am not able to find the mistake.I am getting a null value in my file.

Controller:

public class UploadController : BaseController
    {
        public ActionResult UploadDocument()
        {
            return View();
        }

       [HttpPost]
       public ActionResult Upload(HttpPostedFileBase file)
       {
           if (file != null && file.ContentLength > 0)
           {
               var fileName = Path.GetFileName(file.FileName);
               var path = Path.Combine(Server.MapPath("~/Images/"), fileName);
               file.SaveAs(path);
           }

           return RedirectToAction("UploadDocument");
        }
    }

View:

@using (Html.BeginForm("Upload", "Upload", FormMethod.Post, new { enctype = "multipart/form-data" }))
{ 
    <input type="file" name="FileUpload" />
    <input type="submit" name="Submit" id="Submit" value="Upload" />
}
5
  • possible duplicate of File Upload ASP.NET MVC 3.0 Commented Oct 24, 2013 at 13:06
  • 1
    you just have to change public ActionResult Upload(HttpPostedFileBase file) <input type="file" name="FileUpload" /> Commented Mar 4, 2016 at 11:32
  • check out my Implementation here stackoverflow.com/a/40990080/4251431 Commented Dec 6, 2016 at 9:09
  • 2
    Missing out the enctype on the form cost me an hour Commented Feb 22, 2018 at 7:26
  • Where is the connection between the Upload() method and the button. Should there be an onClick event? New to asp.net I am Commented Nov 29, 2018 at 3:09

5 Answers 5

345

The Upload method's HttpPostedFileBase parameter must have the same name as the the file input.

So just change the input to this:

<input type="file" name="file" />

Also, you could find the files in Request.Files:

[HttpPost]
public ActionResult Upload()
{
     if (Request.Files.Count > 0)
     {
         var file = Request.Files[0];

         if (file != null && file.ContentLength > 0)
         {
            var fileName = Path.GetFileName(file.FileName);
            var path = Path.Combine(Server.MapPath("~/Images/"), fileName);
            file.SaveAs(path);
         }
     }

     return RedirectToAction("UploadDocument");
 }
Sign up to request clarification or add additional context in comments.

7 Comments

won't it through Index out of bounds exception in case there is no file in the Request.Files collection..?
Actually it will throw ArgumentOutOfRangeException, but your are right, i updated
Remember that the parameters of the Html.BeginForm are the action name and the controller name (without the 'controller' postfix. For instance: Home instead of HomeController). Another important thing is to not include the <form> tag inside, because is the BeginForm that opens the tag
In other words - Your view model property name must match that of the input type name. If your viewmodel property is named AgentPhoto then you must have the following on your view: <input type="file" name="AgentPhoto"/>
var path = Path.Combine(Server.MapPath("~/Images/"), fileName);, the class "Server" not found, which package use?
|
66

Clarifying it. Model:

public class ContactUsModel
{
    public string FirstName { get; set; }             
    public string LastName { get; set; }              
    public string Email { get; set; }                 
    public string Phone { get; set; }                 
    public HttpPostedFileBase attachment { get; set; }

Post Action

public virtual ActionResult ContactUs(ContactUsModel Model)
{
 if (Model.attachment.HasFile())
 {
   //save the file

   //Send it as an attachment 
    Attachment messageAttachment = new Attachment(Model.attachment.InputStream,       Model.attachment.FileName);
  }
}

Finally the Extension method for checking the hasFile

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace AtlanticCMS.Web.Common
{
     public static class ExtensionMethods 
     {
         public static bool HasFile(this HttpPostedFileBase file)
         {
             return file != null && file.ContentLength > 0;
         }        
     }
 }

8 Comments

public HttpPostedFileBase attachment { get; set; }/ attachment is not an identify
I think Cola is referring to the Attachment type not being defined.
View could be used as described by user2028367. Actually i forgot to include new { enctype = "multipart/form-data" } in Html.BeginForm part, so was unable to view the file in my action. Great answer. +1 for showing in Model class and Extension method.
@BishoyHanna How I put, on my form, the attachment. For the other values razor provide to us a simple syntax, but how I do it for this file?
hi, @ClintEastwood, that post was for uploading one file, I searched online for something that matches multiple uploads (for you) and found that one which I think would work. Again, its model based which is not using "Request.Files" stackoverflow.com/questions/36210413/…
|
17

View Page

@using (Html.BeginForm("ActionmethodName", "ControllerName", FormMethod.Post, new { id = "formid" }))
 { 
   <input type="file" name="file" />
   <input type="submit" value="Upload" class="save" id="btnid" />
 }

script file

$(document).on("click", "#btnid", function (event) {
        event.preventDefault();
        var fileOptions = {
            success: res,
            dataType: "json"
        }
        $("#formid").ajaxSubmit(fileOptions);
    });

In Controller

    [HttpPost]
    public ActionResult UploadFile(HttpPostedFileBase file)
    {

    }

2 Comments

I agree with @Muflix , you don't need AJAX here. Html.BeginForm does the job already. AJAX is only needed if you don't want a redirect to the <form action=LINK>
Ajax is better for larger files since it allows you to enhance the user experience.
6

you just have to change the name of your input filed because same name is required in parameter and input field name just replace this line Your code working fine

 <input type="file" name="file" />

Comments

2

I think, better way is use HttpPostedFileBase in your controller or API. After this you can simple detect size, type etc.

File properties you can find here:

MVC3 How to check if HttpPostedFileBase is an image

For example ImageApi:

[HttpPost]
[Route("api/image")]  
public ActionResult Index(HttpPostedFileBase file)  
{  
    if (file != null && file.ContentLength > 0)  
        try 
        {  
            string path = Path.Combine(Server.MapPath("~/Images"),  
               Path.GetFileName(file.FileName));

            file.SaveAs(path);  
            ViewBag.Message = "Your message for success";  
        }  
        catch (Exception ex)  
        {  
            ViewBag.Message = "ERROR:" + ex.Message.ToString();  
        }  
    else 
    {  
        ViewBag.Message = "Please select file";  
    }  
    return View();  
}

Hope it help.

1 Comment

Better than what? The OP is already using HttpPostedFileBase.