我已经阅读了其他类似的问题,并尝试了这些问题的解决方案,但由于这不起作用,因此我在这里发布。
当我在下面发送POST请求时,它失败并显示以下错误消息:
System.Net.ProtocolViolationException: You must write ContentLength bytes to the request stream before calling [Begin]GetResponse.
at System.Net.HttpWebRequest.GetResponse()
....
....
我对其他URL端点的GET请求工作正常,我在发出POST请求时只遇到此问题。另外,我已经在代码中适当地设置了ContentLength。我仍然无法发送POST请求。想法?
public void TestSubmitJobWithParams1()
{
const string RestActionPath = "URL_GOES_HERE";
// if you have multipe parameters seperate them with teh '&' delimeter.
var postData = HttpUtility.UrlEncode("MaxNumberOfRowsPerSFSTask") + "=" + HttpUtility.UrlEncode("3000");
var request = (HttpWebRequest)WebRequest.Create(RestActionPath);
request.Method = "POST";
request.Credentials = CredentialCache.DefaultCredentials;
request.PreAuthenticate = true;
request.ContentLength = 0;
request.Timeout = 150000;
request.CachePolicy = new RequestCachePolicy(RequestCacheLevel.BypassCache);
request.ContentType = "application/x-www-form-urlencoded";
byte[] bytes = Encoding.ASCII.GetBytes(postData);
request.ContentLength = bytes.Length;
Stream newStream = request.GetRequestStream();
newStream.Write(bytes, 0, bytes.Length);
string output = string.Empty;
try
{
using (var response = request.GetResponse())
{
using (var stream = new StreamReader(response.GetResponseStream(), Encoding.GetEncoding(1252)))
{
output = stream.ReadToEnd();
}
}
}
catch (WebException ex)
{
if (ex.Status == WebExceptionStatus.ProtocolError)
{
using (var stream = new StreamReader(ex.Response.GetResponseStream()))
{
output = stream.ReadToEnd();
}
}
else if (ex.Status == WebExceptionStatus.Timeout)
{
output = "Request timeout is expired.";
}
}
catch (ProtocolViolationException e)
{
Console.WriteLine(e);
}
Console.WriteLine(output);
Console.ReadLine();
}
答案 0 :(得分:3)
一些事情:
首先,您不需要直接设置ContentLength
- 只需将其保留(默认为-1)。你实际上是在调用它两次,所以删除两个电话。
此外,您需要在调用Close()
GetResponse()
Stream newStream = request.GetRequestStream();
newStream.Write(bytes, 0, bytes.Length);
newStream.Close();
或者,你可以在一个using语句中使用它来处理你的关闭和处理):
using (var newStream = request.GetRequestStream())
{
newStream.Write(bytes, 0, bytes.Length);
}
您在技术上也不需要对HttpUtility.UrlEncode()
使用postData
,因为您的字符串中没有任何内容会违反Url的完整性。只是做:
string postData = "MaxNumberOfRowsPerSFSTask=3000");
如果能解决这个问题,请告诉我。
要获得更全面的简要说明,请查看以下内容:http://msdn.microsoft.com/en-us/library/system.net.httpwebrequest.getresponse.aspx
具体来说,关于ProtocolViolationException
的部分以及它所说的内容:
使用POST方法时,您必须获取请求流,写入要发布的数据,然后关闭流。此方法阻止等待内容发布;如果没有超时设置并且您不提供内容,则调用线程将无限期地阻塞。