The way of Asp.Net Mvc to upload files asynchronously

Today, I tried the Ajax provided by mvc, and found that the backend action could not receive the file when uploading the file, neither Request.Files nor HttpPostedFileBase could receive the file..... Later, I found that the Ajax provided by mvc does not support file upload, but I can only use other methods

The first way: through jQuery's ajaxSubmit -- (jQuery script is introduced first), jquery.form.min.js (can be downloaded through NuGet) needs to be introduced to directly upload the code

 

@{
    Layout = null;
}

<!DOCTYPE html>
<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>Index</title>
    <script src="~/Scripts/jquery-1.10.2.min.js"></script>
    @*<script src="~/Scripts/jquery.unobtrusive-ajax.min.js"></script>*@  
    @*Used jquery.form.min.js No reference is allowed, even if it is referenced, it doesn't matter. However, if it is referenced, it should be noted that two commits will occur, which will be executed before submission return false Yes,*@
    <script src="~/Scripts/jquery.form.min.js"></script>
</head>
<body>
    <div>
        <h3>mvc Upload files asynchronously</h3>
        @using (Ajax.BeginForm("UpFileload", "AjaxFileUpload", new AjaxOptions
        {
            Confirm = "Are you sure to upload?",
            HttpMethod = "post",
            OnSuccess = "func",
        }, new { enctype = "multipart/form-data", id = "fileForm" }))
        {
            <input type="file" name="file" value="" />
            @*<button type="submit">Asynchronous upload</button>*@
            <button type="button">Asynchronous upload</button>
        }
    </div>
</body>
</html>
<script>
    //Perform asynchronous commit when button is clicked
    $("button[type=button]").click(() => {
        //Asynchronous submission
        $("#fileForm").ajaxSubmit({     
            url: "@Url.Action("UpFileload", "AjaxFileUpload")",
            type: "post",
            success: data => {
                alert(data);
            },
            error: () => {
                alert("Error");
            }
        });
    });
</script>

Back end action code:

   /// <summary>
        /// Asynchronous file upload
        /// </summary>
        /// <param name="file">Files uploaded by the front end</param>
        /// <returns>File path</returns>
        public ActionResult UpFileload(HttpPostedFileBase file)
        {
            //var myfile = Request.Files["file"]; //You can also get it
            var path = $"/UploadFile/{Guid.NewGuid() + file.FileName}";
            file.SaveAs(Server.MapPath(path));      //Save file
            return Content(path);
        }

 

 

jQuery's ajax submit method and ajax usage are almost the same

 

The second way is $. ajaxfileupload ({}) - > (jQuery script is introduced first) the ajaxfileupload.js script needs to be introduced (this method has been used in the project before, but I remember that the ajaxfileupload script downloaded from the Internet will prompt an error, for example, it is because of the lack of any function in the script, I forgot, and then I followed the search Solution modified script)

Because the previously written project is not a demo, the code will not be pasted one by one if there is a little more code. In fact, the usage is similar to the first one,

 $.ajaxFileUpload({
            url: '@Url.Action("FileUpload", "Profile")',
            secureuri: false,
            fileElementId: 'btn_file',    //file input Label id
            data: null,
            success: function (data, status) {
                $.post("@Url.Action("MyData", "Profile")", null,
                    html => {
                        $("#mybody").children().remove();
                        $(html).appendTo("#mybody");
                    });
            },
            error: function (data, status, e) {
                console.log('Error')   
            }
        });

Finally, paste the source code of the modified ajaxfileupload.js script:

