2010-03-25 8 views
8

Mam usługę REST używaną przez klienta .NET WCF.Uzyskiwanie szczegółów błędu z WCF REST

Po wystąpieniu błędu usługa REST zwraca nieprawidłowe żądanie HTTP 400 z treścią odpowiedzi zawierającą szeregowane informacje JSON.

Jeśli wykonam żądanie za pomocą Fiddlera, Javascript lub bezpośrednio z C#, mogę łatwo uzyskać dostęp do treści odpowiedzi, gdy wystąpi błąd.

Jednak używam WCF ChannelFactory z 6 dość złożonymi interfejsami. Wyjątek generowany przez ten serwer proxy zawsze ma wartość ProtocolException, bez żadnych użytecznych szczegółów.

Czy istnieje sposób na uzyskanie treści odpowiedzi, gdy pojawia się ten błąd?


Aktualizacja

Zdaję sobie sprawę, że istnieje obciążenie różnych sposobów, aby to zrobić za pomocą .NET oraz że istnieją inne sposoby, aby uzyskać odpowiedź o błędzie. Są przydatne, ale nie odpowiadają na to pytanie.

Usługi REST, których używamy, zmienią się, a gdy to zrobią, kompleksowe interfejsy zostaną zaktualizowane. Użycie interfejsu ChannelFactory z nowymi interfejsami oznacza, że ​​otrzymamy wyjątki czasu kompilacji (a nie czasu wykonywania) i ułatwi to konserwację i aktualizację kodu.

Czy istnieje sposób na uzyskanie treści odpowiedzi na błąd HTTP podczas korzystania z kanałów WCF?

+0

Czytając swoje wyjaśnienie, wygląda na to, że nie masz kontroli nad samą usługą REST, czy to prawda? –

+0

Właściwie w tym przypadku robimy, ale trudno to zmienić. Naszym problemem jest złożoność - WCF ChannelFactory daje naprawdę fajny sposób na zarządzanie nim za pomocą interfejsów. Denerwujące jest to, że odrzuca treść odpowiedzi, gdy status nagłówka HTTP jest inny niż 200. Gdy otrzymamy błąd z usługi REST, zwraca on stan HTTP 400 lub 500 ze szczegółami w treści. – Keith

Odpowiedz

1

Nie używaj ChannelFactory :-) Poważnie. Dlaczego miałbyś utworzyć interfejs REST, a następnie użyć proxy klienta WCF. Jaka jest korzyść z korzystania z usługi REST? Dlaczego po prostu nie używać wsHttpBinding? Za pomocą klasy HttpClient z zestawu startowego REST można tworzyć standardowe żądania HTTP, a następnie deserializować odpowiedź za pomocą DataContractSerializer.

E.g.

var httpClient = new HttpClient(); 
var content = httpClient.Get("http://example.org/customer/45").Content; 
var customer = content.ReadAsDataContract<Customer>() 
+2

Podoba mi się twoje proste, lepsze podejście, ale mamy dużą liczbę interfejsów i prawie wszystkie metody przyjmują złożone treści POST. Prostota kodu implementacji proxy "ChannelFactory" oszczędza nam ogromnej złożoności kodu. Wiem, że można to zrobić na swój sposób, ale naprawdę chcę wiedzieć: czy możemy uzyskać szczegóły błędu, jeśli zrobimy to w sposób 'ChannelFactory'? – Keith

3

Można spróbować rzucanie WebProtocolException z serwisu. W ten sposób szczegóły błędu powinny być zawarte w treści odpowiedzi HTTP. Rzucić okiem na ten artykuł:

Effective Error Handling with WCF & REST

+0

Dokładnie to robi usługa - szczegóły, jak JSON serializował w treści odpowiedzi HTTP. Problem polega na tym, że ChannelFactory rzuca wyjątek bez tych szczegółów dla dowolnego statusu nagłówka HTTP innego niż 200. Usługa działa, jest to problem polegający na implementacji klienta WCF. – Keith

1

moje dwa centy, że WCF jest dobry na wystawienie tej samej klasy przy użyciu wielu różnych wiązań. Podczas komunikacji z C# użyj powiązania SOAP, które jest dobre w informacjach o wyjątku. Jeśli musisz użyć powiązania stylu REST, możesz użyć prostego interfejsu WebRequest do wywołania usługi i użyć serializatora JSON do deserializacji wyników. Zapewni to również bezpośredni dostęp do kodu odpowiedzi.

4

można pobrać poniżej szczegół jako wyjątek:

   Exception innerException = exception.InnerException; 
       WebException webException = innerException as WebException; 
       HttpWebResponse response = webException.Response as HttpWebResponse; 
       string statusDescription = response.StatusDescription; 
       HttpStatusCode statusCode = response.StatusCode; 
1

Podejście opisane przez user653761 pracuje dla mnie; Po uzyskaniu dostępu do obiektu HttpWebResponse mogę użyć klasy DataContractSerializer takiego:

var serializer = new DataContractSerializer(typeof(MyDataContractType)); 
var deserialized = 
    (serializer.ReadObject(httpWebResponse.GetResponseStream()) as MyDataContractType); 

// ... 

Myślę, że to będzie działać na wszystko, co może WCF serializacji jeśli używasz właściwej serializatora, nie testować pod kątem wydajności (jeszcze) .

3

Urządzenie InnerException z ProtocolException będzie oznaczone jako . Możesz pobrać HttpWebResponse i zadzwonić pod numer GetResponseStream, aby odczytać rzeczywistą treść odpowiedzi. (Pamiętaj, aby przed rozpoczęciem czytania szukać na początku strumienia).

var webException = (WebException) protocolException.InnerException; 
var response = (HttpWebResponse) webException.Response; 
var responseStream = response.GetResponseStream() 
responseStream.Seek(0, SeekOrigin.Begin); 
var reader = new StreamReader(responseStream); 
var responseContent = reader.ReadToEnd(); 
Powiązane problemy