2

IIS で実行されているがファクトリを介して実行されている Web サービスは、スローされた元の例外を維持しません。

例えば:

私の Web サービスは、次のように FaultContractAttribute でマークアップされています。

public interface IMyService
{
    [FaultContract(typeof(MyCustomException))]
    [OperationContract]
    bool IsAuthorized();
}

私の Web サービスの実装は、次のようにカスタム例外をスローします。

public class MyService : IMyService
{
    public bool IsAuthorized()
    {
        throw new FaultException<MyCustomException>(fault, fr);
    }
}

それで:

  1. 私の WCF - ファクトリを使用していない - が に似ている<%@ ServiceHost Language="C#" Debug="true" Service="MyService" %>場合、クライアント側で元の例外 (MyCustomException) を取得できます。

  2. 私の WCF - USING some factory - が に似ている場合<%@ ServiceHost Language="C#" Debug="true" Service="MyService" Factory="MyFactory" %>、クライアント側では元の例外 (MyCustomException) を取得できず、SOAP 例外 (FaultException) のみを取得し、役に立たない一般的なトレースとメッセージを表示します

ノート:

WCF ファクトリ MyFactory は、その SERVICE HOST で実装され、IErrorHandler から開始された SERVICE BEHAVIOR が含まれています

このサービス動作では、ProvideFault メソッドは何もしません (この方法で元の例外を維持する方法がわかりません)。

要約すると、期待からの回答を求めます: WCF ファクトリを使用しているときに元の例外 (MyCustomException) を維持するにはどうすればよいですか? ありがとう。

4

1 に答える 1

1

私の最近のプロジェクト (WCF REST サービス) では、WebServiceHostFactoryを使用していますが、 IErrorHandlerを使用してこれを達成することができました。以下のサンプルを探す

シリアル化してクライアントに送り返すクラス ExceptionInfo を作成しました。

[Serializable]
public class ExceptionInfo
{
    public string ExceptionType { get; set; }
    public string ExceptionMessage { get; set; }
    public string StackTrace { get; set; }
}

カスタム エラー ハンドラの実装

[DataContract]
public class MyCustomServiceErrorHandler : IErrorHandler
{
    #region IErrorHandler Members

    /// <summary>
    /// This method will execute whenever an exception occurs in WCF method execution
    /// </summary>
    public void ProvideFault(Exception error, MessageVersion version, ref Message fault)
    {
        var exceptionInfo = new ExceptionInfo();

        if (error is MyCustomException)
            exceptionInfo.ExceptionType = error.Type.ToString();;
        else
            exceptionInfo.Type = "Unhandled Exception";

        exceptionInfo.ExceptionMessage = error.Message;            
        exceptionInfo.StackTrace = error.StackTrace;

        var faultException = new FaultException<ExceptionInfo>(exceptionInfo);

        object detail = faultException.GetType().GetProperty("Detail").GetGetMethod().Invoke(faultException, null);

        fault = Message.CreateMessage(version, "", detail, new DataContractSerializer(detail.GetType()));

        var webBodyFormatMessageProp = new WebBodyFormatMessageProperty(WebContentFormat.Xml);

        fault.Properties.Add(WebBodyFormatMessageProperty.Name, webBodyFormatMessageProp);

        var httpResponseMessageProp = new HttpResponseMessageProperty();

        httpResponseMessageProp.Headers[HttpResponseHeader.ContentType] = "application/xml";
        httpResponseMessageProp.StatusCode = HttpStatusCode.BadRequest;
        httpResponseMessageProp.StatusDescription = exceptionInfo.ExceptionMessage;

        fault.Properties.Add(HttpResponseMessageProperty.Name, httpResponseMessageProp);

    }

    /// <summary>
    /// Performs error related behavior
    /// </summary>
    /// <param name="error">Exception raised by the program</param>
    /// <returns></returns>
    public bool HandleError(Exception error)
    {
        // Returning true indicates that an action(behavior) has been taken (in ProvideFault method) on the exception thrown.
        return true;
    }

これで、上記のハンドラーを使用してサービスを装飾できます。

[ServiceContract]    
[ServiceErrorBehavior(typeof (MyCustomServiceErrorHandler))]
public class LoginService : ServiceBase
{}

クライアント側では、応答の HttpStatusCode が != Ok かどうかを確認し、応答を ExceptionInfo タイプにデシリアライズして、要件ごとにメッセージ ボックスまたはハンドルに表示できます。

お役に立てれば。

于 2012-04-06T16:58:40.583 に答える