如何建立网址?


72

.NET中是否有可用的帮助程序类允许我构建一个Url?

例如,如果用户输入一个字符串:

stackoverflow.com

我试图传递到HttpWebRequest

WebRequest.CreateHttp(url);

它将失败,因为它不是有效的url(没有前缀)。

我想要的是能够解析用户输入的部分URL:

Uri uri = new Uri(url);

然后修复丢失的部分:

if (uri.Port == 0)
   uri.Port = 3333;
if (uri.Scheme == "")
   uri.Scheme = "https";

.NET是否有任何可用于解析和操纵Uri的类?

UriBuilder类无法完成工作

用户输入的值(例如stackoverflow.com:3333)有效;我只需要一堂课就可以把它分开。我尝试使用UriBuilder该类:

UriBuilder uriBuilder = new UriBuilder("stackoverflow.com:3333");

不幸的是,UriBuilder类无法处理URI:

  • uriBuilder.Path = 3333
  • uriBuilder.Port = -1
  • uriBuidler.Scheme = stackoverflow.com

因此,我需要一个可以理解的课程,host:port不是特别http重要但可能会特别重要时,这一点尤其重要。

奖金Chat不休

控制台应用程序。

从另一个问题

需要解析的URL的一些示例:

  • server:8088
  • server:8088/func1
  • server:8088/func1/SubFunc1
  • http://server
  • http://server/func1
  • http://server/func/SubFunc1
  • http://server:8088
  • http://server:8088/func1
  • http://server:8088/func1/SubFunc1
  • magnet://server
  • magnet://server/func1
  • magnet://server/func/SubFunc1
  • magnet://server:8088
  • magnet://server:8088/func1
  • magnet://server:8088/func1/SubFunc1
  • http://[2001:db8::1]
  • http://[2001:db8::1]:80

网址的格式为:

  foo://example.com:8042/over/there?name=ferret#nose
  \_/   \_________/ \__/\_________/\__________/ \__/
   |         |        |     |           |        |
scheme      host    port   path       query   fragment

奖金Chat不休

再次指出,UriBuilder不起作用:


看起来可以UriBuilder正确处理-stackoverflow.com:3333是带有schemestackoverflow.com和path的URI 3333。如果您希望以其他方式解析某些内容,则必须指定您希望行为如何有所不同。您可能只是可以假设一个未知的方案是主机名,或者编写自己的UriParser

问题在于该方案不是stackoverflow.com。只需询问Lynx,Netscape Navigator,Internet Explorer,FireFox,Chrome,Edge和生活水平。他们都意识到那stackoverflow.com是主人。我希望每个实用的实际解析器都能够理解Uri解析器。如果您建议我写我自己的书,那很好-在我问该怎么做的地方看到这个问题。理想情况下,该类已经存在于FCL中。
伊恩·博伊德

Answers:


71

如果需要确保作为用户输入输入的某些字符串是有效的url,则可以使用以下Uri.TryCreate方法:

Uri uri;
string someUrl = ...
if (!Uri.TryCreate(someUrl, UriKind.Absolute, out uri))
{
    // the someUrl string did not contain a valid url 
    // inform your users about that
}
else
{
    var request = WebRequest.Create(uri);
    // ... safely proceed with executing the request
}

现在,如果您想在.NET中构建url,则有UriBuilder专门为此目的设计的类。让我们举个例子。假设你想建立以下网址:http://example.com/path?foo=bar&baz=bazinga#some_fragment其中barbazinga值来自用户:

string foo = ... coming from user input
string baz = ... coming from user input

var uriBuilder = new UriBuilder("http://example.com/path");
var parameters = HttpUtility.ParseQueryString(string.Empty);
parameters["foo"] = foo;
parameters["baz"] = baz;
uriBuilder.Query = parameters.ToString();
uriBuilder.Fragment = "some_fragment";

Uri finalUrl = uriBuilder.Uri;
var request = WebRequest.Create(finalUrl);
... safely proceed with executing the request

2
HttpUtility.ParseQueryString是获取HttpValueCollection内部的一个偷偷摸摸的方法(这就是为什么它如此.ToString()工作的原因)。不确定使用内部框架类并依靠其未记录的行为是一个好主意。信贷对于这个认识去codereview.stackexchange.com/questions/91783/...
杰西Hufstetler

@JesseHufstetler-我认为使用是安全的,因为有关它的MSDN文章没有提到任何警告,并且有用法示例。
bPratik

1
请注意,UriBuilder令人窒息stackoverflow.com:3389
Ian Boyd


4

为了有效,URI需要具有方案组件。“ server:8088”不是有效的URI。“ http:// server:8088 ”是。参见https://tools.ietf.org/html/rfc3986


1
但是您的Chrome浏览器知道您输入时的意思stackoverflow.com:80。.NET类可以解析URI。
伊恩·博伊德

1
实际上,server:8080是一个完全有效的URI,尽管可能没有人会理解您对服务器方案的含义。
Georg

1
一直以为方案server://不是,server:port但思考基本的理解规则很有趣
ljgww 18-2-26

1
@IanBoyd:有些浏览器只知道最常见的错字是什么,并对其进行调整;-)
Stefan
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.