[ASP.NET] 使用 HttpWebRequest POST/GET 方法 (解決錯誤417,Server重新導向)

摘要:[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

 

結果:

 

範例程式碼


TWebRequest.rar

 

參考資料


HttpWebRequest 類別

HttpWebResponse 類別

 

 


以上文章敘述如有錯誤及觀念不正確,請不吝嗇指教
如有侵權內容也請您與我反應~謝謝您 :)