如何在ASP.NET中以编程方式模拟HTTP POST?

时间:2011-02-23 11:10:50

标签: asp.net forms post redirect

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

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

5 个答案:

答案 0 :(得分:19)

这是一种方法。

您以NameValueCollection的形式向此方法发送url和name / value参数。该方法在端点上生成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(它有点简单)。此方法将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();
}

答案 1 :(得分: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;
        }
    }

答案 2 :(得分:1)

我过去曾问过这个问题:

POST a HTML Form programmatically?

我被引导到以下对我有用的链接!:

<强> WebClient.UploadValues

答案 3 :(得分:1)

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

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

答案 4 :(得分:0)

您需要HttpWebRequest课程。