4

我正在使用 ServiceStack 创建一个接受来自 HTML 表单(已发布)的请求的服务。DTO 属性之一是 Enum,当输入与 Enum 成员不匹配时,出现以下异常:

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 {}
}

另一种选择是从请求 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 将它们视为一组受限制的值,这在尝试迭代地发展 Web 服务时会很痛苦,因为你需要重新生成客户端以添加新值。

按照惯例,我处理它的方式是将所有枚举作为字符串,但在 DTO 上提供一些指向目标类型的元数据(这有助于 VS.NET/R# 导航和元数据工具)。

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