Upload Image Asp net MVC

Asked

Viewed 2,059 times

6

My question is this: imagine a scenario where I have a canvas that has a form, and in this form also exists upload images. Let’s assume that I fill out the entire form, and select 3 images in the input type file, when giving the Ubmit, there in the controller i have the attributes of the completed form, and also the list of HttpPostedBaseFile with the 3 images inside, for me to do upload, however the modelstate is with some error, and he will return to the view to show this error.

It turns out that all the other fields are filled again with the values, but the images are lost. User needs to re-select images.

What’s the best way to solve this? I wanted the images to come back too.

  • 1

    I searched and unfortunately there is no way to restore the state of an input type file, and all users chose to save the files sent in the session. http://forums.asp.net/t/1895657.aspx?ASP+NET+MVC+4+Browser+looses+uploading+File+after+Postback

  • That’s why client validations are important, now with html5 can be less traumatic to the said scenario. There is no way to return the images after sending.

2 answers

1

What’s the best way to solve this? I wanted the images to come back too.

Using the Backload. It is a package that manages a session of upload of files in ASP.NET (can be MVC or Web Forms).

An example using jQuery File Upload, taken from Backload’s own Github:

@using System.Web.Optimization

@{
    ViewBag.Title = "Exemplo de Upload";
    Layout = "~/Views/Shared/_Layout.cshtml";
}

@section styles {
    <!-- bootstrap styles -->
    <link href="~/Content/bootstrap.min.css" rel="stylesheet" />

    <!-- Styles for the jQquery File Upload Plugin in Basic Plus UI style -->
    @Styles.Render("~/backload/blueimp/bootstrap/BasicPlus/css")

    <!-- The main application styles -->
    <link href="~/Content/demo.styles.css" rel="stylesheet" />
}

    <!-- Start of the render section -->
    <div class="container">
        <br>
        <blockquote>
            <p>
                File Upload widget with multiple file selection, drag&amp;drop support, progress bar, validation and preview images, audio and video for jQuery. 
                Supports cross-domain, chunked and resumable file uploads and client-side image resizing.
            </p>
        </blockquote>
        <br>
        <!-- The fileinput-button span is used to style the file input field as button -->
        <span class="btn btn-success fileinput-button">
            <i class="glyphicon glyphicon-plus"></i>
            <span>Add files...</span>
            <!-- The file input field used as target for the file upload widget -->
            <input id="fileupload" type="file" name="files[]" multiple>
        </span>
        <br>
        <br>
        <!-- The global progress bar -->
        <div id="progress" class="progress">
            <div class="progress-bar progress-bar-success"></div>
        </div>
        <!-- The container for the uploaded files -->
        <div id="files" class="files"></div>
        <br>
    </div>
    <!-- End of the render section -->


@section scripts {
    <!-- Bootstrap script -->
    <script src="~/Scripts/bootstrap.min.js"></script>

    <!-- Scripts for the jQquery File Upload Plugin in Basic Plus UI style* -->
    @Scripts.Render("~/backload/blueimp/bootstrap/BasicPlus")

    <!-- The demo application script -->
    <script src="/Scripts/demos.blueimp.basicplus.js"></script>

}

The archive demos.blueimp.basicplus.js contains the following (adapted and translated by me):

/*jslint unparam: true */
/*global window, $ */
$(function () {
    'use strict';

    // O Backload é um produto freemium, então algumas funcionalidades são fechadas. 
    // O FileHandlerController é o controlador da sua sessão de upload.
    // No exemplo, definimos uma sessão de upload por um objectContext. 
    // Esse objectContext deve ser definido pela sua aplicação. No exemplo, 
    // foi definido com esse valor 'C5F260DD3787'. 
    var url = '/Backload/FileHandler?objectContext=C5F260DD3787';

    $('#fileupload').fileupload({
        url: url,
        dataType: 'json',
        autoUpload: false,
        disableImageResize: /Android(?!.*Chrome)|Opera/
            .test(window.navigator && navigator.userAgent),
        previewCrop: true,
        maxChunkSize: 10000000                                          // Opcional: tamanho de cada bloco de arquivo, em bytes, para facilitar uploads grandes.
    })
    .bind('fileuploadsubmit', function (e, data) {
        // Opcional: aqui geramos um uuid para identificar qual bloco de arquivo estamos enviando. O Backload reagrupa cada bloco de arquivo sozinho.
        data.formData = { uuid: Math.random().toString(36).substr(2, 8) };
    })

        // Aqui é a inicialização do tema Basic Plus do jQuery File Upload (https://blueimp.github.io/jQuery-File-Upload/basic-plus.html)
    .data('blueimp-fileupload').initTheme("BasicPlus");
});

If ModelState.IsValid for true, you can access the directory of objectContext using classes from namespace System.IO, manipulate your files and then delete the directory.

The location of this directory can be set by setting. My files Web.Backload.config are usually like this:

<?xml version="1.0"?>
<backload xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:name="urn:backload-schema" xsi:noNamespaceSchemaLocation="Config\Web.Backload.xsd">
  <fileSystem filesRoot="~/Uploads/Temp" /> 
</backload>

0

No way to recover files in input file.

But there are some 'contouring solutions'.
One of the solutions is the use of Ajax 'simulation'.
Q: Why Ajax Simulation?
A: Simple, Ajax does not support sending of files, so we simulate creating an invisible iframe (or flash, or Silverlight for example) that receives a copy of the form and the responsibility of running Submit.

There are several javascript plugins that do all this work by you, in addition to providing a standardized API, as is the case of jQuery File upload.

This way it is possible to keep the form data intact, since there was no Reload page.
Here is a small example of how it would be using the jQuery File upload:

$('#fileupload')
    .fileupload('send', {files: filesList})
    .success(function (result, textStatus, jqXHR) {
        console.log('Sucesso!');
        // Redireciona a página
        // ...
    })
    .error(function (jqXHR, textStatus, errorThrown) {
        console.error('Erro!');
        // trata os dados inválidos
        //...
    });

jQuery File Upload Documentation

PS: This is one of the solutions used to maintain backward compatibility with old browsers, since XHR2 already supports sending data binaries.

  • 2

    That statement is not true, okay? "Ajax does not support file uploading". Ajax is the name of the technique of using JS to make asynchronous requests. And it is possible to upload files asynchronously with JS. :)

  • So@Thiagolunardi, you’re right. In fact, I didn’t want to go this way anymore, let’s say, detailed of the thing (talk about protocol, differentiate resource technique, etc). But if you look at the end, I even put a 'PS' stating that "XHR2" supports binary sending. My idea was to focus more on the outcome than on the details. Anyway, it’s very important to have that comment, it can help someone to eliminate that doubt ;)

Browser other questions tagged

You are not signed in. Login or sign up in order to post.