0


1

私はWCFとenumの問題を克服しようとしています。そこではenumを含むオブジェクトをサーバーからクライアント(または他のサーバー)に渡します。 列挙は意図的に1から始まります。 enumが初期化されて値が定義されているときはすべてうまくいきますが、enumで定義されていないときは、この素晴らしい(そして非常にわかりやすい(…​))エラーメッセージが表示されます。

「基になる接続が閉じられました。接続が突然閉じられました。」

私が達成しようとしているのは、データベース内の破損したデータ(とにかくenumにキャストされていて、かなり厄介です)から、または開発者がオブジェクトの開始時にenum値の設定を忘れたときです。意味のあるメッセージを表示するには、「列挙型の値が無効です。\ {0}、値:\ {1}」と入力してください。

私はクラス内のenumのセッターとゲッターに "Enum.IsDefined"を使用しようとしましたが、意味のある例外をクライアント(または他のサーバー)に投げましたが、それでも "connection close"エラーが発生しました。サーバーのデバッグを許可すると、意味のあるメッセージが表示されますが、サーバー側でのみ可能です。

これが列挙型セッターの断片です。

プライベートTestEnum m_TestEnum。

[DataMember] public TestEnum TestEnum {get {if(Enum.IsDefined(typeof(TestEnum)、m_TestEnum))} {return m_TestEnum;} } else {新しいApplicationExceptionをスローします( "列挙値が無効です:" m_TestEnum); set {if(Enum.IsDefined(typeof(TestEnum)、value)){m_TestEnum = value;} } else {新しいApplicationExceptionをスローします( "列挙値は無効です:"値)。 }}}

列挙型を0から(「不明な」値で)開始するのは十分ではありません。列挙型には存在しない値をまだ取得できるからです。 "IsDefined"をチェックしてenumを "Unknown"値に設定する両方のソリューションを組み合わせることができますが、それでも開発サイクルでそれらを解決するためにこれらのケースを知りたいので、これは理想的なソリューションではありません。

あなたは何を言っていますか? ありがとう、Nir。

2 Answer


5


WCFを介して列挙型を送信すると、数値ではなく、列挙型の値の文字列表現が送信されます。 これにより、両側で同じ列挙型ラベルを異なる番号にマッピングできます。

受信者が理解できないラベルが送信された場合は、チャンネルは閉じられます。 私はこれが定義されていないenumの値にも及ぶと信じています(それはあなたが満足しているように見えます)。

したがって、enumラベルが送信者側で有効であるからといって、クライアントが必ずしもそれを理解するとは限りません。

送信者と受信者の両方で同じクラス定義を共有していますか?

この問題をさらにデバッグするには、クライアントとサーバーでサービストレースを有効にする必要があります(これは多くのフラストレーションを起こすWCF問題に当てはまります)。

次のXMLをApp.configに(クライアントとサーバーの両方で)追加します。


http://msdn.microsoft.com/en-us/library/ms733025.aspx[この設定にはいくつかのオプション]

この設定を追加すると、 Service Trace Viewer Toolで表示できる `.svclog`ファイルが作成されます。 このログには、警告やエラーなど、発生したすべてのことに関する多くの情報が含まれています。

生成されるログファイルは非常に大きくなる可能性があることに注意してください。デバッグが終了したら、必ずこの設定セクションを削除またはコメントアウトしてください。

'' '' '

ワイヤ上で使用される列挙型メンバには、異なる文字列値を指定できます。

たとえば、次の2つの列挙型はWCFと同等です。

パブリック列挙体CarCondition {新規、中古、レンタル、[非シリアル化]紛失}

[DataContract(Name = "CarCondition")]
public enum CarConditionWithDifferentNames {[EnumMember(Value = "New")] BrandNew、[EnumMember(Value = "Used")] PreviouslyWw、[EnumMember]レンタル

あなたはhttp://msdn.microsoft.com/en-us/library/aa347875.aspxを参照することができます。


1


問題は、直列化では列挙型で定義されていない値を直列化できないことです。これには(デフォルトの)0の値が含まれます。

例えば:

列挙型E {New = 1、Used}

[OperationContract]
パブリックEメソッド(){E e; eを返します。 }

Methodの呼び出しは、 "e"が "e =(E)0"として初期化されるため失敗します。 シリアライゼーションがその仕事をしようとするとき、それは0にマッチするEの中のフィールドを見つけない、それでそれは失敗する(または値を列挙型メンバーに制限するwsdlとマッチしないxmlを生成する)。

したがって、私たちのサービスメソッドが常に有効な値を返すようにする必要があります(enumの定義に従って)。

私は何もMSDNでこれについて話していないと思ったので、それは私のテストの後の私自身の結論です。

それが役立つことを願って、ホセ