【问题标题】:How to simulate HTTP POST programmatically in ASP.NET?如何在 ASP.NET 中以编程方式模拟 HTTP POST?
【发布时间】:2011-02-23 11:10:50
【问题描述】:

我需要以编程方式模拟 HTTP POST,即,我需要使用一些 POST 变量生成请求,然后将其发送到页面。

为了澄清,我需要模拟常规 POST 的行为,而不是以编程方式完成整个事情。所以基本上我需要以与表单 POST 发生时相同的方式填写请求,然后将浏览器发送到需要 POST 的页面。

【问题讨论】:

    标签: asp.net forms post redirect


    【解决方案1】:

    这是一种方法。

    您以 NameValueCollection 的形式向该方法发送 url 和名称/值参数。该方法在端点上创建一个 Http Post 并将响应作为字符串返回。

    当然,根据您执行此操作的内容/原因以及此方法将被调用多少次,可能还有其他选择。但在您提供有关您的具体需求的更多信息之前,这种方法已经足够了。

    下面的方法使用 Tasks (.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(它更简单一些)。此方法期望 post 参数为表单中的字符串

    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();
    }
    

    【讨论】:

    • 正如我在另一条评论中提到的,在我使用所需的 POST 变量“构造”请求后,我需要能够执行常规的 Response.Redirect()。
    • @Farina,那么请修改您的问题并说明清楚。你不能指望每个人都阅读你所有的 cmets 只是为了了解你需要什么。
    • @Farina,我阅读了其他评论,但我不确定我是否理解您的要求,所以请花时间尽可能清楚地解释您正在尝试做什么(在您的问题中) )。当您向对方发出 http 请求(GET 或 POST)时,可能会向您发送重定向。在这种情况下,您需要遵循该重定向。您不能自己进行重定向。
    • @Farina,如果您正在调用(POSTing 到)的页面重定向到另一个页面,那么我提供的代码将自动调用具有相同参数的另一个页面。但坦率地说,我不明白你要做什么,所以请尽可能解释清楚。
    • 这个想法不是以编程方式执行 POST,而是通过构建请求然后重定向到接受 POST 的页面来模拟帖子。
    【解决方案2】:

    这样的?

        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;
            }
        }
    

    【讨论】:

      【解决方案3】:

      我过去在这里问过这个问题:

      POST a HTML Form programmatically?

      我被引导到以下对我来说非常有用的链接!:

      WebClient.UploadValues

      【讨论】:

      • 我看到了,但是 WebClient 是做 POST 的,我打算在设置 POST 变量后做一个正常的 Response.Redirect()。
      【解决方案4】:

      我认为做你想做的事并不容易,但可能有一个可以接受的解决方法。 以下是一些解决方法的想法:

      • 将 javascript 与您要发布的表单一起返回到浏览器,然后让 javascript 为您发布。不过,这并不安全。
      • 如果目标页面在您的控制之下,则通过 HttpContext.Current.Items 传递数据,调用 Transfer,并让目标页面识别该特殊情况并进行处理。使用 HttpContext.Current.Items 的一个优点是它会在请求结束时自动清除,这与 Session 状态不同。
      • HttpServerUtility.Execute 如果您想将来自另一个页面的结果嵌入到当前页面中,可能会很有用。它不允许您设置表单发布数据或 URL 请求参数。
      • 按照其他答案中的说明运行 HttpWebRequest,并使用 Response.Write 将其作为网页响应返回。您可能还需要提供用户身份验证凭据和 cookie。请参阅 HttpWebRequest.Credentials 和 HttpWebRequest.CookieContainer。
      • 如果您可以修改目标页面,使其在重新请求时显示相同的信息,您可以执行 HttpWebRequest,然后为浏览器添加重定向。
      • 重构代码,以便任一页面都可以生成相同的输出(例如:使用共享的 UserControl 或自定义 WebControl)。
      • 如果目标页面在另一个站点上,页面抓取会很有用。提出请求,抓取结果,并将结果显示在您自己的页面上。

      【讨论】:

        【解决方案5】:

        你需要HttpWebRequest类。

        【讨论】:

          猜你喜欢
          • 2015-01-14
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-11-25
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多