具有自定义 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的主要内容,如果未能解决你的问题,请参考以下文章
具有 basicHttpBinding、传输安全性和基本客户端凭据类型的自定义 WCF 凭据验证器