我正试图向Apache网络服务器发送一个Http POST。
我发现设置ContentLength似乎是请求工作的必要条件。
我宁愿直接从GetRequestStream()中创建一个XmlWriter,并将SendChunked设置为true,但这样做时,请求无限期地挂起。
下面是我的请求是如何创建的。
private HttpWebRequest MakeRequest(string url, string method)
{
HttpWebRequest request = HttpWebRequest.Create(url) as HttpWebRequest;
request.Method = method;
request.Timeout = Timeout; //Property in my class, assume it's 10000
request.ContentType = "text/xml"; //I am only writing xml with XmlWriter
if (method != WebRequestMethods.Http.Get)
{
request.SendChunked = true;
}
return request;
}
我怎样才能让SendChunked工作,从而不必设置ContentLength? 我看不出有什么理由在发送XmlWriter的字符串到服务器之前把它存储在某个地方。
EDIT: 这是我的代码导致的问题。
using (Stream stream = webRequest.GetRequestStream())
{
using (XmlWriter writer = XmlWriter.Create(stream, XmlTags.Settings))
{
Generator.WriteXml<TRequest>(request, writer);
}
}
之前我没有在GetRequestStream()返回的Stream对象上使用,我以为XmlWriter在处理时关闭了流,但事实并非如此。
下面的一个答案,让我对这个。 我将其标记为答案。
至于HttpWebRequest,我的原代码就很好用。
这应该可以按照你写的方式工作。 我们可以看看实际做上传的代码吗? 你是否记得关闭流?
看着这个例子,在 http:/msdn.microsoft.comen-uslibrarysystem.net.httpwebrequest.sendchunked.aspx。 他们仍然设置了一个内容长度。真正的底线是,如果你要发送数据,你需要告诉接收方你将发送多少数据。为什么你在发送请求之前不知道你要发送多少数据呢?
ContentLength:
属性值类型:系统...::.Int64向互联网资源发送的数据字节数。System...::.Int64向Internet资源发送数据的字节数。默认值为-1,表示没有设置该属性,没有请求数据要发送。
编辑为Aaron(我说错了)。
HttpWebRequest httpWebRequest = HttpWebRequest.Create("http://test") as HttpWebRequest;
httpWebRequest.SendChunked = true;
MessageBox.Show("|" + httpWebRequest.TransferEncoding + "|");
从System.Net.HttpWebRequest.SerializeHeaders(),
if (this.HttpWriteMode == HttpWriteMode.Chunked)
{
this._HttpRequestHeaders.AddInternal("Transfer-Encoding", "chunked");
}
else if (this.ContentLength >= 0L)
{
this._HttpRequestHeaders.ChangeInternal("Content-Length", this._ContentLength.ToString(NumberFormatInfo.InvariantInfo));
}
我喜欢用一个通用的方法来遵守这种东西。看看下面的XML sender请求。它将序列化你的XML,然后用适当的ContentType发送。
public bool SendXMLRequest<T>(T entity, string url, string method)
{
HttpWebResponse response = null;
bool received = false;
try
{
var request = (HttpWebRequest)WebRequest.Create(url);
var credCache = new CredentialCache();
var netCred = new NetworkCredential(YOUR_LOGIN_HERE, YOUR_PASSWORD_HERE, YOUR_OPTIONAL_DOMAIN_HERE);
credCache.Add(new Uri(url), "Basic", netCred);
request.Credentials = credCache;
request.Method = method;
request.ContentType = "application/xml";
request.SendChunked = "GET" != method.ToUpper();
using (var writer = new StreamWriter(request.GetRequestStream()))
{
XmlSerializer serializer = new XmlSerializer(typeof(T));
using (StringWriter textWriter = new Utf8StringWriter())
{
serializer.Serialize(textWriter, entity);
var xml = textWriter.ToString();
writer.Write(xml);
}
}
response = (HttpWebResponse)request.GetResponse();
received = response.StatusCode == HttpStatusCode.OK; //YOu can change the status code to check. May be created, etc...
}
catch (Exception ex) { }
finally
{
if(response != null)
response.Close();
}
return received;
}