2014-06-25 16 views
0

我已經閱讀了其他類似的問題,並嘗試瞭解這些問題的解決方案,但由於沒有工作,因此我在此發佈此信息。發送POST請求時的ProtocolViolationException

當我發送下面的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

你確定要ASCII編碼嗎?這將把任何一個127以上的代碼變成問號。這會導致你的程序幾乎失敗,除了美國英語之外的任何語言環境,很可能是這樣。 –

回答

2

有幾件事情:

首先,你不需要直接設置ContentLength - 就這麼走了出去(默認爲-1)。你實際上調用了兩次,所以刪除了兩個呼叫。

另外,你需要調用GetResponse()

Stream newStream = request.GetRequestStream(); 

newStream.Write(bytes, 0, bytes.Length); 
newStream.Close(); 

或者之前,呼籲流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方法,你必須獲得請求流,寫入要發佈的數據,然後關閉流。此方法阻止等待內容發佈;如果沒有超時設置,並且你沒有提供內容,則調用線程會無限期地阻塞。