読者です 読者をやめる 読者になる 読者になる

列挙体のメンバを持つクラスを返す WCF サービスを Windows Azureで動かしたらハマった

.net

次のような列挙体とクラスがあるとします。

public enum ProductType
{
    Normal = 1,
    Demo,
    Support,
}

[DataContract]
public class Product
{
    [DataMember]
    public int Id { get;set; }
    [DataMember]
    public string Name { get;set; }
    [DataMember]
    public ProductType Type { get;set; }
}

そして、下記のように、プロパティに列挙体の範囲外の値を設定したオブジェクトを WCF サービスからクライアントに返します。

[ServiceContract]
public interface IProductService
{
    [OperationContract]
    Product GetProduct(int id);
}

public class ProductService : IProductService
{
    public Product GetProduct(int id)
    {
        return new Product()
        {
            Id = id,
            Name = "Test",
            Type = (ProductType)0,
        };
    }
}

このサービスを Windows Azure で動かすと、WCF サービスが返した結果をクライアント側でシリアル化解除しようとして、列挙体の値が範囲外のためエラーが発生します。


この問題は、Windows Azure 本番環境 と DevelopmentFabric で発生しました。Windows Azure 本番環境では次のメッセージが表示されました。

(WCFサービスのエンドポイントアドレス)のHTTPサービスがビジー状態です。リモートサーバーがエラーを返しました:(503)サーバーを使用できません。

一方、DevelopmentFabric では次のメッセージに変わりました。

基礎になる接続が閉じられました。接続が予期せずに閉じられました。

また、ASP.NET開発サーバーでデバッグしたときは発生しませんでした。WCF の動きが微妙に違う…?


例外メッセージのせいで、てっきり WCF サービスの構成に原因があると思っていました。実際は、WCF サービスが返すデータが不正だったというのに。見当違いの箇所を調査して、だいぶ遠回りしてしまいましたよ…。


例外を発生させるとき、適切な型やメッセージを選ぶことは重要ですね。すご〜く身にしみました。