14
votes

I have implemented a file upload for images using ASP.NET Mvc 3 and the Microsoft.Web.Helpers NuGet package. The implementation is quit simple as it allows you to browse for a file and upload it to a specified directory.

Here is what I have for my image upload solution using ASP.NET MVC 3 and the Microsoft.Web.Helpers NuGet plugin.

enter image description here

Now the ViewModel code

 namespace MvcImageUpload.Models {
    public class ImageUploadViewModel {
        [UIHint("UploadedImage")]
        public string ImageUrl { get; set; }
        public string ImageAltText { get; set; }
    }    
}

Now for the controller I've simply dropped this into the Home controller, since this is just a mock project to get it working. I just added an ActionResult which takes an ImageUploadViewModel as a parameter.

      public ActionResult Upload(ImageUploadViewModel model) {
        var image = WebImage.GetImageFromRequest();

        if (image != null) {
            if (image.Width > 500) {
                image.Resize(500, ((500 * image.Height) / image.Width));
            }

            var filename = Path.GetFileName(image.FileName);
            image.Save(Path.Combine("../Uploads/Images", filename));
            filename = Path.Combine("~/Uploads/Images", filename);
           
                model.ImageUrl = Url.Content(filename);
                model.ImageAltText = image.FileName.Substring(0, image.FileName.Length - 4);
           
        }

        return View("Index", model);
    }

My view for the uploading of images is simple, it has an Html.BeginForm, which handles the Post form method and has the encoding type set to be "multipart/form-data".

Then using The Microsoft.Web.Helpers.FileUpload helper, I request an image from the HTTP post and then display it using a custom DisplayFor template, called ImageViewer.

 @model MvcImageUpload.Models.ImageUploadViewModel
    @using Microsoft.Web.Helpers;
    @{
        ViewBag.Title = "Index";
     }

    <h2>Image Uploader</h2>
    @using (Html.BeginForm("Upload", "Home", FormMethod.Post, 
        new { @encType = "multipart/form-data" })) {           
        @FileUpload.GetHtml(initialNumberOfFiles: 1, allowMoreFilesToBeAdded: false, 
            includeFormTag: false, addText: "Add Files", uploadText: "Upload File") <br />        
                                      
        <input type="submit" name="submit" 
               value="Upload Image" text="Upload Images" 
               style="font-size: .9em;" />
        @Html.DisplayFor(x => x, "ImageViewer")<br />
    }

Here is what the custom DisplayTemplate looks like

    @model MvcImageUpload.Models.ImageUploadViewModel
@if (Model != null) { 
    <h4 style="color:Green;">Upload Success!</h4>           
    <p>
        Alt Text has been set to <strong>@Model.ImageAltText</strong>
    </p>
    <img  style="padding: 20px;" 
        src="@(String.IsNullOrEmpty(Model.ImageUrl) ? "" : Model.ImageUrl)" 
            id="uploadedImage"  alt="@Model.ImageAltText"/>
}

This all works and the image gets successfully uploaded to the /Uploads/Images/FileName.extension on the form post.

My question

How can I now have another view to display all the images in that directory, paged and be able to select and delete and image, from the view and the directory?

Also I know the Microsoft.Web.Helpers.FileUpload, supports uploading of multiple files, but I can't find how to implement this with my current solution. Any help would be greatly appriceated.

3

3 Answers

3
votes

After you click the Upload Image button, the system should call method which uses Request to get the file.

    [HttpPost]
    public ActionResult Upload()
    {
        if(Request.Files != null && Request.Files.Count > 0)
        {
                for (int i = 0; i < request.Files.Count; i++)
                {
                    var postFile = request.Files[i];
                    if (postFile != null && postFile.ContentLength > 0)
                    {
                        if (postFile.ContentLength < GetMaxRequestLength())  //10MB
                        {
                             var file = new ContractAttachment
                            {
                                Name = Path.GetFileName(postFile.FileName),
                                ContentType = postFile.ContentType,
                                FileLength = postFile.ContentLength,
                                FileData = GetStreamBuffer(postFile)
                            };
                            files.Add(file);
                        }

                    }
                }
          }

    }

Hope this help.

1
votes

what you are asking about looks rather implementation to me then any query....

to Display: Fetch all images from your Uploads/Images directory through DirectoryInfo... you can search a directory based on some extension and then it will give you a result set which you can iterate.....

Create a view that will display all records as Image links and in controller fetch the resultset to that View.... Bind those records as you want them to display in your VIEW...

System.IO.DirectoryInfo info = new System.IO.DirectoryInfo("your directory path");
               var filesinfo= info.GetFiles("*.jpg", System.IO.SearchOption.AllDirectories);
               var filenum= filesinfo.GetEnumerator();
               while (filenum.MoveNext())
               {
                   //populate some entity like in your case you have ImageUploadViewModel
               }

and you can implement you delete logic using Ajax or through post back depends how you want it....

Asp.net MVC Views following this tutorial and it will let you go through this....

but again what you are asking is more like implementation Code not any issue....

0
votes

The approach I've followed previously, is to persist the file information in a database(or whatever is appropriate). e.g. path, filename, content-type, filesize. This gives you the most flexibility when editing (alt text, title, description, relation to other objects). Downloading/Viewing the files can then be handled based on path convention, by creating a ViewImage controller which just gets an image id as parameter. You can then build a url from the path to the file and you only need to set the content-type. IIS then does the rest.