C# - HttpWebRequest - POST

问题描述 投票:3回答:3

我正试图向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,我的原代码就很好用。

c# .net xml http httprequest
3个回答
3
投票

这应该可以按照你写的方式工作。 我们可以看看实际做上传的代码吗? 你是否记得关闭流?


1
投票

看着这个例子,在 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));
}

0
投票

我喜欢用一个通用的方法来遵守这种东西。看看下面的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;
}
© www.soinside.com 2019 - 2024. All rights reserved.