使用自定义WCF 4.5 WebHttpBehavior

本文关键字:WebHttpBehavior WCF 自定义 | 更新日期: 2023-09-27 18:06:33

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

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

我们坚持使用WCF是为了同时提供REST和SOAP端点,所以在这里不可能转向Web API。

使用自定义WCF 4.5 WebHttpBehavior

我已经开始沿着实现自己的UriTemplate解析/匹配逻辑的道路前进,但是后来我偶然发现了这个答案(使用自定义WCF Body反序列化而不更改URI模板反序列化),并发现它做了更多。

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

问题可能只是这个例子有点过时了。而且,实现类NewtonsoftJsonBehavior显式地覆盖并抛出Validate(ServiceEndpoint endpoint)方法中的InvalidOperationException

使用Carlos的例子,删除验证:
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);
    //}
}

添加UriTemplateGetPerson或其他方法:

[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": [
{...},
{...}
}