4

ServiceStackを使用して、HTMLフォーム(POSTed)からのリクエストを受け入れるサービスを作成しています。DTOプロパティの1つは列挙型であり、入力が列挙型メンバーと一致しない場合、次の例外が発生します。

Error occured while Processing Request: KeyValueDataContractDeserializer: Error converting to type: Requested value 'MyValue' was not found.
System.Runtime.Serialization.SerializationException: KeyValueDataContractDeserializer: Error converting to type: Requested value 'MyValue' was not found. ---> System.ArgumentException: Requested value 'MyValue' was not found.
   at System.Enum.TryParseEnum(Type enumType, String value, Boolean ignoreCase, EnumResult& parseResult)
   at System.Enum.Parse(Type enumType, String value, Boolean ignoreCase)
   at ServiceStack.ServiceModel.Serialization.StringMapTypeDeserializer.PopulateFromMap(Object instance, IDictionary`2 keyValuePairs) 

この例外をインターセプトして、サービスコードで自分で処理するにはどうすればよいですか?

4

1 に答える 1

3

この状況を処理するには、いくつかの方法があります。

DTO Enumプロパティを文字列にして(すべてが正常に文字列に逆シリアル化できるため:)、それを手動で変換できます。

using ServiceStack.Common; //ToEnum<> is an extension method

public class RequestDto
{
    public string EnumString { get; set; } 
}

public override object OnGet(RequestDto request)
{
    MyEnum defaultValue = MyEnum.None;
    try {
        defaultValue = request.EnumString.ToEnum<MyEnum>();
    } catch {}
}

もう1つの方法は、リクエストDTOから完全に削除し、次のようにIHttpRequestコンテキストから手動で値を取得することです。

public class RequestDto {}
public override object OnGet(RequestDto request)
{
    MyEnum enumValue = MyEnum.DefaultValue;
    try {
        var enumStr = base.RequestContext.Get<IHttpRequest>().QueryString["EnumString"];
        enumValue = enumStr.ToEnum<MyEnum>();
    } catch {}
}

私は一般的に多くの理由でDTOで列挙型を使用することをお勧めしません。主なものはXML/SOAPエンドポイントであり、XSDはそれらを制限された値のセットとして扱います。クライアントを再生成して、新しい値を追加します。

慣例により、私が扱う方法は、すべての列挙型を文字列として持つことですが、ターゲットタイプを指すDTO上のメタデータを提供します(これは、VS.NET / R#ナビゲーションおよびメタデータツールで役立ちます)。

public class RequestDto
{
    [References(typeof(MyEnum))]
    public string EnumString { get; set; } 
}
于 2011-11-18T01:31:09.220 に答える