gpt4 book ai didi

.net - 提交请求后无法执行此操作

转载 作者:可可西里 更新时间:2023-11-01 16:26:47 27 4
gpt4 key购买 nike

以下代码使用了 FSharp.DataHttp 模块,当 Http. RequestString 被调用。当在不同的网站上使用 query 参数而不是 body 时,类似的代码有效。什么会导致问题? 顺便说一句,它在使用修改后的(用于分配代理)以前版本的 Http 模块时有效。

let headers = [ UserAgent ConfigurationManager.AppSettings.["UserAgent"] ]
let setProxy (req: HttpWebRequest) =
req.Proxy <- WebProxy(ConfigurationManager.AppSettings.["Proxy"], true)
req // Error here
let cc = CookieContainer()

let body = HttpRequestBody.FormValues [
"username", user;
"password", password;
"nothing.x", "21"; "nothing.y", "34"]
let html =
Http.RequestString("https://..../CheckLoginServlet",
httpMethod = "POST",
body = body, cookieContainer = cc, headers = headers,
customizeHttpRequest = setProxy )

异常(exception):

An exception of type 'System.InvalidOperationException' occurred in System.dll but was not handled in user code

Additional information: This operation cannot be performed after the request has been submitted.

最佳答案

我认为这是 FSharp.Data 库中的一个错误。翻阅其source code on GitHub ,我们可以将我们感兴趣的代码提取为:

let values = [ "id", "2"; ]
let req = WebRequest.Create("https://..../CheckLoginServlet") :?> HttpWebRequest
req.Method <- HttpMethod.Post
req.UserAgent <- "Magic"
req.AutomaticDecompression <- DecompressionMethods.GZip ||| DecompressionMethods.Deflate
let cookieContainer = new CookieContainer()
req.CookieContainer <- cookieContainer
req.ContentType <- "application/x-www-form-urlencoded"
let bytes = [ for k, v in values -> Uri.EscapeDataString k + "=" + Uri.EscapeDataString v ]
|> String.concat "&"
|> HttpEncodings.PostDefaultEncoding.GetBytes
let f = fun () -> async {
do! writeBody req bytes
let req = customizeHttpRequest req
let! resp = Async.FromBeginEnd(req.BeginGetResponse , req.EndGetResponse)
let stream = resp.GetResponseStream()
return! toHttpResponse
}
f()

问题出在 writeBody 调用 before 调用 customizeHttpRequest,而它的代码是:

let writeBody (req:HttpWebRequest) (postBytes:byte[]) = async { 
req.ContentLength <- int64 postBytes.Length
use! output = Async.FromBeginEnd(req.BeginGetRequestStream, req.EndGetRequestStream)
do! output.AsyncWrite(postBytes, 0, postBytes.Length)
output.Flush()
}

其中 Async.FromBeginEnd(req.BeginGetRequestStream, req.EndGetRequestStream) 更改了 HttpWebRequest.m_RequestSubmitted 标志,然后由(与其他许多一样)属性 setter 检查HttpWebRequest.Proxy。我的建议:

  1. 直接使用HttpWebRequest编写自己的方法,
  2. 编译您自己的 FSharp.Data 版本,更改 的顺序! writeBody req byteslet req = customizeHttpRequest req 调用
  3. 通知库的贡献者对此进行修复

注意:这可以很容易地在 C# 示例程序中重现:

private static async void GetRequestStreamCallback(IAsyncResult ar)
{
HttpWebRequest req = (HttpWebRequest)ar.AsyncState;
Stream postStream = req.EndGetRequestStream(ar); // Here flag req.m_RequestSubmitted is true already
byte[] byteArray = Encoding.UTF8.GetBytes("id=1");
await postStream.WriteAsync(byteArray, 0, byteArray.Length);
postStream.Close();
req.Proxy = new WebProxy("localhost:8888", true);
allDone.WaitOne();
}
private static ManualResetEvent allDone = new ManualResetEvent(false);
static void Main(string[] args)
{
HttpWebRequest req = (HttpWebRequest)WebRequest.Create("http://localhost:64343/api/products");
req.Method = "POST";
req.UserAgent = "Magic";
req.AutomaticDecompression = DecompressionMethods.GZip;
req.CookieContainer = new CookieContainer();
req.ContentType = "application/x-www-form-urlencoded";
var bytes = Encoding.UTF8.GetBytes("id=2");
req.ContentLength = bytes.Length;
req.BeginGetRequestStream(new AsyncCallback(GetRequestStreamCallback), req);
allDone.WaitOne();
}

关于.net - 提交请求后无法执行此操作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24963466/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com