我使用以下[WebGet(UriTemplate = "/foo?id={Id}&flags={flags}&filter={filter}", ResponseFormat = WebMessageFormat.Xml, BodyStyle = WebMessageBodyStyle.Wrapped)]
[OperationContract]
DataTable GetFoo(string id, FlaggedEnum flags, SomeClass filter = null);
FlaggedEnum
DataContract
已被标记为[DataContract]
[Flags]
public enum FlaggedEnum
{
[EnumMember]
Book = 1,
[EnumMember]
Product = 2,
[EnumMember]
TenorGroup = 4,
[EnumMember]
Tenor = 8,
[EnumMember]
Trade = 16
}
成员
Unit player = Unit("something",100,1);
我已阅读Can I pass non-string to WCF RESTful service using UriTemplate?,但在将枚举移至查询部分后,它仍然无法正常工作。我错过了什么?
错误消息: 合同中的GetFoo操作' IFooProvider'有一个名为' flags'的路径变量。没有类型'字符串'。 UriTemplate路径段的变量必须具有类型'字符串'
对于第3个参数(传递类),是否只能通过使用自定义QueryStringConverter来实现?
答案 0 :(得分:2)
枚举在查询字符串中工作正常。对于自定义类,是的,您需要使用查询字符串转换器。下面的代码显示了它的一个例子。
如果您在查询字符串中使用枚举时仍然遇到问题,请提供显示问题的Short, Self-Contained, Compilable Example,我们应该可以提供帮助。
public class StackOverflow_31184719
{
[ServiceContract]
public interface ITest
{
[WebGet(UriTemplate = "/foo?id={Id}&flags={flags}&filter={filter}", ResponseFormat = WebMessageFormat.Xml, BodyStyle = WebMessageBodyStyle.Wrapped)]
[OperationContract]
string GetFoo(string id, FlaggedEnum flags, SomeClass filter = null);
}
[Flags]
public enum FlaggedEnum
{
[EnumMember]
Book = 1,
[EnumMember]
Product = 2,
[EnumMember]
TenorGroup = 4,
[EnumMember]
Tenor = 8,
[EnumMember]
Trade = 16
}
public class SomeClass
{
public string SomeProperty { get; set; }
}
public class MyWebHttpBehavior : WebHttpBehavior
{
protected override QueryStringConverter GetQueryStringConverter(OperationDescription operationDescription)
{
return new MyConverter(base.GetQueryStringConverter(operationDescription));
}
class MyConverter : QueryStringConverter
{
QueryStringConverter inner;
public MyConverter(QueryStringConverter inner)
{
this.inner = inner;
}
public override bool CanConvert(Type type)
{
return type == typeof(SomeClass) || this.inner.CanConvert(type);
}
public override object ConvertStringToValue(string parameter, Type parameterType)
{
if (parameterType == typeof(SomeClass))
{
return new SomeClass { SomeProperty = parameter };
}
else
{
return base.ConvertStringToValue(parameter, parameterType);
}
}
}
}
public class Service : ITest
{
public string GetFoo(string id, FlaggedEnum flags, SomeClass filter = null)
{
return string.Format("{0} - {1} - {2}", id, flags, filter == null ? "<<NULL>>" : filter.SomeProperty);
}
}
public static void Main()
{
string baseAddress = "http://" + Environment.MachineName + ":8000/Service";
ServiceHost host = new ServiceHost(typeof(Service), new Uri(baseAddress));
ServiceEndpoint endpoint = host.AddServiceEndpoint(typeof(ITest), new WebHttpBinding(), "");
endpoint.Behaviors.Add(new MyWebHttpBehavior());
host.Open();
Console.WriteLine("Host opened");
WebClient c = new WebClient();
Console.WriteLine(c.DownloadString(baseAddress + "/foo?id=MyId&flags=Book,Product&filter=MyFilter"));
Console.Write("Press ENTER to close the host");
Console.ReadLine();
host.Close();
}
}