4

問題我已經創建使用ASP.NET的WebAPI文件上傳的方法,下面的代碼:通過使用jquery.form.js阿賈克斯插件上傳文件ASP.NET的WebAPI文件上傳,與IE9

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

     } 
} 

和,下面是代碼:

$('#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說「你想打開或從本地主機救?」

enter image description here 下面是網絡跟蹤: enter image description here 我發現了一些線索here不是不知道如何Task<IEnumerable<FileDesc>>轉換爲Task<HttpResponseMessage>

我在ajaxSetup中指定了30秒的超時時間,所以在30秒後它產生錯誤。

回答

4
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; 
}); 
+0

如果此答案適用於您,請將其標記爲已回答,這對其他遇到類似問題的人有幫助。 – wizzardz

1

我也遇到過同樣的問題,這個問題只會發生在IE中,當你提交表單時,它引用的WebApi函數會返回一些值。我們還沒有找到理想的解決方案。

在我們的例子中,我們所做的是將函數分成兩個調用。第一個函數將保存數據庫中的細節(假設上傳成功),並且在回調函數中,我們將提交表單來上傳文件。 webapi上傳功能的返回類型爲void。如果上傳失敗,我們將處理錯誤的回調,然後從數據庫中刪除相應的條目。

我知道這不是一個很好的解決方法,但我們已經去了。

檢查此question以及。

+0

Hay Wizzardz,謝謝你的建議。我找到了解決方案並編輯了我的問題。我發現,如果我們將WEBAPI的返回類型設置爲無效,那麼它們開始創建IE9問題,並且WEBAPI返回狀態代碼204而不是201,而IE無法理解它。 – Vipul

+0

你好,你是對的,這是正確的方法,它工作正常。如果您可以將其作爲答案發布並接受相同的問題,而不是編輯問題,那會更好。) – wizzardz

3

IE 9不支持新的XMLHttpRequest 2級(僅IE10 +),這意味着jquery.form.js插件使用的IFRAME回退。 閱讀:http://www.malsup.com/jquery/form/#file-upload由jquery.form.js插件的創建者發佈。他在那裏指出,如果返回數據是JSON或Script,IE會提示下載。如果你返回JSON,你必須強制內容類型的頭文件爲「text/html」。