2010-08-10 32 views
6

Ben, gelen web isteği iletir ve başka bir web sayfasına yönlendirir bir proxy eylem yöntemi uygulayan birkaç başlıkları ekliyorum. Eylem yöntemi GET istekleri için dosya çalışır, ancak hala gelen POST isteğini iletmekle uğraşıyorum. Kopyalama HTTP isteği inputStream

sorun

düzgün giden HTTP isteği akışına istek gövdesini yazma bilen kalmamasıdır. İşte

Ben şimdiye kadar ne var kısaltılmış versiyonu:

ProtocolViolationException: You must write ContentLength bytes to the request stream before calling [Begin]GetResponse. 

I: Ben giden http istek üzerine getResponse dediğimiz gibi kısa sürede

//the incoming request stream 
var requestStream=HttpContext.Current.Request.InputStream; 
//the outgoing web request 
var webRequest = (HttpWebRequest)WebRequest.Create(url); 
... 

//copy incoming request body to outgoing request 
if (requestStream != null && requestStream.Length>0) 
      { 
       long length = requestStream.Length; 
       webRequest.ContentLength = length; 
       requestStream.CopyTo(webRequest.GetRequestStream())      
      } 

//THE NEXT LINE THROWS A ProtocolViolationException 
using (HttpWebResponse response = (HttpWebResponse)webRequest.GetResponse()) 
       { 
        ... 
       } 

, ben şu istisna olsun Bu neden olduğunu anlamıyorum, requestStream.CopyTo doğru miktarda bayt yazma dikkat etmeliydi.

Herhangi bir öneri büyük takdir.

sayesinde

Adrian

+1

ilgili soru - http://stackoverflow.com/questions/226784/how-to-create-a-simple-proxy-in-c –

+0

@James Manning: Bağlantınız için teşekkürler, ama geçmişten geçmişim. Proxy'm her türlü GET isteği için iyi çalışıyor. Bu bana hala problemler veren POST talep gövdesi. –

+0

WebRequest.GetResponse() öğesini çağırmadan önce webRequest.GetRequestStream() tarafından döndürülen akışta Stream.Flush() öğesini çağırmayı denediniz mi? –

cevap

13

ile ifadesi

long length = requestStream.Length; 
webRequest.ContentLength = length; 
requestStream.CopyTo(webRequest.GetRequestStream()) 

eğer içeride Evet, .Net bu konuda çok titiz olduğunu bloğu değiştirerek deneyin. sorunu çözmek için bir yol, her iki gömme ve akımı kapatmaktır. Başka bir deyişle:

Stream webStream = null; 

try 
{ 
    //copy incoming request body to outgoing request 
    if (requestStream != null && requestStream.Length>0) 
    { 
     long length = requestStream.Length; 
     webRequest.ContentLength = length; 
     webStream = webRequest.GetRequestStream(); 
     requestStream.CopyTo(webStream); 
    } 
} 
finally 
{ 
    if (null != webStream) 
    { 
     webStream.Flush(); 
     webStream.Close(); // might need additional exception handling here 
    } 
} 

// No more ProtocolViolationException! 
using (HttpWebResponse response = (HttpWebResponse)webRequest.GetResponse()) 
{ 
    ... 
} 
+0

Harika Mesaj Brian. ÇALIŞIYOR bir cazibe gibi. Ancak, öyle görünüyor ki .CopyTo() yalnızca .NET 4.0+ – Sage

+0

'da destekleniyor. Bu benim problemimi çözdü.Bir soru: WebStream'i bir kullanım bloğuna yerleştirmek yerine, son olarak blokta Flush ve Close kullanmanın bir nedeni var mı? WebRequest ile ilgili yan etkiler var mı? – David

+0

Eminim, kızarma hiçbir şey değiştirmez ... GetRequestStream, ConnectStream'in bir örneğini döndürür ve bu sınıf boş bir yöntemle Flush'i geçersiz kılar, böylece Flush'i çağırmanın hiç bir etkisi yoktur. –

1

webRequest.Method = "POST"; 
webRequest.ContentLength = requestStream.Length; 
webRequest.ContentType = "application/x-www-form-urlencoded"; 
Stream stream = webRequest.GetRequestStream(); 
requestStream.CopyTo(stream); 
stream.Close(); 
+0

Ben zaten var (ben de ... parçası) akışları bertaraf edersem çok fazla hata giderim. Dediğim gibi, bu sadece kısaltılmış versiyonu. Diğer şeyler iyi çalışıyor, bu yüzden bu sorunla ilgili olduğunu düşünmüyorum. –

2

cevap @brian işleri, ancak, requestStream.CopyTo (akış) denilen bir kez, o benim HttpWebResponse ateşlemesi ortaya kondu. Bu, talebi göndermek için hazır olmadığım için bir sorun oldu. Dolayısıyla, istek başlıklarının tümü veya gönderilmekte olan diğer verilerle ilgili bir sorun yaşanıyorsa, bunun nedeni, CopyTo'nun isteğinizi yerine getirmesidir.