ASP.NET WEBAPI file upload, issues with IE9

Vipul picture Vipul · Nov 27, 2012 · Viewed 7.6k times · Source

I have created a file upload method using ASP.NET WEBAPI, below the code:

[DataContract]
    public class FileDesc
    {
        [DataMember]
        public string name { get; set; }      

        [DataMember]
        public string url { get; set; }

        [DataMember]
        public long size { get; set; }

        [DataMember]
        public string UniqueFileName { get; set; }

        [DataMember]
        public int id { get; set; }

        [DataMember]
        public DateTime modifiedon { get; set; }

        [DataMember]
        public string description { get; set; }


        public FileDesc(string rootUrl, FileInfo f,int pId, string aFileName)
        {
            id = pId;
            name = aFileName;
            UniqueFileName = f.Name;
            url = rootUrl + "/Files/" + f.Name;
            size = f.Length / 1024;
            modifiedon = f.LastWriteTime;
            description = aFileName;
        }
    }

    public class CustomMultipartFormDataStreamProvider : MultipartFormDataStreamProvider
    {
        //string uniqueFileName = string.Empty;

        public string UniqueFileName
        {
            get;
            set;
        }
        public string ActualFileName
        {
            get;
            set;
        }

        public int TaskID { get; set; }
        private int UserID { get; set; }
        public CustomMultipartFormDataStreamProvider(string path, int ptaskID, int pUserID)
            : base(path)
        {
            TaskID = ptaskID;
            UserID = pUserID;
        }

        public override string GetLocalFileName(System.Net.Http.Headers.HttpContentHeaders headers)
        {
            var name = !string.IsNullOrWhiteSpace(headers.ContentDisposition.FileName) ? headers.ContentDisposition.FileName : "NoName";

            ActualFileName = name.Replace("\"", string.Empty);

            ActualFileName = Path.GetFileName(ActualFileName);

            UniqueFileName = Guid.NewGuid().ToString() + Path.GetExtension(ActualFileName);

            int id = SaveFileInfoIntoDatabase(ActualFileName, TaskID, UniqueFileName, UserID);

            headers.Add("ActualFileName", ActualFileName);
            headers.Add("id", id.ToString());

            return UniqueFileName;

        }   
    }
    [Authorize]
    public class FileUploadController : ApiController
    {

        private string StorageRoot
        {
            get { return Path.Combine(System.Web.HttpContext.Current.Server.MapPath("~/Files/")); } //Path should! always end with '/'
        }


        public Task<IEnumerable<FileDesc>> Post(int id)        
        {

            string folderName = "Files";
            string PATH = HttpContext.Current.Server.MapPath("~/" + folderName);
            string rootUrl = Request.RequestUri.AbsoluteUri.Replace(Request.RequestUri.AbsolutePath, String.Empty);
            HttpContext.Current.Response.BufferOutput = true;
            HttpContext.Current.Response.Buffer = true;
            HttpContext.Current.Response.ContentType = "text/html";

            if (Request.Content.IsMimeMultipartContent())
            {
                var streamProvider = new CustomMultipartFormDataStreamProvider(PATH, id, BEL_PMS.Utilities.FormsAuthenticationUtil.GetCurrentUserID);
                var task = Request.Content.ReadAsMultipartAsync(streamProvider).ContinueWith<IEnumerable<FileDesc>>(t =>
                {

                    if (t.IsFaulted || t.IsCanceled)
                    {
                        throw new HttpResponseException(HttpStatusCode.InternalServerError);
                    }

                    var fileInfo = streamProvider.FileData.Select(i =>
                    {

                        var info = new FileInfo(i.LocalFileName);
                        int FileID = Convert.ToInt32((from h in i.Headers where h.Key =="id" select h.Value.First()).FirstOrDefault());
                        string ActualFileName = (from h in i.Headers where h.Key =="ActualFileName" select h.Value.First()).FirstOrDefault();
                        return new FileDesc(rootUrl, info, FileID, ActualFileName);
                    });
                    return fileInfo;
                });


                //return new HttpResponseMessage { StatusCode = System.Net.HttpStatusCode.OK, Content = task};               
                return task;
            }
            else
            {
                throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.NotAcceptable, "This request is not properly formatted"));
            }

        }
}

and uploading files via Ajax using jquery.form.js plugin, below is the code:

$('#frmmultiupload').ajaxForm({
            success: OnUploadedSuccessfully,            
            error: function (x, y) {
                mesg('Error occured while file upload! Please make sure that total file size is less than 4 MB and try again.',
                    'error', 'File upload failed.');
            }
        });

everything works file but it is creating problem in IE9

IE says "Do you want to open or save from local host?"

enter image description here Below is the network trace: enter image description here I found some hint here not don't know how to convert Task<IEnumerable<FileDesc>> to Task<HttpResponseMessage>.

I have specified timeout of 30 sec in ajaxSetup, so after 30 sec it is generating error.

Answer

Vipul picture Vipul · Nov 29, 2012
var task = Request.Content.ReadAsMultipartAsync(streamProvider).ContinueWith<HttpResponseMessage>(t =>
{
    if (t.IsFaulted || t.IsCanceled)
    {
        throw new HttpResponseException(HttpStatusCode.InternalServerError);
    }

    var fileInfo = streamProvider.FileData.Select(i =>
    {

        var info = new FileInfo(i.LocalFileName);
        int FileID = Convert.ToInt32((from h in i.Headers where h.Key =="id" select h.Value.First()).FirstOrDefault());
        string ActualFileName = (from h in i.Headers where h.Key =="ActualFileName" select h.Value.First()).FirstOrDefault();
        return new FileDesc(rootUrl, info, FileID, ActualFileName);
    });
    var response = Request.CreateResponse(HttpStatusCode.OK, fileInfo);
    response.Content.Headers.ContentType = new MediaTypeHeaderValue("text/html");
    return response;
});