Обработка ошибок службы WCF Rest и WebChannelFactory
Насколько я понимаю, следующее должно правильно генерировать пользовательскую ошибку из службы WCF Rest:
[DataContract(Namespace = "")]
public class ErrorHandler
{
[DataMember]
public int errorCode { get; set; }
[DataMember]
public string errorMessage { get; set; }
} // End of ErrorHandler
public class Implementation : ISomeInterface
{
public string SomeMethod()
{
throw new WebFaultException<ErrorHandler>(new ErrorHandler()
{
errorCode = 5,
errorMessage = "Something failed"
}, System.Net.HttpStatusCode.BadRequest);
}
}
В Fiddler это, кажется, работает, я получаю следующие необработанные данные:
HTTP/1.1 400 Bad Request
Cache-Control: private
Content-Length: 145
Content-Type: application/xml; charset=utf-8
Server: Microsoft-IIS/7.5
X-AspNet-Version: 4.0.30319
Set-Cookie: ASP.NET_SessionId=gwsy212sbjfxdfzslgyrmli1; path=/; HttpOnly
X-Powered-By: ASP.NET
Date: Thu, 03 May 2012 17:49:14 GMT
<ErrorHandler xmlns:i="http://www.w3.org/2001/XMLSchema-instance"><errorCode>5</errorCode><errorMessage>Something failed</errorMessage></ErrorHandler>
Но теперь на стороне клиента у меня есть следующий код:
WebChannelFactory<ISomeInterface> client = new WebChannelFactory<ISomeInterface>(new Uri(targetHost));
ISomeInterface someInterface = client.CreateChannel();
try
{
var result = someInterface.SomeMethod();
}
catch(Exception ex)
{
// Try to examine the ErrorHandler to get additional details.
}
Теперь, когда код выполняется, он попадает в зацепку и является System.ServiceModel.ProtocolException
с сообщением "Удаленный сервер возвратил неожиданный ответ: (400) Bad Request.". Кажется, что у меня нет способа увидеть детали ErrorHandler на данный момент. Кто-нибудь сталкивался с этим? Есть ли способ получить подробности ErrorHander на этом этапе?
1 ответ
WebChannelFactory
или же ChannelFactory
будет раскрывать вам только общий CommunicationException
, Вам нужно будет использовать IClientMessageInspector
поведение или полагаться на WebRequest
вернуть фактическую ошибку.
Для IClientMessageInspector
подход - смотрите комментарии в этой записи блога.
Для WebRequest
подход, вы можете следующее, чтобы поймать WebException
,
try { }
catch (Exception ex)
{
if (ex.GetType().IsAssignableFrom(typeof(WebException)))
{
WebException webEx = ex as WebException;
if (webEx.Status == WebExceptionStatus.ProtocolError)
{
using (StreamReader exResponseReader = new StreamReader(webEx.Response.GetResponseStream()))
{
string exceptionMessage = exResponseReader.ReadToEnd();
Trace.TraceInformation("Internal Error: {0}", exceptionMessage);
}
}
}
}