2011-01-11 6 views
3

特に気がついたことがあります。私は、basicHttpBindingを通じて公開されている内部在庫サービスと、メタデータが有効になっているcustomBinding(http +バイナリ)を持っています。私はhttpのmexエンドポイントも含めました。 Visual Studio 2008を使用しています& VB.NETSystem.Exceptionを含むカスタムFaultContractオブジェクトを使用すると、 'Add Service Reference'が失敗します。

ちょうど最近、他のプロジェクトでこのサービスにサービスリファレンスを追加できなかったことがわかりました。生成するすべてのものは、FaultContract(実際には1つのタイプしかありませんでした)を通じた最初のカスタム例外でした。シンプルなWeb参照を追加すると正しく動作します。また、WcfClient.exeにはサービスのロードに問題はありませんでした。ちょうどVS.NETのサービス参照の追加は機能しません。

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

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

+0

あなたは_もちろん、例外は.NET以外のプラットフォームでは無意味であることを認識していますか? –

+0

私の印象は、WCFフレームワークのために例外からの無関係が必要であったという印象はありません。 Exceptionから継承したカスタム例外の正しいプロキシクラスを常に作成できるので、私は正しいとも思っています。 – SpoBo

答えて

8

私は今日これに遭遇しました。解決策は、FaultContractのExceptionから継承しないオブジェクトを使用することでした。 FaultExceptionFaultContractのMSDNドキュメントを見ると、公式の例では、FaultException.DetailのExceptionを拡張するクラスではなく、プレーンクラス(DataContact属性を使用)が使用されていることがわかります。私はなぜ例外が原因でAdd Service Referenceが失敗するのか分かりませんが、それはシリアライズやカスタム例外の型情報の取得と関係があります。私は、実際のアプローチを実証するために、実装前と実装後の例を取り上げました。彼のコードを使用するためのMax Striniし、解決策を見つけるのに役立ちます。(勤務)

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

ソースを

前(動作しませんでした)この問題に。

+0

thx :)私はいつも、WCFは、適切なFaultExceptionを作成するために、WCFに例外から継承したオブジェクトを必要とすると仮定しました。 – SpoBo

+0

これはうまくいった。私はsvcutilを使ってWSDLからサービスを生成しなければなりませんでした。私は例外をどうすればいいのか分かりませんでした。この回答は私の問題を解決しました。ありがとう! – Zoidberg

0

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

+0

真の解決策の1つは、Exceptionクラス派生モデル(またはおそらく.NET Coreクラスモデル)をDataMemberとして使用しないことです。 POCOに自分自身を制限するだけで、あなたのWCF契約は正確で、よりクリーンで、他の技術とより互換性があります。 (Java、PHPなど) – SpoBo

0

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

+1

Visual Studio内でコードを生成できるように、問題を解決することをお勧めします。誰が他のツールが同じ振る舞いをしているかを知っています。 +誰かがあなたのサービスを追加しようとするたびに、それは問題になるでしょう。ファイルを1つずつ除外して再コンパイルし、サービス参照をもう一度追加しようとします。これは、自分でサービスを書く場合にのみ適用されます。 – SpoBo

1

私はのSystem.Exceptionから継承された反対使用して、障害の契約を作成する方法について、以下の記事を見つけた:http://blog.clauskonrad.net/2008/06/wcf-and-custom-exceptions.html

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

+0

それで、うまくいかなかった解決策をお勧めしますか? –

+0

この記事の記事は、「SerializationInfoとStreamingContextを引数として持つ直列化プロセスを可能にする保護されたコンストラクタを提供する」キーとなりました。 1つは私のカスタム例外のコンストラクタを提供し、私はSystem.Exception'継承を維持することができます。 –

関連する問題