2

私のサービスは、ビジネス ロジック全体が配置されている BusinessLogicLayer メソッドを呼び出すだけです。BL によって発生した例外を処理するためのベスト プラクティスは何ですか? (致命的な例外だけでなく、ユーザーが見つからないときに BL がスローする UserNotFoundException のような「論理的な」ApplicationExceptions も知りたいです)。

これらの例外を、クライアントが表示する FaultExceptions にどこで変換する必要がありますか?

BL からビジネス例外をスローし、それらをサービス呼び出しにキャッチして FaultException に変換し、クライアントに返す必要がありますか? または BL は、すでに「クライアントに優しい」FaultExceptions を発生させる必要がありますか?

前もって感謝します :)

4

2 に答える 2

2

標準の .Net 例外は、サーバー側で正しくシリアル化され、クライアント側で逆シリアル化されます。デフォルトでは、私たちのものではありません。なんで ?デバッグ セッション中にビジネス例外をクライアントに送信することがベスト プラクティスである場合が あります

ExceptionFault<ExceptionDetail>

ただし、コードを本番環境に置くときは、例外を送信しないように注意してください。サービスがインターネット上に公開されている場合、ハッカーに詳細を開示するセキュリティ リークが発生する可能性があります。

ビジネス例外をクライアントに送信するためのベスト (およびいくつかの必須) プラクティスは次のとおりです。

serviceDebugBehavior1/をオンに切り替えます

ServiceHost host = ...;
var debuggingBehavior = host.Description.Behaviors.Find<ServiceBehaviorAttribute>();
if (debuggingBehavior == null)
  debuggingBehavior = new ServiceBehaviorAttribute();
#if DEBUG
debuggingBehavior.IncludeExceptionDetailInFaults = true;
#else
debuggingBehavior.IncludeExceptionDetailInFaults = false;
#endif

xmlで構成するのも非常に簡単です

2/ サービス インターフェイスで、いくつかの [FaultContract] を宣言します。

[ServiceContract(Namespace="your namespace")]
public interface IBillingService
{
  [OperationContract]
  [FaultContract(typeof(BusinessException))]
  void RaiseBusinessException();
}

3/ ビジネス例外はシリアライズ可能としてマークする必要があります

[Serializable]
public class BusinessException : Exception
{ ... }

4/ クライアント側でビジネス例外を正しく逆シリアル化するには、FaultException<BusinessException>逆シリアル化を処理するコンストラクターを実装することが重要です。それ以外の場合は、ジェネリックが取得されますFaultException

protected BusinessException(SerializationInfo info, StreamingContext context)
  : base(info, context)
{}

5/例外に余分なメンバーがある場合は、それらをシリアル化/逆シリアル化します。

public DateTime CreationTime { get; set; }
protected BusinessException(SerializationInfo info, StreamingContext context)
: base(info, context)
{
  CreationTime = (DateTime)info.GetValue("CreationTime", typeof(DateTime));
}
public override void GetObjectData(SerializationInfo info, StreamingContext context)
{
  base.GetObjectData(info, context);
  info.AddValue("CreationTime", CreationTime);
}
于 2015-09-03T09:08:29.707 に答える
2

ビジネスロジックレイヤーからビジネス例外をスローすると言います。これにより、ビジネスロジックレイヤーがwcf実装と分離されたままになります。サービス呼び出しでは、applydispatchbehaviour をオーバーライドして、そこにエラー ハンドラを追加することができます。

IServiceBehavior.ApplyDispatchBehavior のオーバーライド

 void IServiceBehavior.ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
        {
            foreach (ChannelDispatcher dispatcher in serviceHostBase.ChannelDispatchers)
            {
                dispatcher.ErrorHandlers.Add(new FaultErrorHandler());
            }
        }

FaultErrorHandler

public class FaultErrorHandler : IErrorHandler
    {      

        void IErrorHandler.ProvideFault(System.Exception error, MessageVersion version, ref Message fault)
        {
            if (fault == null)
            {
                FaultException<[ExceptionType]> fe = new
                    FaultException<[ExceptionType]>([Exception cass],
                    error.Message, FaultCode.CreateReceiverFaultCode(new FaultCode("ServerException")));
                    MessageFault mf = fe.CreateMessageFault();
                    fault = Message.CreateMessage(version, mf, fe.Action);

            }
        }

    }
于 2012-07-19T11:30:43.317 に答える