【问题标题】:UriTemplates with a Custom WCF 4.5 WebHttpBehavior具有自定义 WCF 4.5 WebHttpBehavior 的 UriTemplates
【发布时间】:2014-07-23 03:15:03
【问题描述】:

我正在实现自定义 WCF REST 行为,它实现/覆盖基本 WebHttpBehavior,但允许使用自定义序列化程序进行 REST 通信。代码基于 Carlos 的工作here

我已经让它运行了,但问题是我们真的很想使用 UriTemplate 功能来允许真正的 REST-ful URI。有没有人看到这样做或可以提供帮助以找到正确的实现?

我们坚持使用 WCF 是为了同时提供 REST 和 SOAP 端点,因此这里不能选择迁移到 Web API。

【问题讨论】:

  • 您如何托管您的 WCF 服务?你用的是什么绑定?
  • 我们通过代码使用服务激活通过 IIS 托管。我们有一个自定义 REST 和 SOAP 服务主机工厂设置,让我们可以更改行为、绑定等,然后使用标准 WCF 路由服务激活来使用 REST 和 SOAP 工厂加载每个服务。
  • 嘿@Paul,问题是我不知道如何重新实现 UriTemplate 功能。我们已经覆盖了基本的 WebHttpBehavior 以添加额外的功能,但这导致我们失去了包括执行 UriTemplate 路由能力的基本功能。如果您查看我们链接到的 Carlos 的文章,他甚至表示他们没有将其包含在示例中,因为它太难了。我正在寻找如何在我们重写的方法/类中执行此操作的参考或示例。
  • @BrentPabst 来自 Carlos 的“博客”...“在新的 WCF Web API(您可以在 Codeplex 网站上预览这些位)中,实现这样的场景要简单得多,而且其他功能(例如 UriTemplate) 将在插入新格式化程序后继续工作。"...你读过wcf.codeplex.com/discussions/255873 吗?

标签: c# .net wcf rest uritemplate


【解决方案1】:

我已经开始着手实现我自己的UriTemplate 解析/匹配逻辑,但后来我偶然发现了这个答案 (Using Custom WCF Body Deserialization without changing URI Template Deserialization),并发现它确实做到了这一点,甚至更多。

为了使用它,您仍然必须取消注释与验证 UriTemplate 未使用相关的代码。最后,为了我的目的,我还重新格式化了代码(取出逻辑来检查是否有多个参数,因为在我的用例中,主体总是恰好是一个参数)。

【讨论】:

    【解决方案2】:

    问题可能只是示例有点过时。此外,实现类NewtonsoftJsonBehavior 显式覆盖并在Validate(ServiceEndpoint endpoint) 方法中抛出InvalidOperationException

    使用Carlos' example,删除验证:

    public override void Validate(ServiceEndpoint endpoint)
    {
        base.Validate(endpoint);
    
        //TODO: Stop throwing exception for default behavior.
        //BindingElementCollection elements = endpoint.Binding.CreateBindingElements();
        //WebMessageEncodingBindingElement webEncoder = elements.Find<WebMessageEncodingBindingElement>();
        //if (webEncoder == null)
        //{
        //    throw new InvalidOperationException("This behavior must be used in an endpoint with the WebHttpBinding (or a custom binding with the WebMessageEncodingBindingElement).");
        //}
    
        //foreach (OperationDescription operation in endpoint.Contract.Operations)
        //{
        //    this.ValidateOperation(operation);
        //}
    }
    

    UriTemplate 添加到GetPerson 或其他方法:

    [WebGet, OperationContract]
    Person GetPerson();
    
    [WebGet(UriTemplate="GetPersonByName?l={lastName}"), OperationContract(Name="GetPersonByName")]
    Person GetPerson(string lastName);
    

    Service 类中,添加一个简单的实现来验证参数是否被解析:

    public Person GetPerson(string lastName)
    {
        return new Person
        {
            FirstName = "First",
            LastName = lastName, // Return the argument.
            BirthDate = new DateTime(1993, 4, 17, 2, 51, 37, 47, DateTimeKind.Local),
            Id = 0,
            Pets = new List<Pet>
            {
                new Pet { Name= "Generic Pet 1", Color = "Beige", Id = 0, Markings = "Some markings" },
                new Pet { Name= "Generic Pet 2", Color = "Gold", Id = 0, Markings = "Other markings" },
            },
        };
    }
    

    Program.Main() 方法中,对这个新 URL 的调用将解析并返回我的查询字符串值,而无需任何自定义实现:

    [Request]
    SendRequest(baseAddress + "/json/GetPersonByName?l=smith", "GET", null, null);
    
    [Response]
    {
    "FirstName": "First",
    "LastName": "smith",
    "BirthDate": "1993-04-17T02:51:37.047-04:00",
    "Pets": [
    {...},
    {...}
    }
    

    【讨论】:

    • 如果 body 被实际传入,这将不起作用,例如在 POST 或 PUT 中。
    猜你喜欢
    • 1970-01-01
    • 2013-08-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-09
    • 2011-09-05
    • 1970-01-01
    • 2011-11-26
    相关资源
    最近更新 更多