c# - 使用 UriTemplate 将枚举和自定义类传递给 WCF RESTful 服务

标签 c# web-services wcf rest enums

我使用以下OperationContract创建了一个WCF服务

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

我已阅读Can I pass non-string to WCF RESTful service using UriTemplate? ,但不知怎的,在枚举移动到查询部分后它仍然不起作用。我错过了什么?

错误消息: 合约“IFooProvider”中的操作 GetFoo 有一个名为“flags”的路径变量,该变量没有“string”类型。 UriTemplate 路径段的变量必须具有“字符串”类型

对于第三个参数(传递一个类),是否只能通过使用自定义QueryStringConverter来实现?

最佳答案

枚举在查询字符串中工作得很好。对于自定义类,是的,您需要使用查询字符串转换器。下面的代码展示了它的工作原理的一个示例。

如果您在查询字符串中使用枚举时仍然遇到问题,请提供 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();
    }
}

关于c# - 使用 UriTemplate 将枚举和自定义类传递给 WCF RESTful 服务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31184719/

相关文章:

c# - 在 C# 中丢失与 sql server 2008 的连接

c# - 无法在 iis 上托管 ASMX Web 服务

托管在 IIS6 上的 WCF

android - 制作动态表格(最佳方法)

c# - 工作流基础 4.5 InstanceLockedException

wcf - Azure REST PUT 或 DELETE 返回 401

c# - 访问整个项目中的模型变量 MVC5 Razor - 使用 Basecontroller 设置 BaseViewModel 并在 Layout 中使用它

c# - 从 MEF 插件读取 AppSettings

c# - 如何测试我的 Linq IQueryable 是否已执行

web-services - 服务发现与负载均衡