2012-11-29 3 views
7

우리는 WCF로 빌드 된 REST API를 가지고 있습니다.스트림을 사용하고 스트림을 닫을 때 잘못된 WebFaultException이 발생했습니다.

우리는이 같은 WebFaultException와 백엔드 모든 예외 처리 : 우리는 포스트 할 곳은 스트림과, 하나 개의 시나리오를 제외하고 잘 작동

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

합니다.

이의 예 :

[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); 

우리가 다음 우리가 계속 예외로 실행 할 때마다하는 using 문에이 스트림을 처리 : 피들러에서

:

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> 

스트림 및 StreamRead와 관련이있는 것처럼 보입니다. 처리되고있다.

그런 다음 StreamReader를 처리 할 항목을 제거하려고 시도했으며이 기능이 작동합니다.

enter image description here

이 올바른 예외 메시지를 보내는의 문제를 해결하지만, 얼마나 나쁜이 닫거나 우리는 StreamReader를 폐기하지, 우리의 응용 프로그램에 영향을 미칠 것 : 지금이 처리하는 코드는 다음과 같습니다? 이 문제를 해결하는 다른 방법이 있습니까?

답변

7

이 오류는 StreamReader가 스트림의 '소유권'을 인계 받기 때문에 발생합니다. 즉, 소스 스트림을 닫을 책임이 있습니다. 프로그램이 Dispose 나 Close를 호출하자마자 (당신의 경우에 using 문 범위를 남겨둔다) 소스 스트림을 처리 할 것이다. 귀하의 경우 sr.Dispose()를 호출하십시오. 그래서 파일 스트림은 죽은 것입니다.

이 작업을 원하지 않으면 StreamReader에서 상속 받고 Close 메서드를 재정의하는 새 클래스를 만들 수 있습니다. Close 메서드 내에서 스트림을 닫지 않는 Dispose (false)를 호출합니다.

Jon Skeet의 MiscUtil 라이브러리에있는 NonClosingStreamWrapper 클래스를 사용할 수도 있습니다. 이는 해당 용도로 사용됩니다.

그러나 관리되지 않는 리소스를 정리할 수 없으므로 삭제하지 않고 StreamReader를 종료하지 않는 것이 좋습니다.

관련 문제