Dean
Dean

Reputation: 1084

How to Retain HttpPostedFileBase on View Return

I have the following model:

public string Content { get; set; }
public HttpPostedFileBase LogoImageFile { get; set; }

View:

 @Html.EditorFor(model => model.Content, new { htmlAttributes = new { @class = "form-control" } })
 <div class="uploaded-img-wrapper hidden">
   <img class="img-thumbnail-md" title="logo image" alt="logo image" />
 </div>
 @Html.TextBoxFor(model => model.LogoImageFile, new { type = "file", @class = "image-upload" })

When user select a photo from the local drive using the 'choose file' button from the file input element, the image will be displayed on the screen by javascript (Image will be saved to the server if form is valid and get submitted):

if (input.files && input.files[0]) {
            var reader = new FileReader();
            reader.onload = function (e) {
                var $wrapper = $(input).prev();
                $wrapper.removeClass('hidden');
                $wrapper.find('img').attr('src', e.target.result).removeAttr('title');
                $(input).addClass('hidden');
            }
            reader.readAsDataURL(input.files[0]);
        }

I have a server side validation for the "Content" textbox. If it fails server side validation and the return View(Model); got called, the image from the file input will disappear. Anyone knows how to keep the file on the page when View is returned?

Upvotes: 4

Views: 2874

Answers (1)

Mohammad Reza Rahimi
Mohammad Reza Rahimi

Reputation: 662

I have two solution for your problem:

Remote Validation:

according to following sentence "I have a server side validation for the Content textbox", in my view you can use remote validation for validate your form instead send your form to server.This link can help you to using Remote Validation(I would recommend this).

Temporary Store

In this solution you must use ajax-enabled file-upload component (such as this) to send file or files to server. Then you must prepare a action in order to receive file and save it in temporary storage such as (cache or file system) and generate a file-reference to restore the saved file and finally return the file-reference to client.The client insert received file-reference to form as a hidden input thus from then each time form sent, send file-reference instead file content.Of course two points should be noted:

1) Prepare a action to cancel a selected file with user request

2) Prepare a api for restore temporary file by file reference

3) Manage the temporary files to make sure that those don't fill your storage(if using asp.net cache as temporary storage the IIS itself handle it). enter image description here

public ActionResult UploadTemporary(HttpPostedFileBase file)
{
    Guid reference = Guid.NewGuid();
    string extension = Path.GetExtension(file.FileName);
    string fullName= reference.ToString()+extension;
    var path = Path.Combine(Server.MapPath("~/Content/TempFiles/"), fullName);

    var data = new byte[file.ContentLength];
    file.InputStream.Read(data, 0, file.ContentLength);

    using (var sw = new FileStream(path, FileMode.Create))
    {
        sw.Write(data, 0, data.Length);
    }

    return Content(reference);
}

summary

The first solution is quick and easy if you encounter with a few of this requirement case in your project, but if you encounter with a lot number of this case I recommend you to use second solution.The second solution is so time-consuming but very useful for applications that lots deal with file.

Upvotes: 2

Related Questions