【发布时间】:2016-01-22 17:54:20
【问题描述】:
WCF 支持使用带有FlagsAttribute 标记的枚举类型作为UriTemplate 中的参数。像这样:
[DataContract]
[Flags]
public enum OptionsEnum
{
[EnumMember]
None = 0,
[EnumMember]
MyOption1 = 1,
[EnumMember]
MyOption2 = 2,
[EnumMember]
MyOption3 = 4,
[EnumMember]
MyOption4 = 8
}
[ServiceContract]
public interface MyServiceContract
{
[OperationContract]
[WebInvoke(Method = "GET", UriTemplate = "resource?options={options}")]
void MyOperation(OptionsEnum options);
}
然后可以通过如下 URL 请求资源:
GET /resource?options=None
GET /resource?options=MyOption1
GET /resource?options=MyOption1,MyOption3
只要 URL 实际上包含 options 参数的值,所有这些都可以很好地工作。但是,如果我在请求资源时未在 URL 中指定值,如下所示:
GET /resource
我收到一条异常消息 Value cannot be null。\r\nParameter name: value 以及以下堆栈跟踪:
at System.Enum.TryParseEnum(Type enumType, String value, Boolean ignoreCase, EnumResult& parseResult)
at System.Enum.Parse(Type enumType, String value, Boolean ignoreCase)
at System.ServiceModel.Dispatcher.QueryStringConverter.ConvertStringToValue(String parameter, Type parameterType)
at System.ServiceModel.Dispatcher.UriTemplateDispatchFormatter.DeserializeRequest(Message message, Object[] parameters)
at System.ServiceModel.Dispatcher.DispatchOperationRuntime.DeserializeInputs(MessageRpc& rpc)
at System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(MessageRpc& rpc)
at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage5(MessageRpc& rpc)
at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage31(MessageRpc& rpc)
at System.ServiceModel.Dispatcher.MessageRpc.Process(Boolean isOperationContextSet)
显然,这是因为在这种情况下QueryStringConverter 将null 传递到Enum.Parse(...)。因此MyServiceContract的实现将不会被执行。
当然,对于options 参数的类型,我当然可以切换到string,并在服务实现中自己完成所有解析工作,但这并不是我想要的,真的。
如果 URL 不包含值(就像为 int 类型的省略参数传递 0 一样),是否有人知道将 OptionsEnum.None 传递到服务实现的干净解决方案?
我已经尝试过使用自定义的TypeConverter 实现,但即使这样似乎也不起作用。查看QueryStringConverter 的实现,它似乎总是会尝试自行转换enum 类型。
【问题讨论】:
标签: c# web-services wcf rest enums