3

我正在尝试对 Apache Web 服务器进行 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 的字符串发送到服务器之前,我认为没有理由将其存储在某处。

编辑:这是我导致问题的代码:

    using (Stream stream = webRequest.GetRequestStream())
    {
        using (XmlWriter writer = XmlWriter.Create(stream, XmlTags.Settings))
        {
            Generator.WriteXml<TRequest>(request, writer);
        }
    }

在我没有使用从 GetRequestStream() 返回的 Stream 对象之前,我假设 XmlWriter 在释放时关闭了流,但事实并非如此。

下面的答案之一,让我来看看。我会将它们标记为答案。

就 HttpWebRequest 而言,我的原始代码工作得很好。

4

3 回答 3

3

这应该按照您编写的方式工作。我们能看到实际上传的代码吗?你还记得关闭流吗?

于 2009-12-14T18:03:05.980 回答
1

查看http://msdn.microsoft.com/en-us/library/system.net.httpwebrequest.sendchunked.aspx上的示例,他们仍然设置了内容长度。真正的底线是,如果您要发送数据,您需要告诉接收者您将发送多少数据。为什么在发送请求之前不知道要发送多少数据?

内容长度:

属性值 类型: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));
}
于 2009-12-14T18:19:45.263 回答
0

我更喜欢使用通用方法来遵守这种东西。看看下面的 XML 发送者请求。它将序列化您的 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;
}
于 2020-04-30T16:17:29.197 回答