我已经完成了这个键盘的敲击工作。
我有一个 WCF 客户端项目,可用于访问 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
也会转换回正斜杠 ( /
)。结果,像这样"Saint Augustine Tunapuna/Piarco, Trinidad and Tobago"
的搜索(可以理解)被雅虎服务器以 400 Bad Request 拒绝。
最糟糕的是,这似乎只在客户端库用作非 Visual Studio 项目参考时才会发生。我在项目中有以下测试,始终通过:
[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);
}
}
当我在另一个项目中使用这个库时,它仅在客户端 .csproj 是另一个项目的解决方案的一部分时才有效,并且作为项目引用被引用。一旦我将它作为 NuGet 包或直接 dll 文件引用包含在内,它就会失败。
我已经进入了代码,看起来 URL 在传递给Channel
. 然而,在那之后的某个时候,%2F
搜索字符串中的 被转换回正斜杠。我知道这一点的唯一原因是检查提琴手中的请求。