WCF サービスが、無効な値 (Enum 型に存在しない int) を持つ列挙型メンバーを持つ DataContract を返すシナリオでは、クライアント側でスローされる例外The underlying connection was closed: The connection was closed unexpectedly.
が発生します。接続のサーバー側。
サーバーサイドでの実行時に、もっと便利で重要なものを投げてもらいたいのですが、おそらくコンパイラの警告...
WCF サービス コントラクト
[ServiceContract]
public interface IDtoService
{
[OperationContract]
MyDto GetData(int value);
}
public enum Rating
{
None = 0,
NotSet = 1,
Somevalue = 34
}
[DataContract]
public class MyDto
{
Rating _rate;
[DataMember]
public Rating Rating
{
get { return _rate; }
set
{
_rate = value;
}
}
}
サービスの実装
public class DtoService : IDtoService
{
public MyDto GetData(int value)
{
var dto = new MyDto { Rating = (Rating) 42 }; // not in ENUM!
return dto;
}
}
クライアント
var cl = new DtoServiceClient.DtoServiceClient();
var tada = cl.GetData(1); // connection closed exception
実際の例外をスローするには、VS2010 のデバッグ オプションで [自分のコードのみを有効にする] を無効にし、[例外] ダイアログで [共通言語ランタイムの例外] のスローを有効にする必要がありました。
その設定では、貴重な例外は次のとおりです。
SerializationException
Enum 値 '42' はタイプ 'WcfService1.Rating' に対して無効であり、シリアル化できません。型に DataContractAttribute 属性がある場合は、必要な列挙値が存在し、EnumMemberAttribute 属性でマークされていることを確認します
これには、デバッガーがスローされた他のすべての種類の例外について非常にうるさくなり、AFAIK を無視できるという犠牲が伴います。
ノイズなしでこの例外をスローするにはどうすればよいですか?
WCF パイプラインで微調整または追加できるものはありますか?
手直しのコストで早期に失敗する可能性のある解決策の 1 つは、enum メンバーのセッターに追加の Assert を追加することです。
Debug.Assert(Enum.IsDefined(typeof(Rating), value),"value is not valid for this enum");
私が試した別の方法は、警告が生成されることを期待して契約を追加することでした。基本的に Debug.Assert のコピーよりも優れたものは見つかりませんでした。
System.Diagnostics.Contracts.Contract.Assert(Enum.IsDefined(typeof(Rating), value));
コンパイラにこのチェックを発行させるオプションはありますか、それとも私が知らない代替手段はありますか? (成功することを期待せずに有効にし
てコンパイルしようとしました)check for arithmetic overflow/underflow
CodeContracts は警告を発します (Implicit Enum 書き込み義務を有効にする必要があります) が、それは実際には役に立ちません
実際の値は、この列挙値に対して定義された範囲内にない可能性があります
この動作は、VS2010/.Net 4.0 コンテキストにあります。