一般 ASP.NET MVC 4 上傳檔案可以參考:ASP.NET MVC - 檔案上傳的基本操作,而使用 ASP.NET MVC 4 WebApi 結合 Extjs 上傳檔案,可以參考以下做法:
View
使用 Extjs 建立一個 file 欄位 ( 備註:allowBlank : false 為必填 ){
xtype: 'filefield',
name: 'photo',
fieldLabel: 'Photo',
labelWidth: 100,
msgTarget: 'side',
allowBlank: false,
anchor: '100%',
buttonText: 'Select Photo...'
}
畫面如下:
Button
建立一個按鈕對應 Api 來上傳檔案:buttons: [{
text: 'Send',
// button 按下動作
handler: function () {
// 檢查 form isValid 檢查條件是否符合 加if 成為判斷式
this.up('form').getForm().isValid();
// 傳送檔案
this.up('form').getForm().submit({
// 傳送到 url
url: 'http://localhost/api/Upload',
waitMsg: 'Uploading your photo...',
success: function (fp, o) {
Ext.Msg.alert('Success', 'Your photo "' + o.result.file + '" has been uploaded.');
}
});
}
}, {
text: 'Cancel'
}]
Fakepath 解決方案
當開始測試上傳時,發現檔案上傳路徑都不是真實路徑,而會是 C:\fakepath\ 開頭的路徑,實際找尋這個路徑,發現根本不存在。問題來了,現在幾乎每個瀏覽器都會將實際路徑隱藏,這是為了安全性著想,所以將實際路徑以 C:\fakepath\ 取代。
這個問題,其實本是用戶端安全性上考量不提供實際路徑,所以沒有辦法找到檔案上傳,但是,我們不能把這些問題都推給用戶去處理,因為他或許不知道問題在哪,而是我們程式人員必須要解決這問題。
後來發現,在 Controller 可以解決這個問題。
Controller
在 Request.Content 內,可以使用 Request.Content.IsMimeMultipartContent() 判斷是否 MIME 多組件內容,再將 Multipart 內檔案讀到 MemoryStream,最後轉型成 Byte[],再存成實體檔案。[HttpPost]
public HttpResponseMessage Post()
{
if (Request.Content.IsMimeMultipartContent())
{
var streamProvider = new MultipartMemoryStreamProvider();
Request.Content.ReadAsMultipartAsync(streamProvider).ContinueWith(t =>
{
foreach (var item in streamProvider.Contents)
{
if (item.Headers.ContentDisposition.FileName == null)
{
// 參數區
}
else
{
System.IO.Stream stream = item.ReadAsStreamAsync().Result;
byte[] bytes = new byte[stream.Length];
stream.Read(bytes, 0, bytes.Length);
System.IO.File.WriteAllBytes(@"D:\Image\" + item.Headers.ContentDisposition.FileName.Replace(@"""", @""), bytes);
}
}
});
}
return Request.CreateResponse(HttpStatusCode.OK);
}
所以這不管是在是否有實際路徑的情況下都能適用,用戶端不管是否停用或啟用安全性,都會透過 Multipart 傳送檔案到 MemoryStream,在 Controller 讀取這些檔案並且存成實體檔案。



沒有留言 :
張貼留言