2012-03-09 12 views
10

Dzwonię do API hostowanego na serwerze Apache w celu publikowania danych. Używam HttpWebRequest do wykonania POST w języku C#.GetRequestStream() zwraca wyjątek podczas wysyłania danych do adresu URL HTTPS

Interfejs API ma zarówno normalny port HTTP, jak i warstwę zabezpieczoną (HTTPS) na serwerze. Kiedy wołam URL HTTP, działa doskonale. Jednak, gdy wywołuję HTTPS, daje mi to wyjątek time-out (przy funkcji GetRequestStream()). Wszelkie spostrzeżenia? Używam VS 2010, .Net framework 3.5 i C#. Oto fragment kodu:

string json_value = jsonSerializer.Serialize(data); 


     HttpWebRequest request = (HttpWebRequest)System.Net.WebRequest.Create("https://server-url-xxxx.com"); 
     request.Method = "POST"; 
     request.ProtocolVersion = System.Net.HttpVersion.Version10; 
     request.ContentType = "application/x-www-form-urlencoded"; 

     byte[] buffer = Encoding.ASCII.GetBytes(json_value); 
     request.ContentLength = buffer.Length; 
     System.IO.Stream reqStream = request.GetRequestStream(); 
     reqStream.Write(buffer, 0, buffer.Length); 
     reqStream.Close(); 

EDIT: Program Konsola sugerowane przez Piotra działa dobrze. Ale kiedy dodaję dane (w formacie JSON), które muszą być wysłane do interfejsu API, wygasza wyjątek przekroczenia czasu operacji. Oto kod, który dodaję do aplikacji bazującej na konsoli i generuje błąd.

byte[] buffer = Encoding.ASCII.GetBytes(json_value); 
request.ContentLength = buffer.Length; 
+0

możesz spróbować bez ProtocolVersion i ContentType – Peter

+0

dostać również Wireshark i rzucić okiem na to, co dzieje się przez przewód. sprawdź, czy serwer docelowy akceptuje połączenia międzydomenowe. – Peter

+0

Dzięki Peter. Dodałem ProtocolVersion i ContentType, ale wygląda na to, że to nie pomogło. Sprawdzę za pomocą wireshark, ale ponieważ aplikacja Python może łatwo GET/POST to API Wierzę, że serwer akceptuje połączenia międzydomenowe. – Wiz

Odpowiedz

10

Nie wiem, czy to pomoże Ci konkretnego problemu, ale należy wziąć pod uwagę Utylizacja niektóre z tych obiektów po zakończeniu pracy z nimi. Robiłem coś takiego ostatnio, a zawijanie rzeczy przy użyciu instrukcji wydaje się oczyścić kilka wyjątków timeout dla mnie.

  using (var reqStream = request.GetRequestStream()) 
      { 
       if (reqStream == null) 
       { 
        return; 
       } 

       //do whatever 

      } 

również sprawdzić te rzeczy

  • Czy serwer służący https w lokalnym środowisku dev?
  • Czy poprawnie skonfigurowałeś powiązania * .443 (https)?
  • Czy musisz ustawić poświadczenia na żądanie?
  • Czy to twoje konto puli aplikacji uzyskuje dostęp do zasobów https lub czy jest ono przekazywane przez twoje konto?
  • Czy myślałeś o użyciu WebClient zamiast tego?

    using (WebClient client = new WebClient()) 
        {    
         using (Stream stream = client.OpenRead("https://server-url-xxxx.com")) 
         using (StreamReader reader = new StreamReader(stream)) 
         { 
          MessageBox.Show(reader.ReadToEnd()); 
         } 
        } 
    

EDIT:

złożyć wniosek od konsoli.

internal class Program 
{ 
    private static void Main(string[] args) 
    { 
     new Program().Run(); 
     Console.ReadLine(); 
    } 

    public void Run() 
    { 

     var request = (HttpWebRequest)System.Net.WebRequest.Create("https://server-url-xxxx.com"); 
     request.Method = "POST"; 
     request.ProtocolVersion = System.Net.HttpVersion.Version10; 
     request.ContentType = "application/x-www-form-urlencoded"; 

     using (var reqStream = request.GetRequestStream()) 
     { 
      using(var response = new StreamReader(reqStream) 
      { 
       Console.WriteLine(response.ReadToEnd()); 
      } 
     } 
    } 
} 
+0

Dzięki za odpowiedź. 1. Nie, nie służy 2. Tak 3. Nie 4. Czy możesz to rozwinąć? Nie dostałem tego. 5. Próbowałem WebClient, ale w .OpenRead wyrzucił błąd przekroczenia czasu operacji – Wiz

+0

Jeszcze jedna aktualizacja - mam prostą konfigurację aplikacji Pythona, aby uzyskać dostęp do tego samego interfejsu API przez HTTPS i jego pracę absolutnie w porządku. Wygląda na to, że tylko .Net jest problematyczny. Nie pewny dlaczego. – Wiz

+0

używasz cassini, iisexpress lub iis? – Peter

9

wpadłem na ten sam problem. Wygląda na to, że został rozwiązany dla mnie. Przeszedłem cały mój kod, upewniając się, aby wywołać webResponse.Close() i/lub responseStream.Close() dla wszystkich moich obiektów HttpWebResponse. Dokumentacja wskazuje, że można zamknąć strumień lub obiekt HttpWebResponse. Dzwonienie do nich nie jest szkodliwe, więc zrobiłem to. Brak zamknięcia odpowiedzi może spowodować, że aplikacja zakończy połączenia w celu ponownego użycia, co wydaje się mieć wpływ na HttpWebRequest.GetRequestStream, o ile mogę zaobserwować w moim kodzie.

+0

przydarzyło mi się, gdy korzystam z REST API dla usług mobilnych Azure – Ramakrishna

+0

@ DDRider62 Uratowałeś mój czas, człowieku! –

0

Spróbuj tego:

WebRequest req = WebRequest.Create("https://server-url-xxxx.com"); 
    req.Method = "POST"; 
    string json_value = jsonSerializer.Serialize(data); //Body data 
    ServicePointManager.Expect100Continue = false; 
    using (var streamWriter = new StreamWriter(req.GetRequestStream())) 
    { 
     streamWriter.Write(json_value); 
     streamWriter.Flush(); 
     streamWriter.Close(); 
    } 
    HttpWebResponse resp = req.GetResponse() as HttpWebResponse; 
    Stream GETResponseStream = resp.GetResponseStream(); 
    StreamReader sr = new StreamReader(GETResponseStream); 
    var response = sr.ReadToEnd(); //Response 
    resp.Close(); //Close response 
    sr.Close(); //Close StreamReader 

i przegląd URI:

  • zastrzeżone znaki.Wyślij znaki zastrzeżone przez URI może przynieść problemy ! * ' () ; : @ & = + $ ,/? # [ ]

  • URI Długość: Państwo nie powinno przekraczać 2000 znaków

+0

'StreamWriter' wywoła' Flush() '&' Close() 'w jego' Dispose() 'metodzie, która zostanie wywołana dla twojego bloku używającego. –

Powiązane problemy