一般的な障害例外を作成しFaultException<MyWebServiceFaultDetail>
、MessageFault としてメッセージ インスペクター パイプラインに戻す場合、クライアントはその catch(FaultException<MyWebServiceFaultDetail> ex)
ブロックで一般的な障害を受信せず、ブロック内でのみキャッチされcatch (FaultException ex)
ます。
MyWebServiceFaultDetail
と含意はどちらも、単一のプロジェクト内のIClientMessageInspector
クライアント WCF Web 参照と同じプロジェクト内にありますMyProjects.MyWebService
。
WebService は、プロジェクトへの参照を持つ別のプロジェクトによって呼び出されますMyProjects.MyWebService
。
*簡潔にするためにコメントを削除しました
データ コントラクト:
[DataContract]
public class MyWebServiceFaultDetail
{
[DataMember]
public string MessageDetail { get; set; }
[DataMember]
public string MessageType { get; set; }
[DataMember]
public string TransactionComplete { get; set; }
[DataMember]
public string TransactionSuccess { get; set; }
public override string ToString()
{
return string.Format("Detail[MessageDetail={0}] [MessageType={1}] [TransactionComplete={2}] [TransactionSuccess={3}]", MessageDetail,MessageType ,TransactionComplete ,TransactionSuccess );
}
}
メッセージ インスペクター。reply.Headers.Action
このメソッドの実行時にそれが nullであることを追加します。CreateMessage() の呼び出しでアクション値を設定しても影響はありませんでした。私が試した値。
.CreateMessage(reply.Version, ex.CreateMessageFault(), "*");
.CreateMessage(reply.Version, ex.CreateMessageFault(), reply.Headers.Action);
.CreateMessage(reply.Version, ex.CreateMessageFault(), ex.Action);
internal class ResponseMessageInspector : System.ServiceModel.Dispatcher.IClientMessageInspector
{
private static NLog.Logger _logger = NLog.LogManager.GetCurrentClassLogger();
public void AfterReceiveReply(ref Message reply, object correlationState)
{
MessageBuffer bufferedMessage = null;
try
{
bufferedMessage = reply.CreateBufferedCopy(Int32.MaxValue);
Message replacedMessage = bufferedMessage.CreateMessage();
if (bufferedMessage.MessageContentType != "application/soap+msbin1" || reply.IsEmpty || reply.IsFault)
{
reply = replacedMessage;
return;
}
bool isErrorMessage;
var messageReader = replacedMessage.GetReaderAtBodyContents();
isErrorMessage = (messageReader.Name == "TransactionReport");
if (isErrorMessage)
{
string transactionComplete = "",
transactionSuccess = "",
messageType = "",
messageDetail = "",
messageBrief = "";
while (messageReader.Read())
{
if (messageReader.NodeType == XmlNodeType.Element && !messageReader.IsEmptyElement)
{
switch (messageReader.Name)
{
case "TransactionComplete":
transactionComplete = messageReader.ReadString();
break;
case "TransactionSuccess":
transactionSuccess = messageReader.ReadString();
break;
case "MessageType":
messageType = messageReader.ReadString();
break;
case "MessageDetail":
messageDetail = messageReader.ReadString();
break;
case "MessageBrief":
messageBrief = messageReader.ReadString();
break;
default:
break;
}
}
}
if (string.IsNullOrEmpty(messageBrief))
{
messageBrief = "My response processing fault: {Unable to obtain error message from My response, enable WCF message tracing for more detailed information}";
_logger.Warn(messageBrief);
}
FaultException ex = new FaultException<MyWebServiceFaultDetail>(
new MyWebServiceFaultDetail
{
TransactionComplete = transactionComplete,
TransactionSuccess = transactionSuccess,
MessageDetail = messageDetail,
MessageType = messageType
},
new FaultReason(messageBrief));
Message faultMessage = Message.CreateMessage(reply.Version, ex.CreateMessageFault(), null);
faultMessage.Headers.CopyHeadersFrom(reply.Headers);
faultMessage.Properties.CopyProperties(reply.Properties);
reply = faultMessage;
}
else
reply = bufferedMessage.CreateMessage();
}
finally
{
if (bufferedMessage != null)
bufferedMessage.Close();
}
}
public object BeforeSendRequest(ref Message request, System.ServiceModel.IClientChannel channel)
{
return null;
}
}
FaultException
を受信しているが、を受信していないクライアント コードFaultException<MyWebServiceFaultDetail>
internal static T TrySendToMyWebService<T>(
CallWebServiceDelegate<T> callWebService,
bool expectResponce,
out MessageProcessorResult result) where T : class
{
T MyWebServiceResponce = null;
result = new MessageProcessorResult();
using (ServiceRequestConnectorServiceSoapClient ws =
new ServiceRequestConnectorServiceSoapClient())
{
try
{
MyWebServiceWebServiceHelper.LogOn(ws);
MyWebServiceResponce = callWebService(ws);
if (expectResponce && MyWebServiceResponce == null)
{
result.ShouldRetry = true;
result.RetryReason = "Unexpected MyWebService web service response. The response was null";
}
}
catch (FaultException<MyWebServiceFaultDetail> ex)
{
// I never get called :(
result.Exception = ex;
result.ShouldRetry = true;
result.RetryReason = string.Format("An Exception was raised calling the MyWebService web service: Reason:{0} /r/nDetails: {1}", ex.Reason, ex.Detail.ToString());
_logger.ErrorException(result.RetryReason, ex);
}
catch (FaultException ex)
{
result.Exception = ex;
result.ShouldRetry = true;
result.RetryReason = string.Format("An Exception was raised calling the MyWebService web service: {0}", ex.Message);
_logger.ErrorException(ex.Message, ex);
}
finally
{
MyWebServiceWebServiceHelper.LogOff(ws);
}
}
return MyWebServiceResponce;
}