简体   繁体   English

如何修改HttpWebRequest对象的请求主体?

[英]How can I modify the request body of an HttpWebRequest object?

I have an HttpWebRequest object that I obtain by overriding a method on some thirdparty library. 我有一个HttpWebRequest对象,该对象是通过重写某些第三方库上的方法而获得的。 The body of which contains some data that I want to strip out and replace. 其中的正文包含一些我想删除并替换的数据。 Is there a way that I can read the content of the HttpWebRequest object, do some replacements, and then write it back? 有没有一种方法可以读取HttpWebRequest对象的内容,进行一些替换,然后将其写回? The method I'm overriding allows you to modify the request object before attempting to get a response using it. 我覆盖的方法允许您在尝试使用请求对象进行响应之前修改请求对象。

I know that I can write bytes to HttpWebRequest , but I'm stuck on how to read it. 我知道我可以将字节写到HttpWebRequest ,但是我对如何读取字节感到困惑。 I want to do something like this, but I cannot. 我想做这样的事情,但是我做不到。

protected override WebRequest GetWebRequest(Uri uri)
{
    request = (HttpWebRequest)base.GetWebRequest(uri);
    using (var reader = new StreamReader(request.GetRequestStream()))
    {
        var result = reader.ReadToEnd();
        // modify result text and write back
    }

    request.Headers.Add("Authorization", "Bearer " + token);
    return request;
}

I'm afraid this approach will not work, reason is, 恐怕这种方法行不通,原因是,

if you look at the line 1490 of HttpWebRequest.cs 如果您查看HttpWebRequest.cs的 1490行

        /// <devdoc>
        /// <para>Gets a <see cref='System.IO.Stream'/> that the application can use to write request data.
        ///    This property returns a stream that the calling application can write on.
        ///    This property is not settable.  Getting this property may cause the
        ///    request to be sent, if it wasn't already. Getting this property after
        ///    a request has been sent that doesn't have an entity body causes an
        ///    exception to be thrown.
        ///</para>
        /// </devdoc>
        public Stream GetRequestStream(out TransportContext context) {

It states that once you get the property request is sent. 它指出一旦获得属性请求即发送。 Which means you won't be able to modify it. 这意味着您将无法对其进行修改。 As an example you can try following code 例如,您可以尝试以下代码

            var postData = "thing1=hello";
            postData += "&thing2=world";
            var data = Encoding.ASCII.GetBytes(postData);

            var request = (HttpWebRequest)WebRequest.Create("https://www.google.com.au/");
            request.Method = "POST";
            request.ContentType = "application/x-www-form-urlencoded";
            request.ContentLength = data.Length;

            using (var stream = request.GetRequestStream())
            {
                stream.Write(data, 0, data.Length);
            }

            using (var stream = request.GetRequestStream())
            {
                stream.Write(data, 0, data.Length);
            }

The second stram.Write will fail. 第二个stram.Write将失败。

You could use something like Fiddler.Core to achieve what you need. 您可以使用Fiddler.Core之类的东西来实现所需的功能。

Simple answer: you cannot. 简单的答案:您不能。
Detailed answer: 详细答案:

HttpWebRequest.GetRequestStream ultimately opens a socket connection to remote host. HttpWebRequest.GetRequestStream最终打开与远程主机的套接字连接。 Everything you write to request stream is being sent to host. 您写入请求流的所有内容都将发送到主机。

In other words, request body isn't stored locally. 换句话说,请求正文不是存储在本地。
If some third party library has created request and has filled its body, then body was already sent to host. 如果某个第三方库创建了请求并填充了它的主体,则该主体已发送给主机。

All you can do is to contact library owner to update library API. 您所能做的就是与库所有者联系以更新库API。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM