【问题标题】:Passing Enum & Custom Classes to WCF RESTful service using UriTemplate使用 UriTemplate 将枚举和自定义类传递给 WCF RESTful 服务
【发布时间】:2015-07-02 12:29:13
【问题描述】:

我使用以下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”的路径变量,它没有“字符串”类型。 UriTemplate 路径段的变量必须具有“字符串”类型

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

【问题讨论】:

    标签: c# web-services wcf rest enums


    【解决方案1】:

    枚举在查询字符串中工作正常。对于自定义类,是的,您需要使用查询字符串转换器。下面的代码显示了它的一个示例是如何工作的。

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

    【讨论】:

    • 感谢您提供课程示例。确实它可以默认进行枚举转换,似乎我的项目没有正确重建
    猜你喜欢
    • 2010-10-07
    • 1970-01-01
    • 1970-01-01
    • 2021-12-06
    • 2013-07-24
    • 1970-01-01
    • 1970-01-01
    • 2012-07-03
    • 1970-01-01
    相关资源
    最近更新 更多