問(wèn)題
在武定等地區(qū),都構(gòu)建了全面的區(qū)域性戰(zhàn)略布局,加強(qiáng)發(fā)展的系統(tǒng)性、市場(chǎng)前瞻性、產(chǎn)品創(chuàng)新能力,以專(zhuān)注、極致的服務(wù)理念,為客戶提供網(wǎng)站建設(shè)、做網(wǎng)站 網(wǎng)站設(shè)計(jì)制作定制設(shè)計(jì),公司網(wǎng)站建設(shè),企業(yè)網(wǎng)站建設(shè),成都品牌網(wǎng)站建設(shè),營(yíng)銷(xiāo)型網(wǎng)站,成都外貿(mào)網(wǎng)站建設(shè)公司,武定網(wǎng)站建設(shè)費(fèi)用合理。
我們想創(chuàng)建一個(gè)能夠處理 HTML表單的 ASP.NET Web API應(yīng)用程序(使用 application/x-www-form-urlencoded方式提交數(shù)據(jù))。
解決方案
我們可以創(chuàng)建一個(gè) Controller Action 接收一個(gè) Moddel,Model 的結(jié)構(gòu)和準(zhǔn)備從HTML 表單提交的準(zhǔn)備處理的結(jié)構(gòu)相似,模型綁定依賴(lài)于 ASP.NET Web API 來(lái)處理。模型中的屬性名字和 HTTP 請(qǐng)求中要用的名字要匹配。
public HttpResponseMessage Post(RegistrationModel model) { //忽略 }
另外,我們可以使用System.Net.Http.Formatting.FormDataCollection作為 Action方法的唯一參數(shù)??蚣軐?huì)通過(guò)鍵值對(duì)集合的方式傳值,我們就可以自己處理我們想要的值。
public HttpResponseMessage Post(FormDataCollection form) { //忽略 }
工作原理
當(dāng)使用 ASP.NET Web API構(gòu)建 web應(yīng)用程序時(shí),為了提升現(xiàn)有 Web應(yīng)用程序(MVC,Web Form,或者其他技術(shù))而使用Web API的時(shí)候,提交 form-URL-encoded數(shù)據(jù)是一種很常見(jiàn)的需求。
ASP.NET Web API使用 MediaTypeFormatters從 HttpRequestMessage表單中提取數(shù)據(jù),并且,傳輸這些數(shù)據(jù)給相應(yīng)選擇的action來(lái)處理請(qǐng)求。第四章會(huì)詳細(xì)介紹模型綁定和格式化,在這里,我們僅僅接觸了直接與處理 HTML表單相關(guān)的概念。
兩個(gè)現(xiàn)成的格式化程序能夠處理的格式:
FormUrlEncodedMediaTypeFormatter,用于綁定使用 application/x-www-form-urlencoded內(nèi)容類(lèi)型的 FormDataCollection。
JQueryMvcFormUrlEncodedFormatter,也是使用同樣的內(nèi)容類(lèi)型,也可以綁定到Model(DTO)
從設(shè)計(jì)角度來(lái)看,后面的應(yīng)該是前面的子類(lèi)。
使用FormDataCollection來(lái)代替我們action參數(shù),他不僅讓我們能夠訪問(wèn)原始表單數(shù)據(jù),還通知了 ASP.NET Web API不執(zhí)行任何驗(yàn)證。
默認(rèn)情況,Web API僅僅讀請(qǐng)求體一次,當(dāng)使用模型綁定表單數(shù)據(jù)時(shí),這種模式應(yīng)該封裝了所有的表單域。換句話說(shuō),不能在傳輸數(shù)據(jù)的時(shí)候,即使用請(qǐng)求體傳輸數(shù)據(jù),同時(shí)又使用 URL參數(shù)形式傳輸數(shù)據(jù),在這樣的情況下,還希望框架自動(dòng)處理模型綁定。對(duì)于 MVC開(kāi)發(fā)者這個(gè)情況就很痛苦,因?yàn)樗麄兞?xí)慣了這樣的開(kāi)發(fā)方式。不過(guò),我們還是可以強(qiáng)制 Web API使用像 MVC樣式的參數(shù)綁定。這部分將在本書(shū) 4-4部分討論。
如果你的表單處理的時(shí)二進(jìn)制數(shù)據(jù),例如,上傳文件。這時(shí)候,表單將被替換為 multipart/form-data的形式提交。ASP.NET Web API沒(méi)有提供任何內(nèi)建的MediaTypeFomatter來(lái)處理二進(jìn)制數(shù)據(jù)。不過(guò),他還是很容易處理這種方式提交的表單。他是使用 MultipleFormDataStreamProvider來(lái)直接處理 HttpRequestMessage的內(nèi)容。如清單 1-7所示。盡管處理文件上傳超出了我們介紹的范圍,還是會(huì)在 4-11單獨(dú)討論。
清單1-7. 接收復(fù)雜請(qǐng)求的表單數(shù)據(jù)
public async Task Post() { if (!Request.Content.IsMimeMultipartContent()) { throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.NotAcceptable, "請(qǐng)求格式化失敗")); } var streamProvider = new MultipartFormDataStreamProvider("d:/uploads/"); await Request.Content.ReadAsMultipartAsync(streamProvider); //訪問(wèn) FormDataCollection 的 實(shí)例 streamProvider.FormData }
注意在這一部分討論的功能不是 ASP.NET特有的,Web API 之外一樣可以用。不過(guò),作為 ASP.NET Web 應(yīng)用程序的一部分來(lái)運(yùn)行 Web API 的時(shí)候,我們通常還是要處理傳統(tǒng)的網(wǎng)頁(yè)表單。
代碼演示
清單1-8展示了使用簡(jiǎn)單表單和JavaScript提交到 ASP.NET Web API的簡(jiǎn)單網(wǎng)頁(yè)表單.
清單 1-8. 簡(jiǎn)單的網(wǎng)頁(yè)表單
清單 1-9展示了可以處理清單1-8表單的兩個(gè) ASP.NET Web API action。第一個(gè)是是使用相對(duì)傳統(tǒng)的方式,使用 FormDataCollection和手動(dòng)提取數(shù)據(jù),然后在填充到服務(wù)器的模型里面。第二個(gè)依依賴(lài)與框架的自動(dòng)模型綁定。
清單 1-9. Web API 控制器處理表單數(shù)據(jù)
public async Task Post() { if (!Request.Content.IsMimeMultipartContent()) { throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.NotAcceptable, "請(qǐng)求格式化失敗")); } var streamProvider = new MultipartFormDataStreamProvider("d:/uploads/"); await Request.Content.ReadAsMultipartAsync(streamProvider); //訪問(wèn) FormDataCollection 的 實(shí)例 streamProvider.FormData } public class UserModel{ public string Name { get; set; } public string Email { get; set; } public string Gender { get; set; } } public class FormController : ApiController{ public HttpResponseMessage Post(FormDataCollection form) { var user = new UserModel { Email = form["Email"], Name = form["Name"], Gender = form["Gender"] }; // 處理用戶... // 忽略 } } public class UserController : ApiController{ public HttpResponseMessage Post(UserModel user) { //process user... //rest omitted for brevity } }