system.exceptionを含むカスタムfaultContractオブジェクトを使用すると、「サービスリファレンスの追加」が失敗します

StackOverflow https://stackoverflow.com/questions/4656257

質問

私はちょうど何か特別なことに気づきました。 Basichttpbindingを通じて公開された内部株式サービスと、メタデータが有効になっているカスタムバインディング(HTTP+バイナリ)があります。 HTTPのMEXエンドポイントも含めました。 Visual Studio 2008&VB.Netを使用しています

つい最近、私たちは他のプロジェクトでこのサービスへのサービスリファレンスを成功して追加できないことに気付きました。それが生成するのは、FaultContractを介して含めた最初のカスタム例外だけでした(実際、タイプは1つしかありませんでした)。簡単なWebリファレンスを追加すると、正しく機能します。また、WCFCLIENT.EXEは、サービスのロードにも問題ありませんでした。 vs.netの追加サービスリファレンスは機能しません。

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

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

役に立ちましたか?

解決

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

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

[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 */ }
    }
}

ソース: マックス・ストリーニ 彼のコードを使用し、この問題の解決策を見つけるのに役立ちます。

他のヒント

System.Exceptionから継承されたObjected exceptionを使用して障害契約を作成する方法に関する次の記事を見つけました。 http://blog.clauskonrad.net/2008/06/wcf-and-custom-exceptions.html

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

私もこの問題にぶつかりました。結局、svcutil.exeを使用して、同じ問題を抱えていないと思われるプロキシを生成しました。

私は同じ問題を抱えており、svcutil.exeを使用してプロキシを生成することで解決しました。 MSDNが推奨する方法でカスタム障害セットアップを正確に設定しましたが、「サービスリファレンスの追加」はプロキシに障害契約を含めていませんでした。それから私はsvcutilを使用しました、そしてそれは魔法のように働きました:)

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top