jQuery.extend({

    handleError: function (s, xhr, status, e) {
        // If a local callback was specified, fire it
        if (s.error) {
            s.error.call(s.context || s, xhr, status, e);
        }

        // Fire the global callback
        if (s.global) {
            (s.context ? jQuery(s.context) : jQuery.event).trigger(
                "ajaxError", [xhr, s, e]);
        }
    },

    createUploadIframe: function(id, uri)
    {
        //create frame
        var frameId = 'jUploadFrame' + id;

        if(window.ActiveXObject) {
            var io = document.createElement('<iframe id="' + frameId + '" name="' + frameId + '" />');
            if(typeof uri== 'boolean'){
                io.src = 'javascript:false';
            }
            else if(typeof uri== 'string'){
                io.src = uri;
            }
        }
        else {
            var io = document.createElement('iframe');
            io.id = frameId;
            io.name = frameId;
        }
        io.style.position = 'absolute';
        io.style.top = '-1000px';
        io.style.left = '-1000px';

        document.body.appendChild(io);

        return io
    },
    createUploadForm: function(id, fileElementId)
    {
        //create form
        var formId = 'jUploadForm' + id;
        var fileId = 'jUploadFile' + id;
        var form = $('<form  action="" method="POST" name="' + formId + '" id="' + formId + '" enctype="multipart/form-data"></form>');
        var oldElement = $('#' + fileElementId);
        var newElement = $(oldElement).clone();
        $(oldElement).attr('id', fileId);
        $(oldElement).before(newElement);
        $(oldElement).appendTo(form);
        //set attributes
        $(form).css('position', 'absolute');
        $(form).css('top', '-1200px');
        $(form).css('left', '-1200px');
        $(form).appendTo('body');
        return form;
    },
    addOtherRequestsToForm: function(form,data)
    {
        // add extra parameter
        var originalElement = $('<input type="hidden" name="" value="">');
        for (var key in data) {
            name = key;
            value = data[key];
            var cloneElement = originalElement.clone();
            cloneElement.attr({'name':name,'value':value});
            $(cloneElement).appendTo(form);
        }
        return form;
    },

    ajaxFileUpload: function(s) {
        // TODO introduce global settings, allowing the client to modify them for all requests, not only timeout
        s = jQuery.extend({}, jQuery.ajaxSettings, s);
        var id = new Date().getTime()
        var form = jQuery.createUploadForm(id, s.fileElementId);
        if ( s.data ) form = jQuery.addOtherRequestsToForm(form,s.data);
        var io = jQuery.createUploadIframe(id, s.secureuri);
        var frameId = 'jUploadFrame' + id;
        var formId = 'jUploadForm' + id;
        // Watch for a new set of requests
        if ( s.global && ! jQuery.active++ )
        {
            jQuery.event.trigger( "ajaxStart" );
        }
        var requestDone = false;
        // Create the request object
        var xml = {}
        if ( s.global )
            jQuery.event.trigger("ajaxSend", [xml, s]);
        // Wait for a response to come back
        var uploadCallback = function(isTimeout)
        {
            var io = document.getElementById(frameId);
            try
            {
                if(io.contentWindow)
                {
                    xml.responseText = io.contentWindow.document.body?io.contentWindow.document.body.innerHTML:null;
                    xml.responseXML = io.contentWindow.document.XMLDocument?io.contentWindow.document.XMLDocument:io.contentWindow.document;

                }else if(io.contentDocument)
                {
                    xml.responseText = io.contentDocument.document.body?io.contentDocument.document.body.innerHTML:null;
                    xml.responseXML = io.contentDocument.document.XMLDocument?io.contentDocument.document.XMLDocument:io.contentDocument.document;
                }
            }catch(e)
            {
                jQuery.handleError(s, xml, null, e);
            }
            if ( xml || isTimeout == "timeout")
            {
                requestDone = true;
                var status;
                try {
                    status = isTimeout != "timeout" ? "success" : "error";
                    // Make sure that the request was successful or notmodified
                    if ( status != "error" )
                    {
                        // process the data (runs the xml through httpData regardless of callback)
                        var data = jQuery.uploadHttpData( xml, s.dataType );
                        // If a local callback was specified, fire it and pass it the data
                        if ( s.success )
                            s.success( data, status );

                        // Fire the global callback
                        if( s.global )
                            jQuery.event.trigger( "ajaxSuccess", [xml, s] );
                    } else
                        jQuery.handleError(s, xml, status);
                } catch(e)
                {
                    status = "error";
                    jQuery.handleError(s, xml, status, e);
                }

                // The request was completed
                if( s.global )
                    jQuery.event.trigger( "ajaxComplete", [xml, s] );

                // Handle the global AJAX counter
                if ( s.global && ! --jQuery.active )
                    jQuery.event.trigger( "ajaxStop" );

                // Process result
                if ( s.complete )
                    s.complete(xml, status);

                jQuery(io).unbind()

                setTimeout(function()
                {    try
                    {
                        $(io).remove();
                        $(form).remove();

                    } catch(e)
                    {
                        jQuery.handleError(s, xml, null, e);
                    }

                }, 100)

                xml = null

            }
        }
        // Timeout checker
        if ( s.timeout > 0 )
        {
            setTimeout(function(){
                // Check to see if the request is still happening
                if( !requestDone ) uploadCallback( "timeout" );
            }, s.timeout);
        }
        try
        {
            // var io = $('#' + frameId);
            var form = $('#' + formId);
            $(form).attr('action', s.url);
            $(form).attr('method', 'POST');
            $(form).attr('target', frameId);
            if(form.encoding)
            {
                form.encoding = 'multipart/form-data';
            }
            else
            {
                form.enctype = 'multipart/form-data';
            }
            $(form).submit();

        } catch(e)
        {
            jQuery.handleError(s, xml, null, e);
        }
        if(window.attachEvent){
            document.getElementById(frameId).attachEvent('onload', uploadCallback);
        }
        else{
            document.getElementById(frameId).addEventListener('load', uploadCallback, false);
        }
        return {abort: function () {}};

    },

    uploadHttpData: function( r, type ) {
        var data = !type;
        data = type == "xml" || data ? r.responseXML : r.responseText;
        // If the type is "script", eval it in global context
        if ( type == "script" )
            jQuery.globalEval( data );
        // Get the JavaScript object, if JSON is used.
        if ( type == "json" )
        {
            // If you add mimetype in your response,
            // you have to delete the '<pre></pre>' tag.
            // The pre tag in Chrome has attribute, so have to use regex to remove
            var data = r.responseText;
            var rx = new RegExp("<pre.*?>(.*?)</pre>","i");
            var am = rx.exec(data);
            //this is the desired data extracted
            var data = (am) ? am[1] : "";    //the only submatch or empty
            eval( "data = " + data );
        }
        // evaluate scripts within html
        if ( type == "html" )
            jQuery("<div>").html(data).evalScripts();
        //alert($('param', data).each(function(){alert($(this).attr('value'));}));
        return data;
    }
})

I feel more comfortable ~ ~ ~ I don't know if there is any easier way to use it

Tags: ASP.NET JQuery xml Javascript encoding

Posted on Wed, 08 Jan 2020 09:23:32 -0800 by loftystew