1

プロパティが FillerInd と呼ばれる DataMember(isRequired:=True) があります。そのフィールドが空であるか、存在しないかをどのように判断しますか? 私はオンラインで読んでいましたが、必要なフィールドが欠落している場合、XML のシリアル化と逆シリアル化を行う必要があり、例外 MissingMethodException がスローされます。これを実装する方法や、これが最善の方法であるかどうかはわかりません。私を正しい道に導く助けがあれば、本当に感謝しています。

4

1 に答える 1

4

DataMember プロパティIsRequiredは、プロパティがネットワークで必要かどうか、つまりメッセージに存在する必要があるかどうかを示します。これにより例外が発生する典型的な状況は、サービスがIsRequired = trueクライアントに通知せずにプロパティを追加して DataContract を更新する場合です。クライアントは、プロパティを含まないシリアル化されたオブジェクトを送信するため、例外がスローされます。

あまり一般的ではありませんが、基本型のプロパティを使用してこの問題を再現する簡単な方法は、EmitDefaultValueプロパティを明示的に false に設定することです。これを行ってから、その DataContract のオブジェクトを使用して操作を呼び出そうとすると、例外がスローされる場合があります。次の例を検討してください。

// Data Contract
[DataContract]
public class Animal
{
    [DataMember(IsRequired = true, EmitDefaultValue = false)]
    public string Name;
}

// IService
[OperationContract]
int GetIdentifier(Animal animal);

// Client operation
int id = client.GetIdentifier(new Animal()); // Causes exception

これにより、SerializationExceptionが発生し(次に CommunicationException が発生します)、次の行に沿ったメッセージが表示されます。

型 ....アニマルのメンバー名はシリアライズできません。この例外は通常、null 値が許可されていない場所で null 値を使用しようとした場合に発生します。「名前」メンバーはデフォルト値 (通常は null またはゼロ) に設定されます。メンバーの EmitDefault 設定は「false」で、メンバーをシリアル化しないことを示します。ただし、メンバーの IsRequired 設定は「true」であり、シリアル化する必要があることを示しています。この競合は解決できません。「名前」をデフォルト以外の値に設定することを検討してください。または、DataMemberAttribute 属性の EmitDefaultValue プロパティを true に変更するか、IsRequired プロパティを false に変更することもできます。

クライアント側でこの問題を回避する場合 (たとえば、生成されたサービス参照の reference.cs を編集して、クライアント側で DataMember が不要になるようにする)、デシリアライズ時にサービスで例外が発生することに注意してください。間違いだと思います。


あなたの特定の発言や質問に目を向けます。

フィールドが空かどうかを判断するために何もする必要はありません。WCF フレームワークがこれを処理します。必要に応じて、(デ) シリアライゼーションにフックして、この問題を把握したり、メッセージを処理する前に検査したりすることもできると思います。

前述のとおり、この状況ではMissingMethodExceptionではなく、SerializationExceptions と CommunicationExceptions が発生します。

「IsRequired」が必要かどうか、それが「最適なルート」かどうかはわかりません。もちろん、これはあなたの状況によって異なります。

于 2012-10-22T20:37:32.167 に答える