2011-02-23 97 views
10

我需要以編程方式模擬HTTP POST,即我需要生成帶有一些POST變量的請求,然後將其發送到頁面。如何在ASP.NET中以編程方式模擬HTTP POST?

爲了澄清,我需要模擬常規POST的行爲,而不是以編程方式完成整個事情。所以基本上我需要填寫一個請求,就像POST表單發生時那樣填充Request,然後將瀏覽器發送到期望POST的頁面。

回答

19

這是一種方法。

您以NameValueCollection的形式發送此方法的URL和名稱/值參數。該方法在端點上創建一個Http Post並將響應作爲字符串返回。

當然,取決於你爲什麼要做這個以及調用這個方法的次數,還有其他的選擇。但是,除非您提供有關您特定需求的更多信息,否則此方法足夠好。

下面的方法使用任務(.NET 4.0)和異步方法,所以它會更快然後如果你正在做的,例如一個循環多次調用,如下面的代碼同步方法上市。

static string GetWebResponse(string url, NameValueCollection parameters) 
{ 
    var httpWebRequest = (HttpWebRequest)WebRequest.Create(url); 
    httpWebRequest.ContentType = "application/x-www-form-urlencoded"; 
    httpWebRequest.Method = "POST"; 

    var sb = new StringBuilder(); 
    foreach (var key in parameters.AllKeys) 
    sb.Append(key + "=" + parameters[key] + "&"); 
    sb.Length = sb.Length - 1; 

    byte[] requestBytes = Encoding.UTF8.GetBytes(sb.ToString()); 
    httpWebRequest.ContentLength = requestBytes.Length; 

    using (var requestStream = httpWebRequest.GetRequestStream()) 
    { 
    requestStream.Write(requestBytes, 0, requestBytes.Length); 
    requestStream.Close(); 
    } 

    Task<WebResponse> responseTask = Task.Factory.FromAsync<WebResponse>(httpWebRequest.BeginGetResponse, httpWebRequest.EndGetResponse, null); 
    using (var responseStream = responseTask.Result.GetResponseStream()) 
    { 
    var reader = new StreamReader(responseStream); 
    return reader.ReadToEnd(); 
    } 
} 

你也可以使用WebClient(這有點簡單)。所以,如果你用這個方法一定要在你的參數傳遞這樣或修改的實施,像上面的代碼此方法需要在形式

name1=value1&name2=value2&name3=value3 

等職參數爲字符串。

static string HttpPost(string url, string Parameters) 
{ 
    var req = System.Net.WebRequest.Create(url);  

    req.ContentType = "application/x-www-form-urlencoded"; 
    req.Method = "POST"; 
    byte[] bytes = System.Text.Encoding.ASCII.GetBytes(Parameters); 
    req.ContentLength = bytes.Length; 
    System.IO.Stream os = req.GetRequestStream(); 
    os.Write (bytes, 0, bytes.Length); 
    os.Close(); 
    System.Net.WebResponse resp = req.GetResponse(); 
    if (resp== null) 
    return null; 
    var sr = new StreamReader(resp.GetResponseStream()); 
    return sr.ReadToEnd().Trim(); 
} 
+0

正如我在另一條評論中提到的,我需要能夠在用我需要的POST變量「構造」請求之後執行常規的Response.Redirect()。 – Farinha 2011-02-23 14:09:25

+0

@Farina,然後請修改你的問題,並明確說明。你不能指望每個人都閱讀你的所有評論,只是爲了瞭解你需要什麼。 – 2011-02-23 19:39:51

+0

@Farina,我讀了其他評論,我不確定我是否理解你的要求,所以請花時間儘可能清楚地解釋你正在嘗試做什麼(在你的問題中)。當你發出一個http請求(GET或POST)對方時,可能會發送你重定向。在這種情況下,您需要遵循該重定向。你不能自己重定向。 – 2011-02-23 19:42:46

3

像這樣的東西?

public string DoFormPost(string Target, string PostData) 
    { 
     //Make a request    
     HttpWebRequest request = (HttpWebRequest)WebRequest.Create(Target); 
     request.Method = "POST"; 
     request.ContentType = "application/x-www-form-urlencoded"; 
     request.AllowAutoRedirect = false; 

     //Put the post data into the request 
     byte[] data = (new ASCIIEncoding()).GetBytes(PostData); 
     request.ContentLength = data.Length; 
     Stream reqStream = request.GetRequestStream(); 
     reqStream.Write(data, 0, data.Length); 
     reqStream.Close(); 

     //Get response 
     HttpWebResponse response = (HttpWebResponse)request.GetResponse(); 

     //Output response to a string    
     String result = ""; 
     using (Stream responseStream = response.GetResponseStream()) 
     { 
      using (StreamReader reader = new StreamReader(responseStream, Encoding.UTF8)) 
      { 
       result = reader.ReadToEnd(); 
       reader.Close(); 
      } 
      return result; 
     } 
    } 
1

我認爲做你想做的事並不容易,但可能會有一個接受可行的解決方法。 這裏有解決方法的一些想法:

  • 返回JavaScript與您要發佈,並有JavaScript的形式沿瀏覽器做後你。雖然這不安全。
  • 如果目標頁面在您的控制之下,請通過HttpContext.Current.Items傳遞數據,調用Transfer,並讓目標頁面識別出特殊情況並處理它。使用HttpContext.Current.Items的一個好處是它在請求結束時自動清除,與會話狀態不同。
  • 如果要將其他頁面的結果嵌入當前頁面,HttpServerUtility.Execute會很有用。它不允許您設置表單發佈數據或URL請求參數。
  • 按照其他答案中所述運行HttpWebRequest,並使用Response.Write將其作爲網頁的響應返回。您可能還需要提供用戶身份驗證憑據和Cookie。請參閱HttpWebRequest.Credentials和HttpWebRequest.CookieContainer。
  • 如果您可以修改目標頁面,以便在重新請求時顯示相同的信息,則可以執行HttpWebRequest,並按照瀏覽器的重定向進行操作。
  • 重構代碼,以便任一頁面都可以生成相同的輸出(例如:使用共享UserControl或自定義WebControl)。
  • 如果目標頁面位於另一個站點上,則頁面抓取可能很有用。提出請求,刮取結果,並在您自己的頁面上顯示結果。
相關問題