Вопрос по asyncfileupload, internet-explorer-9, asp.net-web-api, jquery, jquery-forms-plugin – Загрузка файла ASP.NET WEBAPI, проблемы с IE9

4

Я создал метод загрузки файлов, используя ASP.NET WEBAPI, ниже кода:

[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 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(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"));
            }

        }
}

и загрузка файлов через Ajax с помощью плагина jquery.form.js, ниже приведен код:

$('#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.');
            }
        });

все работает файл, но это создает проблему в IE9

IE говорит "Хотите открыть или сохранить с локального хоста?

 Ниже приведена трассировка сети: Я нашел какой-то намекВот не надоне знаю, как конвертироватьTask кTask

Я указал время ожидания 30 секунд в ajaxSetup, поэтому через 30 секунд он генерирует ошибку.

Ваш Ответ

3   ответа
3

IE 9 не поддерживает новый XMLHttpRequest Level 2 (только IE10 +), что означает, что плагин jquery.form.js использует откат iframe. Прочитай это:http://www.malsup.com/jquery/form/#file-upload опубликовано создателем плагина jquery.form.js. Там он заявляет, что IE будет запрашивать загрузку, если возвращаемыми данными являются JSON или Script. Jou нужно заставить заголовок типа контента на "текст / html» если вы вернете JSON.

4
var task = Request.Content.ReadAsMultipartAsync(streamProvider).ContinueWith(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;
});
Если этот ответ работает для вас, пожалуйста, пометьте его как отвеченный, это будет полезно для других, кто сталкивается с подобной проблемой. wizzardz
1

Я также сталкивался с такой же проблемой, эта проблема возникает только в IE, когда вы отправляете форму, а функция WebApi, на которую она ссылается, возвращает некоторое значение. У нас нет идеального решения этой проблемы.

В нашем случае мы разделили функцию на два вызова. Первая функция сохранит детали в базе данных (при условии, что выгрузка прошла успешно), а при обратном вызове мы отправим форму для выгрузки файла. Тип возврата функции загрузки через веб-интерфейс:void , если загрузка не удалась, мы обработаем это при обратном вызове ошибки и затем удалим соответствующую запись из базы данных.

Я знаю, что это не очень хорошее решение, но мы должны были пойти на это.

Проверь этовопрос также.

привет приятель, ты прав, это правильный подход, и он работает нормально. Было бы лучше, если бы вы могли опубликовать его как ответ и принять то же самое, а не редактировать вопрос :) wizzardz
Hay Wizzardz, спасибо за совет. Я нашел решение и отредактировал свой вопрос. Я обнаружил, что если мы установим тип возврата WEBAPI недействительным, они начнут создавать проблему с IE9, и WEBAPI возвращает код состояния 204, а не 201, и IE не сможет его понять. Vipul

Похожие вопросы