gpt4 book ai didi

带有进度跟踪的 C# HttpWebRequest 表单发布(用于上传可能较大的文件)

转载 作者:太空狗 更新时间:2023-10-30 00:36:21 25 4
gpt4 key购买 nike

我有一个正在编写的 winforms 应用程序,它可以将文件发布到 Web 应用程序(不是我的)。就发布文件本身而言,我的工作一切正常,我的问题是我想提供一些指示,说明我在发送请求方面走了多远。

下面的代码是我为此目的使用 BeginGetResponse 的尝试 - 这是我发现请求仍然阻塞的地方。

关于我可以从哪里开始寻找的任何建议?

    public void Dummy()
{
Dictionary<string, string> fields = new Dictionary<string, string>();
fields.Add("key", "something");

HttpWebRequest hr = WebRequest.Create("http://somesite.com/api/something.xml") as HttpWebRequest;
string bound = "----------------------------" + DateTime.Now.Ticks.ToString("x");
hr.ContentType = "multipart/form-data; boundary=" + bound;
hr.Method = "POST";
hr.KeepAlive = true;
hr.Credentials = CredentialCache.DefaultCredentials;

byte[] boundBytes = Encoding.ASCII.GetBytes("\r\n--" + bound + "\r\n");
string formDataTemplate = "\r\n--" + bound + "\r\nContent-Disposition: form-data; name=\"{0}\";\r\n\r\n{1}";

Stream s = hr.GetRequestStream();

foreach (string key in fields.Keys)
{
byte[] formItemBytes = Encoding.UTF8.GetBytes(
string.Format(formDataTemplate, key, fields[key]));
s.Write(formItemBytes, 0, formItemBytes.Length);
}

s.Write(boundBytes, 0, boundBytes.Length);

string headerTemplate =
"Content-Disposition: form-data; name=\"{0}\"; filename=\"{1}\"\r\n Content-Type: application/octet-stream\r\n\r\n";

List<string> files = new List<string> { Server.MapPath("/Images/Phillip.jpg") };

foreach (string f in files)
{
byte[] headerBytes = Encoding.UTF8.GetBytes(
String.Format(headerTemplate, "image", f));

s.Write(headerBytes, 0, headerBytes.Length);
FileStream fs = new FileStream(f, FileMode.Open, FileAccess.Read);
int bytesRead = 0;
byte[] buffer = new byte[1024];
while ((bytesRead = fs.Read(buffer, 0, buffer.Length)) != 0)
{
s.Write(buffer, 0, buffer.Length);
}

s.Write(boundBytes, 0, boundBytes.Length);
fs.Close();
}

s.Close();

string respString ="";
hr.BeginGetResponse((IAsyncResult res) =>
{
WebResponse resp = ((HttpWebRequest)res.AsyncState).EndGetResponse(res);

StreamReader respReader = new StreamReader(resp.GetResponseStream());
respString = respReader.ReadToEnd();
resp.Close();
resp = null;
}, hr);

while (!hr.HaveResponse)
{
Debug.Write("hiya bob!");
Thread.Sleep(150);
}

Debug.Write(respString);
hr = null;
}

最佳答案

好的,明白了。 HttpWebRequest 对象,如果您设置 ContentLength 属性,将在您调用 GetRequestStream() 时将其 ResponseStream 直接连接到网络套接字。然后,您可以通过直接写入此流来跟踪您的进度。

伪代码:

Request r = CreateWebRequest(Url)
r.ContentLength = CalculateRequestLength(fields, files)
Stream requestStream = r.GetRequestStream()
while(moreData)
{
requestStream.write(someData);
UpdateProgress();
}
r.GetResponse();

工作代码:

   public void Dummy()
{
Dictionary<string, string> fields = new Dictionary<string, string>();
fields.Add("key", "something");

HttpWebRequest hr = WebRequest.Create("http://imgur.com/api/upload.xml") as HttpWebRequest;
string bound = "----------------------------" + DateTime.Now.Ticks.ToString("x");
hr.ContentType = "multipart/form-data; boundary=" + bound;
hr.Method = "POST";
hr.KeepAlive = true;
hr.Credentials = CredentialCache.DefaultCredentials;

byte[] boundBytes = Encoding.ASCII.GetBytes("\r\n--" + bound + "\r\n");
string formDataTemplate = "\r\n--" + bound + "\r\nContent-Disposition: form-data; name=\"{0}\";\r\n\r\n{1}";

//add fields + a boundary
MemoryStream fieldData = new MemoryStream();
foreach (string key in fields.Keys)
{
byte[] formItemBytes = Encoding.UTF8.GetBytes(
string.Format(formDataTemplate, key, fields[key]));
fieldData.Write(formItemBytes, 0, formItemBytes.Length);
}
fieldData.Write(boundBytes, 0, boundBytes.Length);

//calculate the total length we expect to send
List<string> files = new List<string> { Server.MapPath("/Images/Phillip.jpg") };
string headerTemplate =
"Content-Disposition: form-data; name=\"{0}\"; filename=\"{1}\"\r\n Content-Type: application/octet-stream\r\n\r\n";
long fileBytes = 0;
foreach (string f in files)
{
byte[] headerBytes = Encoding.UTF8.GetBytes(
String.Format(headerTemplate, "image", f));
FileStream fs = new FileStream(f, FileMode.Open, FileAccess.Read);

fileBytes += headerBytes.Length;
fileBytes += fs.Length;
fileBytes += boundBytes.Length;
fs.Close();
}

hr.ContentLength = fieldData.Length + fileBytes;

Stream s = hr.GetRequestStream();
//write the fields to the request stream
Debug.WriteLine("sending field data");
fieldData.WriteTo(s);

//write the files to the request stream
Debug.WriteLine("sending file data");
foreach (string f in files)
{
byte[] headerBytes = Encoding.UTF8.GetBytes(
String.Format(headerTemplate, "image", f));
s.Write(headerBytes, 0, headerBytes.Length);

FileStream fs = new FileStream(f, FileMode.Open, FileAccess.Read);
int bytesRead = 0;
long bytesSoFar = 0;
byte[] buffer = new byte[10240];
while ((bytesRead = fs.Read(buffer, 0, buffer.Length)) != 0)
{
bytesSoFar += bytesRead;
s.Write(buffer, 0, bytesRead);
Debug.WriteLine(String.Format("sending file data {0:0.000}%", (bytesSoFar * 100.0f) / fs.Length));
}

s.Write(boundBytes, 0, boundBytes.Length);
fs.Close();
}

s.Close();

GetResponseDel d = new GetResponseDel(GetResponse);
ResponseData data = new ResponseData { del = d };
d.BeginInvoke(hr, EndGetResponse, data);

while (!hr.HaveResponse)
{
Debug.Write("waiting for response" + "\n");
Thread.Sleep(150);
}

Debug.Write(data.responseString);
hr = null;
}

delegate WebResponse GetResponseDel(HttpWebRequest hr);
private WebResponse GetResponse(HttpWebRequest hr)
{
return hr.GetResponse();
}

class ResponseData
{
public GetResponseDel del { get; set; }
public string responseString { get; set; }
}

private void EndGetResponse(IAsyncResult res)
{
ResponseData data = (ResponseData)res.AsyncState;
GetResponseDel d = data.del;

WebResponse r = d.EndInvoke(res);
data.responseString = new StreamReader(r.GetResponseStream()).ReadToEnd();
}

关于带有进度跟踪的 C# HttpWebRequest 表单发布(用于上传可能较大的文件),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2208299/

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