具有自定义 WCF 4.5 WebHttpBehavior 的 UriTemplates

Posted

技术标签:

【中文标题】具有自定义 WCF 4.5 WebHttpBehavior 的 UriTemplates【英文标题】:UriTemplates with a Custom WCF 4.5 WebHttpBehavior 【发布时间】: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 工厂加载每个服务。 那么你的问题到底是什么? msdn.microsoft.com/en-us/library/bb675245%28v=vs.110%29.aspx 嘿@Paul,问题是我不知道如何重新实现 UriTemplate 功能。我们已经覆盖了基本的 WebHttpBehavior 以添加额外的功能,但这导致我们失去了包括执行 UriTemplate 路由能力的基本功能。如果您查看我们链接到的 Carlos 的文章,他甚至表示他们没有将其包含在示例中,因为它太难了。我正在寻找如何在我们重写的方法/类中执行此操作的参考或示例。 @BrentPabst 来自 Carlos 的“博客”...“在新的 WCF Web API(您可以在 Codeplex 网站上预览这些位)中,实现这样的场景要简单得多,而且其他功能(例如 UriTemplate) 将在插入新格式化程序后继续工作。"...你读过wcf.codeplex.com/discussions/255873 吗? 【参考方案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 中。

以上是关于具有自定义 WCF 4.5 WebHttpBehavior 的 UriTemplates的主要内容,如果未能解决你的问题,请参考以下文章

如何让 gzip 压缩在 WCF 4.5 中工作

具有 basicHttpBinding、传输安全性和基本客户端凭据类型的自定义 WCF 凭据验证器

WCF 服务中的自定义证书验证

.net 4.5 Controller:参数polymorphism和自定义Json反序列化

如何在 WCF 服务中实现自定义身份验证

为啥找不到我的自定义 WCF 行为扩展元素类型?