37

We're currently having a debate whether it's better to throw faults over a WCF channel, versus passing a message indicating the status or the response from a service.

Faults come with built-in support from WCF where by you can use the built-in error handlers and react accordingly. This, however, carries overhead as throwing exceptions in .NET can be quite costly.

Messages can contain the necessary information to determine what happened with your service call without the overhead of throwing an exception. It does however need several lines of repetitive code to analyze the message and determine actions following its contents.

We took a stab at creating a generic message object we could utilize in our services, and this is what we came up with:

public class ReturnItemDTO<T>
{
    [DataMember]
    public bool Success { get; set; }

    [DataMember]
    public string ErrorMessage { get; set; }

    [DataMember]
    public T Item { get; set; }
}

If all my service calls return this item, I can consistently check the "Success" property to determine if all went well. I then have an error message string in the event indicating something went wrong, and a generic item containing a Dto if needed.

The exception information will have to be logged away to a central logging service and not passed back from the service.

Thoughts? Comments? Ideas? Suggestions?

Some further clarification on my question

An issue I'm having with fault contracts is communicating business rules.

Like, if someone logs in, and their account is locked, how do I communicate that? Their login obviously fails, but it fails due to the reason "Account Locked".

So do I:

A) use a boolean, throw Fault with message account locked

B) return AuthenticatedDTO with relevant information

4

3 に答える 3

32

ただし、.NET で例外をスローすると非常にコストがかかる可能性があるため、これにはオーバーヘッドが伴います。

オブジェクトを XML にシリアライズおよびデシリアライズし、低速のネットワーク経由で送信しています。例外をスローすることによるオーバーヘッドは、それに比べれば無視できます。

私は通常、例外をスローすることに固執します。なぜなら、それらは何かがうまくいかなかったことを明確に伝え、すべてのWeb サービスツールキットにはそれらを適切に処理する方法があるからです。

あなたのサンプルでは、​​「アカウントがロックされました」というメッセージで UnauthorizedAccessException をスローします。

明確化: .NET wcf サービスはデフォルトで例外を FaultContracts に変換しますが、この動作は変更できます。MSDN:契約とサービスの障害の特定と処理

于 2008-09-17T09:09:10.910 に答える
6

他のメソッドを呼び出すようにサービスを呼び出すことを考えると、全体像を把握するのに役立つ場合があります。呼び出したすべてのメソッドがステータスを返し、それが true か false かをチェックするのは自分次第だと想像してみてください。それはかなり退屈になります。

result = CallMethod();
if (!result.Success) handleError();

result = CallAnotherMethod();
if (!result.Success) handleError();

result = NotAgain();
if (!result.Success) handleError();

これは、構造化されたエラー処理システムの強みの 1 つであり、実際のロジックをエラー処理から分離できることです。チェックを続ける必要はありません。例外がスローされなければ成功です。

try 
{
    CallMethod();
    CallAnotherMethod();
    NotAgain();
}
catch (Exception e)
{
    handleError();
}

同時に、結果を返すことで、クライアントにより多くの責任を負わせることになります。結果オブジェクトのエラーをチェックすることはよく知られているかもしれませんが、John Doe が入ってきて、例外がスローされないために何か問題があることに気づかずにサービスを呼び出し始めます。これは、例外のもう 1 つの大きな強みであり、何か問題があり、対処する必要がある場合に、顔を平手打ちできることです。

于 2012-09-25T05:39:43.657 に答える
0

これを回避するには、FaultContract および FaultException オブジェクトを使用することを真剣に検討します。これにより、意味のあるエラー メッセージをクライアントに返すことができますが、障害状態が発生した場合に限られます。

残念ながら、私は現在トレーニング コースに参加しているので、完全な回答を書くことはできませんが、運が良ければ、WCF アプリケーションでの例外管理について学んでいます。詳細については、今夜また投稿します。(微妙な回答ですみません)

于 2008-09-17T09:13:39.777 に答える