摘要:[ASP.NET] 使用 HttpWebRequest POST/GET 方法 (解決錯誤417,Server重新導向)
前言
專案執行中有些時後可能互需要在某段程式邏輯中呼叫另一個URL的網址並取得回傳資料,當碰到這種情況的時後,就可以使用 HttpWebRequest類別 ,簡單介紹下在HTTP中最常用的POST與GET方法。
範例
POST:
string targetUrl = "http://localhost:13772/TWebRequest/TargetHandler.ashx";
string parame = "p=Arvin";
byte[] postData = Encoding.UTF8.GetBytes(parame);
HttpWebRequest request = HttpWebRequest.Create(targetUrl) as HttpWebRequest;
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
request.Timeout = 30000;
request.ContentLength = postData.Length;
// 寫入 Post Body Message 資料流
using (Stream st = request.GetRequestStream())
{
st.Write(postData, 0, postData.Length);
}
string result = "";
// 取得回應資料
using (HttpWebResponse response = request.GetResponse() as HttpWebResponse)
{
using (StreamReader sr = new StreamReader(response.GetResponseStream()))
{
result = sr.ReadToEnd();
}
}
Response.Write(result);
以上程式碼可以看到在建立HttpWebRequest應該使用HttpWebRequest.Create(string)方法建立,參數以UTF8格式轉成Byte[]之後才能夠寫入資料流內,當使用 request.GetResponse() 方法時,HttpWebRequest即會將資料傳送到指定的網址做處理,處理完成後會依照Server的動作看是回傳資料或是重新定向他頁,一般回傳'所需的要資料的情形下要用 HttpWebResponse類別 來接收Response的內容,取得Response後在使用 StreamReader類別 來讀取 response.GetResponseStream() 的資料流內容,如此就是一個簡單的使用方式,接下來看看 GET 方法。
GET:
string targetUrl = "http://localhost:13772/TWebRequest/TargetHandler.ashx?p=Channy";
HttpWebRequest request = HttpWebRequest.Create(targetUrl) as HttpWebRequest;
request.Method = "GET";
request.ContentType = "application/x-www-form-urlencoded";
request.Timeout = 30000;
string result = "";
// 取得回應資料
using (HttpWebResponse response = request.GetResponse() as HttpWebResponse)
{
using (StreamReader sr = new StreamReader(response.GetResponseStream()))
{
result = sr.ReadToEnd();
}
}
Response.Write(result);
GET方法較為簡略,因為是使用 QueryString 傳遞參數,所以並無 Body Message,最後再看看一種情況,就是當POST資料到Server端時,原本只是需要取得回傳的資料而以,但是在Server端卻做了重新導向的動作,導致本業被重新呼叫了一次而讓程式中斷錯誤,當碰到這種問題時後可以使用以下解法:
POST Redirect:
string targetUrl = "http://localhost:13772/TWebRequest/RedirectHandler.ashx";
string parame = "url=http://localhost:13772/TWebRequest/Default.aspx";
byte[] postData = Encoding.UTF8.GetBytes(HttpUtility.HtmlEncode(parame));
HttpWebRequest request = HttpWebRequest.Create(targetUrl) as HttpWebRequest;
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
request.Timeout = 30000;
request.ContentLength = postData.Length;
request.AllowAutoRedirect = false; // 禁止重新導向網頁
// 寫入 Post Body Message 資料流
using (Stream st = request.GetRequestStream())
{
st.Write(postData, 0, postData.Length);
}
string result = "";
// 取得回應資料
using (HttpWebResponse response = request.GetResponse() as HttpWebResponse)
{
if (response.StatusCode == HttpStatusCode.Found) // 判斷是否為 302
{
// 取得返回的Header中的Location參數,Location函有重新導向的網址資訊
Uri redirectUrl = new Uri(response.Headers["Location"]);
// 利用HttpUtility類別的ParseQueryString方法剖析QueryString參數
result = HttpUtility.ParseQueryString(redirectUrl.Query, Encoding.UTF8).Get("parame");
}
}
Response.Write(result);
首先為了避免被重新導向,所以要增加 request.AllowAutoRedirect = false 設定,當Server有重新導向動作時,response回來的StatusCode應該為302,302 有包含導向的Location,所以要取得 response 回來的 Header 資料中的 Location ,Location 將包含導向的URL位置及參數,最後利用HttpUtility類別的ParseQueryString方法剖析QueryString中要取得的參數即可。
注意事項:
1.當使用GET方法時,如果URL與上一次一樣時會Cache 資料,導致兩次取得的資料是一樣的。
2.當response返回 417錯誤 時,是因為Server端為HTTP 1.0版本不支援,Server端為HTTP 1.1以上才能辨識 100 Continue,解法為要將 request.Expect100Continue 設定為 false。
結果:
範例程式碼
參考資料
以上文章敘述如有錯誤及觀念不正確,請不吝嗇指教
如有侵權內容也請您與我反應~謝謝您 :)