畢設和OAuth協議相關,而要理解OAuth協議就必須理解HTTP GET/POST方法。因此研究了一下如何使用Web API或MVC構造POST報文並實現客戶端與服務器端的交互。
我使用的工具是Visual Studio 2013 + Web API 2 + MVC 5。
在兩個不同的VS2013實例中分別新建兩個Web項目,都選擇空模板,其中一個命名為Client,采用MVC架構,另一個命名為Server,采用Web API架構。
這里需要兩個不同的VS2013實例是為了能使兩個IIS Express服務在同一台機器上同時運行。
我們先來看看客戶端:
由於只是個Demo,因此我們只在客戶端中新建一個空的MVC控制器,將其命名為HomeController。它會自帶一個Index()方法。我們在這里面寫好構造請求並發送請求的代碼:
namespace Client.Controllers { public class HomeController : Controller { // // GET: /Home/ public ActionResult Index() { string url = ""; // 這里我們還不知道服務器的url,因此留空 #region 構造POST請求 HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest; request.Method = "POST"; request.ContentType = "application/x-www-form-urlencoded"; request.Host = "localhost:14340"; string body = "client_id=123&redirect_uri="+url+"&response_type=code"; byte[] bodyBytes = Encoding.UTF8.GetBytes(body); Stream requestStream = request.GetRequestStream(); requestStream.Write(bodyBytes,0,bodyBytes.Length); #endregion #region 發送請求並取得響應 // 必須使用HttpWebRequest.GetResponse()方法,請求才能被發送並取得響應 HttpWebResponse response = request.GetResponse() as HttpWebResponse; StreamReader sr = new StreamReader(response.GetResponseStream()); ViewBag.Response = sr.ReadToEnd(); #endregion return View(); } } }
接下來我們構造服務器端:
在Server項目中,新建一個Web API 2控制器。命名隨意(我這里命名為ApiTestController),在控制器中寫入一個方法Post,返回HttpResponseMessage類型。
本來我一直以為POST的參數可以在Request屬性中獲取,但是仔細檢查了Request屬性的所有屬性和方法,包括擴展方法,都沒有找到可以直接讀取POST報文請求體的屬性或方法。查閱資料得知,如果要在POST請求中獲取請求體的內容,就必須將參數封裝在一個類中。於是我們建立一個類RequestArgs如下:
namespace Server.Models { /// <summary> /// 對於POST請求,必須對請求體的所有參數建立一個模型類。 /// </summary> public class RequestArgs { public string client_id { get; set; } public string redirect_uri { get; set; } public string response_type { get; set; } } }
這里的參數和上文客戶端Action方法中的請求報文內容必須保持名稱一致(包括大小寫)
之后我們再寫入控制器的POST方法如下:
namespace Server.Controllers { public class ApiTestController : ApiController { public HttpResponseMessage Post(RequestArgs args) { string client_id = args.client_id; string redirect_uri = args.redirect_uri; string response_type = args.response_type; return Request.CreateResponse(HttpStatusCode.OK, "I have received your message. Client_id = "+client_id+", RedirectUri = "+redirect_uri+"response_type = "+response_type); } } }
這里我們直接返回了報文的內容,而在實際的項目中,我們可以自己對傳入的參數進行處理。
之后我們編譯運行服務器端(最好是按F5進入調試模式運行)。可以看到出現的Web頁面似乎是一個錯誤頁面,但是不用管它,我們的服務器已經開始運行了。
記下服務器的地址(一般也就是端口號會變化),將這個服務器的地址填入客戶端的url變量。
編譯運行客戶端,如果出現返回的信息(這里是“I have received your message”和參數信息),說明我們的請求成功了。
補充說明:如果在Request.CreateResponse()方法中傳入實體對象的話,默認是轉換成JSON傳遞,當然可以在WebApiConfig.cs中修改返回結果的方式。
筆者撰寫此文的目的一是為以后畢設的繼續進行而研究,二也是對MVC和Web API學習的一個記錄。
敬請指正!