简体   繁体   English

更改 System.Uri 的方案

[英]Changing the scheme of System.Uri

I'm looking for canonical way of changing scheme of a given System.Uri instance with System.UriBuilder without crappy string manipulations and magic constants.我正在寻找使用System.UriBuilder更改给定System.Uri实例方案的规范方法,而无需糟糕的字符串操作和魔术常量。 Say I have说我有

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

and I need to change it to ' https '.我需要将其更改为“ https ”。 My issue is in limited UriBuilder ctors and Uri.Port defaulting to 80 (should we change it to 443? hardcoding?).我的问题是有限的UriBuilderUri.Port默认为 80(我们应该将其更改为 443?硬编码?)。 The code must respect all Uri properties such as possible basic auth credentials, query string, etc.代码必须遵守所有Uri属性,例如可能的基本身份验证凭据、查询字符串等。

Ended up with this one:结束了这个:

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

UserControl's answer works fine unless you have to make sure non-default ports are preserved in the URI.除非您必须确保在 URI 中保留非默认端口,否则UserControl 的答案可以正常工作。

For instance, http://localhost:12345/hello should become https://localhost:12345/hello instead of https://localhost/hello .例如, http://localhost:12345/hello应该变成https://localhost:12345/hello而不是https://localhost/hello

Here's how to do that easily:以下是如何轻松做到这一点:

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();
}

Note that we have to read uri.Uri.IsDefaultPort before setting uri.Scheme .请注意,我们要读uri.Uri.IsDefaultPort设置之前uri.Scheme

Here is a working example: https://dotnetfiddle.net/pDrF7s这是一个工作示例: https : //dotnetfiddle.net/pDrF7s

Another iteration on Good Night Nerd Pride's answer, as an extension:晚安书呆子骄傲的答案的另一个迭代,作为扩展:

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;
}

I prefer to pass the desired https port number into the ForceHttps method if you want to use a custom one otherwise omit the https port or use -1 to use the standard one (implicitly).如果您想使用自定义端口号,我更喜欢将所需的 https 端口号传递给 ForceHttps 方法,否则省略 https 端口号或使用 -1 来使用标准端口号(隐式)。 I don't really bother with the port that is already on the url because http and https can never use the same port on the same server.我并不真正关心 url 上已经存在的端口,因为 http 和 https 永远不能在同一台服务器上使用相同的端口。

In the event that the url is already https, it will pass through unchanged leaving whatever port is there in place.如果 url 已经是 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;
}

Usage:用法:

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/

Another iteration on Nick Evans answer: Nick Evans的另一次迭代回答:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM