0

在开发我最初的MonoTouch iOS 应用程序时,我尝试使用 System.Uri 实例从私有 Web 服务下载受保护的资源,但由于所有实例总是返回未转义的 URL,因此在检查其签名时我的请求失败。

一个好的请求的例子:

http://example.com/folder%2Ftest?signature=000%3D

错误请求的示例:

http://example.com/folder/test?signature=000=

为了正确下载我的资源,我需要将一个好的 URL 从一个简单的字符串转换为一个好的 Uri 实例。我刚刚开始了这个过程,但我无法得出结论:

string urlStringVersion = "http://example.com/folder%2Ftest?signature=000%3D";
//
// urlStringVersion == http://example.com/folder%2Ftest?signature=000%3D

Uri urlUriVersion = new Uri (urlStringVersion);
//
// urlUriVersion == http://example.com/folder/test?signature=000=

var fi = typeof (Uri).GetField ("host", BindingFlags.NonPublic | BindingFlags.Instance);
fi.SetValue (urlUriVersion, "example.com");
//
// urlUriVersion.AbsoluteUri is now == http://example.com/folder/test?signature=000%3D

<Another C# command here>

//
// urlUriVersion.AbsoluteUri is now == http://example.com/folder%2Ftest?signature=000%3D

最后,为了让我的最终urlUriVersion.AbsoluteUri指向相同的初始urlStringVersion描述的 URL ,我可以使用哪个命令来替换此处的另一个 C# 命令?

我需要这种转换工作,否则我将被迫在我的私人网络服务上公开我的资源。

我还测试了一些替代方案:

  1. 来自其他问题,例如:GETting a URL with an url-encoded slash但发生了一些异常:

    System.NullReferenceException:对象引用未设置为对象的实例

  2. 使用配置文件,但在这种情况下,由于移动设备在技术上没有应用程序域,因此它们不可用。

  3. 通过用编码的百分号替换百分号来对 URL 进行双重编码(因此 '%' 变为 '%25')。

我的尝试都没有解决我的问题。

提前致谢,

皮瓦

4

1 回答 1

1

您正在使用的Uri 构造函数采用未转义的 url 字符串,而不是转义的 url 字符串。

在创建 Uri 实例之前尝试取消转义url 字符串:

string urlStringVersion = "http://example.com/folder%2Ftest?signature=000%3D";
urlStringVersion = Uri.UnescapeDataString (urlStringVersion);

Uri urlUriVersion = new Uri (urlStringVersion);

如果要将 Uri 转换为(未)转义的字符串,请使用GetComponents方法:

var unescaped = urlUriVersion.GetComponents (UriComponents.HttpRequestUri, UriFormat.Unescaped);
var escaped = urlUriVersion.GetComponents (UriComponents.HttpRequestUri, UriFormat.UriEscaped);

不要更改私有字段的值,这势必有一天会破坏您的应用程序。您正在规避 Uri 类的每一个测试(您正在以一种非设计的方式使用该类,也未经过测试),此外,实现可能随时更改。

于 2012-11-16T12:33:35.090 回答