使用WCF WebGetAttribute的UriTemplate属性的奇怪行为

时间:2013-07-16 18:27:33

标签: wcf url-encoding uritemplate webget

我在键盘上为这个敲打了我的头。

我有a WCF client project可用于点击Yahoo GeoPlanet服务。其中一个自由文本查询端点可以表示如下:

[OperationContract(Name = "places")]
[WebGet(
    UriTemplate = "places.q({query});count=0?format=json&view={view}&appid={appId}",
    RequestFormat = WebMessageFormat.Json,
    ResponseFormat = WebMessageFormat.Json,
    BodyStyle = WebMessageBodyStyle.Bare
)]
PlacesResponse Places(string query, string appId, RequestView view);

有一个实现可以调用WCF客户端(或多或少),如下所示:(这里有重试逻辑,但这就是它归结为)

public Places Places(string query, string appId, RequestView view = RequestView.Long)
{
    return Channel.Places(HttpUtility.UrlEncode(query), appId, view);
}

问题在于,即使query参数是url编码的,在WCF发出实际HTTP请求时,%2F的值也会转换回正斜杠({{1} })。因此,像/这样的搜索(可以理解)被Yahoo服务器拒绝了400 Bad Request。

最糟糕的是,当客户端库被用作非可视工作室项目引用时,似乎只会发生这种情况。我在项目中有以下测试,总是通过:

"Saint Augustine Tunapuna/Piarco, Trinidad and Tobago"

当我在另一个项目中使用此库时,它仅在客户端.csproj是其他项目解决方案的一部分时才有效,并且作为项目引用引用。只要我将它包含为NuGet包或直接dll文件引用,它就会失败。

我已经进入代码,看起来URL在传递给[TestMethod] public void Yahoo_GeoPlanet_GeoPlanetClient_Places_ShouldUrlEncodeQuery_WhenItContainsUnsafeCharacters() { using (var geoPlanetClient = new GeoPlanetClient()) { var places = geoPlanetClient.Places("Saint Augustine Tunapuna/Piarco, Trinidad and Tobago", AppId); places.ShouldNotBeNull(); places.Items.Count.ShouldBeInRange(1, int.MaxValue); } } 时正确编码。但是在此之后的某个时间,搜索字符串中的Channel将被转换回正斜杠。我知道这个的唯一原因是来自fiddler检查请求。

1 个答案:

答案 0 :(得分:0)

也许考虑使用HttpClient?这简直太简单了。