ASP.NET MVC 4 WebApi 與 Extjs 的結合 -- 送出表單 ( Submit Form )
ASP.NET MVC 4 WebApi 與 Extjs 的結合 -- 動態複製表單並送出
ASP.NET MVC 4 WebApi 與 Extjs 的結合 -- 上傳檔案 ( FileUpload )
為了避免網路或其他因素造成只成功上傳某些資料,所以需要將Form跟File上傳到同一個WebApi做資料儲存
同時上傳資料與檔案,Controller無法自動區分Form跟File丟到指定的Model裡面,所以我們需要對傳上來的資料做處理。
每次傳上來的資料類別不同,做成共用的Method讓大部分的狀況都可以直接使用,而且自動轉成我們所指定的型別。
先把Request.Form傳進去,用Keys跑迴圈把Value放到Dictionary去,因為我們需要自動轉換型別,先把Dictionary轉成Json格式,然後讓JsonConvert.DeserializeObject<T>去幫我們做型別轉換的處理。
備註:Key跟欄位名稱要一樣,多的Key不會被放到Model,沒有資料的欄位會是null。
public T getSingleFormData<T>(NameValueCollection Form)
{
List<T> Data = new List<T>();
Dictionary<string, object> tmpData = new Dictionary<string, object>();
foreach (var item in Form.AllKeys)
{
tmpData.Add(item, Form[item]);
}
if (tmpData.Count > 0)
{
T formData = JsonConvert.DeserializeObject<T>(JsonConvert.SerializeObject(tmpData));
Data.Add(formData);
}
return Data.FirstOrDefault();
}
看完單筆資料接收,當然有可能資料是多筆,這邊需要做傳過來的Key做切割,然後判斷這是第幾筆資料,所以要對AllKeys做排序,避免傳過來的順序亂掉導致轉換後是錯誤的資料。
public List<T> getMultiFormData<T>(NameValueCollection Form)
{
List<T> Datas = new List<T>();
Dictionary<string, object> tmpData = new Dictionary<string, object>();
string Seq = string.Empty;
foreach (var item in Form.AllKeys.OrderBy(x => x))
{
string[] formName = item.Split('.');
string formSeq = formName[0].Substring(1, formName[0].Length - 2);
if (string.IsNullOrEmpty(Seq) == false && Seq != formSeq)
{
if (tmpData.Count > 0)
{
T formData = JsonConvert.DeserializeObject<T>(JsonConvert.SerializeObject(tmpData));
Datas.Add(formData);
}
tmpData.Clear();
}
Seq = formSeq;
tmpData.Add(formName[1], Form[item]);
}
if (tmpData.Count > 0)
{
T formData = JsonConvert.DeserializeObject<T>(JsonConvert.SerializeObject(tmpData));
Datas.Add(formData);
}
return Datas;
}
接下來做檔案的接收,因為直接把檔案存到資料庫,所以用Stream去存放。
public IDictionary<string, object> getFileData(HttpFileCollection Files)
{
Dictionary<string, object> FilesStream = new Dictionary<string, object>();
foreach (var item in Files.AllKeys)
{
HttpPostedFile File = Files[item];
if (string.IsNullOrEmpty(File.FileName) == false)
{
Dictionary<string, object> tmpFile = new Dictionary<string, object>();
tmpFile.Add("FileName", File.FileName);
tmpFile.Add("Stream", File.InputStream);
FilesStream.Add(item, tmpFile);
}
}
return FilesStream;
}
Method都寫完,開始動手寫資料處理的部分。
public HttpResponseMessage Post()
{
var httpRequest = HttpContext.Current.Request;
//多筆
List<Products> AllProducts = getMultiFormData<Products>(httpRequest.Form);
/*
Code
*/
//單筆
Products Products = getSingleFormData<Products>(httpRequest.Form);
/*
Code
*/
//檔案
IDictionary<string, object> Files = getFileData(httpRequest.Files);
foreach (var item in Files)
{
Dictionary<string, object> tmpFile = (Dictionary<string, object>)item.Value;
/*
Code
*/
}
return Request.CreateResponse(HttpStatusCode.OK);
}
David Kuo:
為什麼要傳參數,而不在Method直接取Request?
答:
如果從Method直接取Request,這樣不夠彈性,變成其他NameValueCollection、HttpFileCollection的資料要取就會沒辦法使用,然後也有可能在建立共用物件時發生Request未初始化的問題。
參考:
ASP.NET MVC 4 Web Api 回傳HttpResponseMessage遇到 System.ArgumentNullException: Value cannot be null. Parameter name: request
沒有留言 :
張貼留言