質問
初めて WCF サービスを作成します。サービスとそのすべてのクライアントは (少なくとも現時点では) C# で書かれています。サービスは、渡されるデータに対して多くの入力検証を行う必要があるため、無効なデータをクライアントに返す何らかの方法が必要です。私はフォールトと例外、フォールトで例外をラップすること、そしてさらに混乱させるだけの矛盾した記事についてたくさん読んできました。この場合の適切な対処方法は何ですか?
例外を完全に回避し、結果の戻りメッセージをパッケージ化する必要がありますか?特別な Fault または特別な Exception を作成する必要がありますか、それとも非 WCF 検証関数の場合と同様に ArgumentExceptions をスローするだけでよいでしょうか?
私が今持っているコード(の影響を受けています) MSDN) は:
[DataContract]
public class ValidationFault
{
[DataMember]
public Dictionary<string, string> Errors { get; private set; }
[DataMember]
public bool Fatal { get; private set; }
[DataMember]
public Guid SeriesIdentifier { get; private set; }
public ValidationFault(Guid id, string argument, string error, bool fatal)
{
SeriesIdentifier = id;
Errors = new Dictionary<string, string> {{argument, error}};
Fatal = fatal;
}
public void AddError(string argument, string error, bool fatal)
{
Errors.Add(argument, error);
Fatal |= fatal;
}
}
そしてメソッドには [FaultContract(typeof(ValidationFault))] があります。では、これはこれに取り組む「正しい」方法なのでしょうか?
解決
クライアントで検証を行っており、メソッド (Web サービス呼び出し) に渡されると有効な値が必要な場合は、例外をスローします。これは、パラメーターの名前が無効であることを示す例外である可能性があります。(見る:引数例外)
しかし、データを適切に検証するためにクライアントに依存したくない場合もあり、その場合、Web サービスに入力されるデータが無効である可能性があるという前提が残ります。その場合、それは本当に例外的なケースではなく、例外であってはなりません。その場合、列挙型 (OK、無効、不完全) に設定された Status プロパティとパラメーターの名前などの詳細が設定された Message プロパティを持つ列挙型または Result オブジェクトを返すことができます。
この種のエラーは開発中に必ず発見して修正します。QA プロセスでは、クライアントの有効な使用と無効な使用を注意深くテストする必要があり、これらの技術メッセージをクライアントに中継したくないでしょう。代わりに、検証システムを更新して、無効なデータがサービス呼び出しに送信されないようにする必要があります。
私の想定では、WCF サービスには複数の UI があると考えられます。現時点では 1 つは Web UI ですが、後で WinForms、WinCE、または .NET クライアントに期待されるものに準拠していないネイティブの iPhone/Android モバイル アプリケーションを使用して別の UI を追加する可能性があります。
他のヒント
WCF サービスから例外をスローすることは役に立ちません。なぜでしょうか?それは裸の障害として戻ってくるので、次のことを行う必要があります。
a) 例外を含むようにフォルトを設定します。
b) フォールトを解析して例外のテキストを取得し、何が起こったのかを確認します。
したがって、例外ではなく障害が必要です。あなたの場合、障害コントラクトの一部として検証に失敗したフィールドのリストを含むカスタム障害を作成します。
WCF は、ISerializable ではない辞書を使って面白いことを行うことに注意してください。特別な処理が行われるため、戻ってくるメッセージがネットワーク上で適切に表示されることを確認してください。そうでない場合は、配列に戻ります。
MS Patterns and Practices Enterprise Library Validation ブロックをポリシー注入ブロックと組み合わせて確認するとよいでしょう。 リンクテキスト これにより、データ コントラクト メンバーを検証属性で装飾したり、サービス実装を装飾したりすることができます。これは、WCF との統合と合わせて、検証の失敗が、それぞれの検証失敗に対する ValidationDetail オブジェクトを含む ArgumentValidationException フォールトとして自動的に返されることを意味します。
WCf で entlib を使用すると、多くのコードを記述せずに、多くの検証やエラー報告を取得できます。