Image upload with ajax and asp.net returns html

2020-07-24 18:45发布

问题:

I'm trying to build simple image upload to server. Page is basic asp.net page with webforms.

HTML Code - Works fine

<div>
 <input type="file" id="myPhoto" />
 <input type="button" id="upload" value="Upload" />
</div>

In backend my code in dog.aspx is

[WebMethod(EnableSession = true)]
    public static string uploadDoc(HttpPostedFileBase file)
    {
        try
        {
        string _file = mkStorage.UploadImg(file);
        return _file;
        }
        catch (Exception e)
        {
            return e.Message;
        }
    }

And the problem I have with jQuery ajax call. It only returns full page to console as a html. It wont even call the WebMethod because my brakepoint wont activate.

Javascript code

$(document).ready(function () {
        $("#upload").click(function () {
            var formdata = new FormData();
            var _image = $('#myPhoto')[0].files[0];
            formdata.append('file', _image);

            $.ajax({
                type: "POST",
                url: "dog.aspx/uploadDoc",
                data: formdata,
                async: false,
                cache: false,
                contentType: false,
                processData: false,
                success: function (result) { console.log(result);},
                error: function (result) { console.log(result); }
            });
        });
    });

I have other ajax calls and they works fine. But those only passing json to WebMethod. So I assume that there is something wrong with my ajax call parameters.

回答1:

Maybe something like this?

HTML:

//*
<input type="file" class="upload"  id="f_UploadImage"><br />
<img id="myUploadedImg" alt="Photo" style="width:180px;" />
//*

Now we create a common function sendFile() in which we add the file content to FormData’s collection and making a jQuery Ajax call

function sendFile(file) {

    var formData = new FormData();
    formData.append('file', $('#f_UploadImage')[0].files[0]);
    $.ajax({
        type: 'post',
        url: 'fileUploader.ashx',
        data: formData,
        success: function (status) {
            if (status != 'error') {
                var my_path = "MediaUploader/" + status;
                $("#myUploadedImg").attr("src", my_path);
            }
        },
        processData: false,
        contentType: false,
        error: function () {
            alert("Whoops something went wrong!");
        }
    });
}

Note: The contentType and processData are set to false which is important.

Now we call this function on File Upload control change event. .i.e. whenever user select any image file to upload our sendFile() function gets call. Code as shown below.

var _URL = window.URL || window.webkitURL;
$("#f_UploadImage").on('change', function () {

    var file, img;
    if ((file = this.files[0])) {
        img = new Image();
        img.onload = function () {
            sendFile(file);
        };
        img.onerror = function () {
            alert("Not a valid file:" + file.type);
        };
        img.src = _URL.createObjectURL(file);
    }
});

You may have notice in above jQuery ajax method we set URL as fileUploader.ashx this is Generic Handler (ashx file). By using this file, we will upload files on the server side. We are done with our client-side code, let’s head to server-side code.

Server-side: Add Generic Handler ( ashx file) to handle server side code i.e. C# code to save image file on the server.

Now first import System.IO namespaces as shown in below code.

C#

Copy the below-written code, this will get the files from client-side, and rename image with a unique name, then save it to the MediaUploader folder.

using System;
using System.Web;
using System.IO;
public class fileUploader : IHttpHandler {

    public void ProcessRequest(HttpContext context)
    {
        context.Response.ContentType = "text/plain";
        try
        {
            string dirFullPath = HttpContext.Current.Server.MapPath("~/MediaUploader/");
            string[] files;
            int numFiles;
            files = System.IO.Directory.GetFiles(dirFullPath);
            numFiles = files.Length;
            numFiles = numFiles + 1;
            string str_image = "";

            foreach (string s in context.Request.Files)
            {
                HttpPostedFile file = context.Request.Files[s];
                string fileName = file.FileName;
                string fileExtension = file.ContentType;

                if (!string.IsNullOrEmpty(fileName))
                {
                    fileExtension = Path.GetExtension(fileName);
                    str_image = "MyPHOTO_" + numFiles.ToString() + fileExtension;
                    string pathToSave_100 = HttpContext.Current.Server.MapPath("~/MediaUploader/") + str_image;
                    file.SaveAs(pathToSave_100);
                }
            }
            //  database record update logic here  ()

            context.Response.Write(str_image);
        }
        catch (Exception ac) 
        { 

        }
    }

    public bool IsReusable {
        get {
            return false;
        }
    }

}

Note: Here MediaUploader is our folder name, where all our uploaded images get saved.

Output: Finally we are done with Uploading image using jQuery ajax

Reference: here



回答2:

Using formData doesn't send a parameter to the server. The file must be pulled from the http context as such:

[WebMethod]
public static string uploadDoc()
    {
        var context = HttpContext.Current; 
        //I generally use foreach (string file in context.request.files) to avoid null errors 
        string file = context.request.files[0];  
        var fileContent = context.Request.Files[file];

This is just a tiny stub to allow you to get the file object on the server. It returns a stream for you to manipulate and load into an image or save as convert to binary and save the file.

HTH, Geoff