3

何か特別なことに気づきました。basicHttpBindingを介して公開される内部ストックサービスと、メタデータが有効になっているcustomBinding(http + binary)があります。httpのmexエンドポイントも含めました。VisualStudio2008とVB.NETを使用しています

つい最近、他のプロジェクトでこのサービスへのサービス参照を正常に追加できないことに気付きました。生成されるのは、FaultContractを介して含めた最初のカスタム例外だけでした(実際には、1つのタイプしかありませんでした)。単純なWeb参照を追加すると、それも正しく機能します。また、WcfClient.exeは、サービスのロードにも問題はありませんでした。VS.NET追加サービス参照だけでは機能しません。

サービスでは、この例外はExceptionを継承し、シリアル化可能としてマークされます。それがあなたがすることになっているすべてです、そうではありませんか?

とにかく、これは私を困惑させました。このカスタム例外のFaultContractを削除すると、すべてが正常に機能します。サービス参照を追加できますが、問題ありません。しかし、カスタム例外をまだ持つことができる方法はありますか?これは既知の問題ですか?

4

4 に答える 4

8

今日、私はこれに出くわしました。解決策は、FaultContractでExceptionから継承しないオブジェクトを使用することでした。FaultExceptionFaultContractのMSDNドキュメントを見ると、公式の例では、FaultException.DetailのExceptionを拡張するクラスではなく、プレーンクラス(DataContact属性を使用)が使用されていることがわかります。例外によってサービス参照の追加が失敗する理由はわかりませんが、カスタム例外の型情報のシリアル化または取得に関係していると思われます。実用的なアプローチを示すために、実装例の前後を含めました。

前(動作しませんでした):

[ServiceContract]
public interface IMyService
{
    [OperationContract]
    [FaultContract(typeof(MyException))]
    MyResults MyServiceOperation(string myParameter);
}

[Serializable]
public class MyException : Exception
{
    public string CustomData { get; set; }
}

[ErrorHandlerBehavior(typeof(MyErrorHandler))]
public class MyService : IMyService
{
    public MyResults MyServiceOperation(string myParameter)
    {
        ...
        throw new MyModelException { CustomData = "42" };
        ...
    }
}

public class MyErrorHandler : IErrorHandler
{
    public bool HandleError(Exception error) { return false; }

    public void ProvideFault(Exception error, MessageVersion version, ref Message fault)
    {
        try { throw error; }
        catch (MyModelException ex)
        {
            var faultEx = new FaultException<MyException>(new MyException { CustomData = ex.CustomData });
            fault = Message.CreateMessage(version, faultEx.CreateMessageFault(), faultEx.Action);
        }
        catch { /* Supress all others */ }
    }
}

後(働いた):

[ServiceContract]
public interface IMyService
{
    [OperationContract]
    [FaultContract(typeof(MyFault))]
    MyResults MyServiceOperation(string myParameter);
}

[DataContract]
public class MyFault
{
    [DataMember]
    public string CustomData { get; set; }
}

[ErrorHandlerBehavior(typeof(MyErrorHandler))]
public class MyService : IMyService
{
    public MyResults MyServiceOperation(string myParameter)
    {
        ...
        throw new MyModelException { CustomData = "42" };
        ...
    }
}

public class MyErrorHandler : IErrorHandler
{
    public bool HandleError(Exception error) { return false; }

    public void ProvideFault(Exception error, MessageVersion version, ref Message fault)
    {
        try { throw error; }
        catch (MyModelException ex)
        {
            var faultEx = new FaultException<MyFault>(new MyFault { CustomData = ex.CustomData });
            fault = Message.CreateMessage(version, faultEx.CreateMessageFault(), faultEx.Action);
        }
        catch { /* Supress all others */ }
    }
}

出典:Max Striniは、彼のコードを使用し、この問題の解決策を見つけるのに役立ちました。

于 2011-02-08T01:51:04.307 に答える
1

System.Exceptionから継承されたオブジェクトを使用して障害コントラクトを作成する方法に関する次の記事を見つけました:http: //blog.clauskonrad.net/2008/06/wcf-and-custom-exceptions.html

しかし、それは私にはうまくいきませんでした。それがうまくいかなかった理由は、.NET-.NETバインディングではなくBasicHttpバインディングを使用しているためだと思います。

于 2012-07-31T20:06:41.217 に答える
0

私もこの問題にぶつかりました。svcutil.exeを使用して、同じ問題が発生していないように見えるプロキシを生成することになりました。

于 2011-09-02T13:06:53.850 に答える
0

同じ問題が発生し、SVCUTIL.exeを使用してプロキシを生成することで解決しました。私はMSDNが推奨する方法でカスタム障害セットアップを行いましたが、「サービス参照の追加」にはプロキシに障害コントラクトが含まれていませんでした。それから私はSVCUTILを使用しました、そしてそれは魔法のように働きました:)

于 2011-11-25T17:18:17.157 に答える