2012-11-29 23 views
7

WCF ile oluşturulmuş bir REST API'mız var.Yanlış WebFaultException

Böyle WebFaultException ile arkayüz tüm istisnaları ele: biz Yayınla yapmak Burası bir dere ile bir senaryoda haricinde gayet güzel çalışıyor

throw new WebFaultException<string>(e.Message, HttpStatusCode.NotAcceptable); 

.

Bunun bir örneği:

[WebInvoke(Method = "POST", UriTemplate = "saveUser?sessionId={sessionId}&userId={userId}", 
     RequestFormat = WebMessageFormat.Json, 
     ResponseFormat = WebMessageFormat.Json,    
     BodyStyle = WebMessageBodyStyle.WrappedRequest)] 
    [OperationContract] 
    string SaveUser(string sessionId, int userId, Stream stream); 

biz o zaman almaya devam istisna içine koşmak zaman, using ifadesinde bu akışı işleme: Fiddler itibaren

:

HTTP/1.1 400 Bad Request 
    <p>The server encountered an error processing the request. The exception message is 'The message object has been disposed.'. See server logs for more details. The exception stack trace is: </p> 
    <p> at System.ServiceModel.Channels.ByteStreamMessage.InternalByteStreamMessage.get_Properties() 
    at System.ServiceModel.OperationContext.get_IncomingMessageProperties() 
    at System.ServiceModel.Dispatcher.WebErrorHandler.ProvideFault(Exception error, MessageVersion version, Message&amp; fault)</p> 

Akışla ve StreamRead ile ilgili bir şeyleri var gibi görünüyor bertaraf ediliyor.

Daha sonra StreamReader'ı imha edecek her şeyi kaldırmaya çalıştım ve bu acctualy çalışır.

enter image description here

Bu, doğru istisna mesaj gönderme ile sorunu çözer, ama ne kadar kötü bu kapatmadan veya bizim StreamReader imha değil, başvurumuzu etkileyecektir: Şimdi bu işleme kodu şöyle? Bunu çözmenin başka bir yolu var mı?

cevap

7

Bu, StreamReader'ın akışın "sahipliğini" ele geçirmesi nedeniyle olur. Başka bir deyişle, kaynak akışını kapatmak kendi kendini sorumlu kılar. Programınız Dispose veya Close (çağrı kullanma kapsamını durumunuzda bırakarak) olarak adlandırılır çağırmaz, o zaman kaynak akışını da elden çıkarır. Durumunuzda sr.Dispose() çağrısı. Yani dosya akışı sonra öldü.

Bunu istemezseniz, StreamReader'dan miras kalan ve Kapat yöntemini geçersiz kılan yeni bir sınıf oluşturabilirsiniz; Kapanış yönteminizin içinde, akışı kapatmayan Atma (yanlış) 'ı çağırın.

Ayrıca, Jon Skeet's MiscUtil kitaplığından NonClosingStreamWrapper sınıfını da kullanabilirsiniz, bu tam olarak bu amaca hizmet eder.

Ancak Yönetilmeyen kaynakları temizleyemediğinden StreamReader'ı elden çıkarmadan bırakmak daha iyi olur.