改变System.Uri的方案

时间:2013-07-31 10:54:57

标签: c# .net url uri

我正在寻找使用System.Uri更改给定System.UriBuilder实例的方案的规范方法,而不需要糟糕的字符串操作和魔术常量。说我有

var uri = new Uri("http://localhost/hello")

我需要将其更改为“ https ”。我的问题是有限的UriBuilder ctors和Uri.Port默认为80(我们应该将其更改为443?硬编码?)。代码必须遵守所有Uri属性,例如可能的基本身份验证凭据,查询字符串等。

5 个答案:

答案 0 :(得分:82)

结束这一次:

var uriBuilder = new UriBuilder(requestUrl)
{
    Scheme = Uri.UriSchemeHttps,
    Port = -1 // default port for scheme
};

答案 1 :(得分:25)

UserControl's answer正常工作,除非你必须确保在URI中保留非默认端口。

例如,http://localhost:12345/hello应该变为https://localhost:12345/hello而不是https://localhost/hello

以下是如何轻松完成这项工作:

public static string ForceHttps(string requestUrl)
{
    var uri = new UriBuilder(requestUrl);

    var hadDefaultPort = uri.Uri.IsDefaultPort;
    uri.Scheme = Uri.UriSchemeHttps;
    uri.Port = hadDefaultPort ? -1 : uri.Port;

    return uri.ToString();
}

请注意,我们必须在设置uri.Uri.IsDefaultPort之前阅读uri.Scheme

以下是一个工作示例:https://dotnetfiddle.net/pDrF7s

答案 2 :(得分:2)

如果您要使用自定义的端口号,我更希望将所需的https端口号传递到ForceHttps方法中;否则,请省略https端口或使用-1(默认)使用标准端口号。我真的不会打扰URL上已经存在的端口,因为http和https永远不能在同一服务器上使用同一端口。

如果该网址已经是https,则它将通过原样通过,而无需考虑任何端口。

private static string ForceHttps(string requestUrl, int? httpsPort = null)
{
    var uri = new UriBuilder(requestUrl);
    // Handle https: let the httpsPort value override existing port if specified
    if (uri.Uri.Scheme.Equals(Uri.UriSchemeHttps)) {
        if (httpsPort.HasValue)
            uri.Port = httpsPort.Value;
        return uri.Uri.AbsoluteUri;
    }

    // Handle http: override the scheme and use either the specified https port or the default https port
    uri.Scheme = Uri.UriSchemeHttps;
    uri.Port = httpsPort.HasValue ? httpsPort.Value : -1;

    return uri.Uri.AbsoluteUri;
}

用法:

ForceHttps("http://www.google.com/"); // https://www.google.com/
ForceHttps("http://www.google.com/", 225); // https://www.google.com:225/
ForceHttps("http://www.google.com/", 443); // https://www.google.com:443/
ForceHttps("https://www.google.com/"); // https://www.google.com/
ForceHttps("https://www.google.com:443/"); // https://www.google.com:443/
ForceHttps("https://www.google.com:443/", -1); // https://www.google.com/
ForceHttps("http://www.google.com:80/"); // https://www.google.com/
ForceHttps("http://www.google.com:3000/", 8080); // https://www.google.com:8080/

答案 3 :(得分:2)

《晚安书呆子的骄傲》回答的另一个扩展,作为扩展:

public static Uri RewriteHttps(this Uri originalUri)
{
    return new UriBuilder(originalUri)
    {
        Scheme = Uri.UriSchemeHttps,
        Port = originalUri.IsDefaultPort ? -1 : originalUri.Port // -1 => default port for scheme
    }.Uri;
}

答案 4 :(得分:0)

关于尼克·埃文斯的另一遍回答:

public static Uri UseHttps(this Uri uri, int httpsPort = -1)
{
    return new UriBuilder(uri) { Scheme = Uri.UriSchemeHttps, Port = httpsPort }.Uri;
}