0

I am using MVC to upload some files. The following code works fine but I would like to be return some information from the server ( eg a message or an ID ). What I am trying to do is very simple but I fear I amy not have made it clear. Can anyone help please?

VIEW

   @using (Html.BeginForm("AddFileX", "Upload", FormMethod.Post, new { enctype = "multipart/form-data" }))
     {
         <input type="file" name="files" multiple="true" />
         <input id="submit" type="submit" value="Upload" />
     }

CONTROLLER

   [HttpPost]
    public ActionResult AddFileX(IEnumerable<HttpPostedFileBase> files)
    {
        foreach (var file in files)
        {
            if (file.ContentLength > 0)
            {
                var fileName = Path.GetFileName(file.FileName);
                var path = Path.Combine(Server.MapPath("~/App_Data/uploads"), fileName);
                file.SaveAs(path);
            }
        }
        // I would like to return a message or an ID of something
        // (eg "you are about to overwrite your files" or the ID of something not shown here)
        return View("IdxUpload");  // This line probably needs to be changed
    }
tereško
  • 58,060
  • 25
  • 98
  • 150

2 Answers2

1

Check out the bottom of this Scott Hanselman article. He basically demonstrates how to send information about the status of the file upload back to the user. In particular he creates a ViewModel to hold fileUpload results, creates a list of results based on the upload status of each file, and sends the information back to user by passing it into a View to be rendered.

http://www.hanselman.com/blog/ABackToBasicsCaseStudyImplementingHTTPFileUploadWithASPNETMVCIncludingTestsAndMocks.aspx

Edit:

If you're looking to prompt the user for a confirmation when uploading (in case the file already exists), you can:

(a) use a javascript ajax call to check if file exists and prompt the user before posting -or-

(b) allow the user to submit, save the files to a temp location, prompt the user for confirmation in another view, process files if user confirms.

EXAMPLE (a):

[Controller]

public ActionResult AddFileForm() {
   return View();
}

[HttpPost]
public ActionResult AddFileX(IEnumerable<HttpPostedFileBase> files) {
   // do what you need to save your files and/or update your db
   foreach (var file in files) {
      if (file.ContentLength > 0) {
         var fileName = Path.GetFileName(file.FileName);
         var path = Path.Combine(Server.MapPath("~/App_Data/uploads"), fileName);
         file.SaveAs(path);
      }
   }

   // collect the updated file ids and send to View to render (should prob use Strongly typed class(es))
   string[] results = {"123", "456", "789"};

   return View(results);
}

[HttpPost]
public JsonResult FileExists(List<string> filelist) {
   //check if file(s) exist given filename 

   // return ids for files that already exist on your system
   string[] results = {"123", "", "789"};
   return Json(results);
}

[View] for AddFileForm

@using (Html.BeginForm("AddFileX", "File", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
   <input id="f1" type="file" name="files" multiple="true" />
   <input id="f2" type="file" name="files" multiple="true" />
   <input id="overwrite" type="hidden" value="false" />
   <input id="submit" type="submit" value="Upload" />
}

<script>
   $(document).ready(function () {
      $('#submit').click(function (e) {
         if ($('#overwrite').val() == 'true')
            return; //proceed w/ submit

         e.preventDefault();

         // collect filenames of proposed file updates
         var files = [];
         $('input[type=file]').each(function () {
            var filename = $(this).val();
            files.push(filename);
         });

         // send request to check if files exist
         $.ajax({
            type: "POST",
            url: "/File/FileExists",
            data: { filelist: files },
            success: function (data) {
               confirmUpload(data);
            },
            traditional: true
         });
      });
   });

   function confirmUpload(results) {
      var existing = false;
      $(results).each(function () {
         var fid = $(this)[0];
         if (fid.length > 0) {
            existing = true; //file exists on Server, fid returned.

            //do stuff..highlight table row..etc
         }
      });

      if (existing) {
         //do whatever to request confirmation, show a message div, etc
         var answer = confirm("Overwrite files?");
         if (answer) {
            // if confirmed, set flag submit form
            $('#overwrite').val('true');
            $('#submit').click();   //$('form').submit() - unreliable
         }
      }
   }
</script>

Hope this gives you some ideas.

ltiong_sh
  • 3,186
  • 25
  • 28
  • Thanks Itiong-sh, as I supspected I cannot have explained the problem correctly. Sometimes, what seems simple is often hard to explain. If I understand your link correctly, all it does is return the results to a different page. I was hoping to give the user the option of overwriting a file if one existed. It would seem that a requirement as obvious as mine is beyond my ability to explain it which is really frustrating. I assume you still have no idea what I am trying to achieve. – user1384117 May 09 '12 at 20:10
  • sure..makes sense. I'll give another alternative when I'm able later today. – ltiong_sh May 09 '12 at 20:49
  • Thanks Itiong-sh, that would be much appreciated. Sorry about the delay in replying but I had to go to bed :-) – user1384117 May 10 '12 at 05:18
  • is using JQuery to check if the file exists an option for you? If not, then i'll come up w/ something without using javascript. – ltiong_sh May 10 '12 at 06:04
  • Hello Itiong-sh - I really appreciate you taking the time to try to help. Yes, I am very happy to use jQuery. Perhaps a bit more information might be helpful: The view shows a table of files contained in a database. The user needs to upload new files which will also be added to a database. A successful upload will also add a new row to the table on the screen. The database ID will need to be included in the row so this ID will need to passed back to the view from the server. I hope this makes what I am trying to do a bit more clear, but please say if it is still confusing – user1384117 May 10 '12 at 07:13
  • Hello again ltiong_sh, I cannot thank you enough for your help. I have studied your code and learnt many things from it. I have implemented your code and everything works perfectly and I even undeerstand what it is doing. However although I have tried, I cannot work out how the view can read the results returned from AddFileX. i.e string[] results = {"123", "456", "789"}; I wonder if I could impose on your kindness once again and ask you how that might be achieved. – user1384117 May 11 '12 at 10:07
  • Again..you're probably better off creating a view model to hold your file results as Scott Hanselman did..but if u want easy way to pass a string array: http://stackoverflow.com/questions/1405383/asp-net-mvc-how-to-pass-an-array-to-the-view – ltiong_sh May 11 '12 at 15:30
  • Thanks for the reply ltiong_sh. From you reply, I think perhaps I have again failed to explain what I am try to do. There is nowhere in your code that a can see, where it is possible to read what is returned from the AddFileX server function. The result from the test to see if the file exists, can be read in the "success" function in your code, but what do I need to do to read the result from the AddFileX function please? ( I tried to include the success function I was referring to but it then said that I only had 12 characters left - perhaps a small bug in the site). – user1384117 May 11 '12 at 17:54
  • @ ltiong_shI am guessing that you have given up on me – user1384117 May 17 '12 at 09:56
0

if you dont wish to use ajax file upload plugin there is a very simple thing you can do.

assuming the view in which you have file upload element is named view1 so when the view 1 is posted to the action method check to see wether files have been upload or already present(this part i think you have done already)

next add a message in the viewbag like this ViewData.Message = "Files have been loaded"; and return the same view

add a line inside your view anywhere(preferably at the end). @ViewData.Message. this way whatever message you wanna show to the user will be shown the user

Parv Sharma
  • 12,581
  • 4
  • 48
  • 80