I have a condition in my program where I have to combine a server (e.g. http://server1.my.corp/) that may or may not have an ending slash with a relative path (e.g. /Apps/TestOne/). According to the docs, Uri should...
Canonicalizes the path for hierarchical URIs by compacting sequences such as /./, /../, //,...
So when I do something like var url = new Uri(server + relativePath), I'd expect it to take what would otherwise be http://server1.my.corp//Apps/TestOne/ and remove the double slash (i.e // -> /), but ToString, AbsolutePath and various options still show the redundant/duplicate slash. Am I not using Uri right?
Take a look at the constructors for the Uri class. You need to specify a base Uri and a relative path to get the canonized behavior. Try something like this:
var server = new Uri("http://server1.my.corp/");
var resource = new Uri(server, "/Apps/TestOne/");
Related
How do you properly encode a path that includes a hash (#) in it? Note the hash is not the fragment (bookmark?) indicator but part of the path name.
For example, if there is a path like this:
http://www.contoso.com/code/c#/somecode.cs
It causes problems when you for example try do this:
Uri myUri = new Uri("http://www.contoso.com/code/c#/somecode.cs");
It would seem that it interprets the hash as the fragment indicator.
It feels wrong to manually replace # with %23. Are there other characters that should be replaced?
There are some escaping methods in Uri and HttpUtility but none seem to do the trick.
There are a few characters you are not supposed to use. You can try to work your way through this very dry documentation, or refer to this handy URL summary on Stack Overflow.
If you check out this very website, you'll see that their C# questions are encoded %23.
Stack Overflow C# Questions
You can do this using either (for ASP.NET):
string.Format("http://www.contoso.com/code/{0}/somecode.cs",
Server.UrlEncode("c#")
);
Or for class libraries / desktop:
string.Format("http://www.contoso.com/code/{0}/somecode.cs",
HttpUtility.UrlEncode("c#")
);
Did some more digging friends and found a duplicate question for Java:
HTTP URL Address Encoding in Java
However, the .Net Uri class does not offer the constructor we need, but the UriBuilder does.
So, in order to construct a proper URI where the path contains illegal characters, do this:
// Build Uri by explicitly specifying the constituent parts. This way, the hash is not confused with fragment identifier
UriBuilder uriBuilder = new UriBuilder("http", "www.contoso.com", 80, "/code/c#/somecode.cs");
Debug.WriteLine(uriBuilder.Uri);
// This outputs: http://www.contoso.com/code/c%23/somecode.cs
Notice how it does not unnecessarily escape parts of the URI that does not need escaping (like the :// part) which is the case with HttpUtility.UrlEncode. It would seem that the purpose of this class is actually to encode the querystring/fragment part of the URL - not the scheme or hostname.
Use UrlEncode: System.Web.HttpUtility.UrlEncode(string)
class Program
{
static void Main(string[] args)
{
string url = "http://www.contoso.com/code/c#/somecode.cs";
string enc = HttpUtility.UrlEncode(url);
Console.WriteLine("Original: {0} ... Encoded {1}", url, enc);
Console.ReadLine();
}
}
I'm using constructor:
public Uri(Uri baseUri, string relativeUri)
to append relative paths to an initial Uri.
Usually, everything works OK and the desired path is appended, but, in some cases, the final path is REPLACED.
For example, with this code:
new Uri(new Uri("http://localhost:3000/app/api/publicapi/NAS_0x5d65d971895edc438f465c17db6992698a52318d"), "Blocks")
I expected this result:
http://localhost:3000/app/api/publicapi/NAS_0x5d65d971895edc438f465c17db6992698a52318d/Blocks
But I get:
http://192.168.26.50:3000/app/api/publicapi/Blocks
What's wrong, here?
Missing the final slash so it's treating NAS_0x5d65d971895edc438f465c17db6992698a52318d as a resource not a path:
var existingUri =
new Uri("http://localhost:3000/app/api/publicapi/NAS_0x5d65d971895edc438f465c17db6992698a52318d/");
new Uri(existingUri, "Blocks");
// returns: http://localhost:3000/app/api/publicapi/NAS_0x5d65d971895edc438f465c17db6992698a52318d/Blocks
From docs:
If the baseUri has relative parts (like /api), then the relative part
must be terminated with a slash, (like /api/), if the relative part of
baseUri is to be preserved in the constructed Uri.
I'm trying to create a URI which contains an underscore (it's pointing to a UNC path) like so:
hplLink.NavigateUri = new Uri(String.Format("{0}\\{1}", selectedFolder.LinkTitle, selectedFolder.FolderPath), false);
Unfortuantely this chokes up with the following:
Invalid URI: The format of the URI could not be determined.
I need to essentially create a hyperlink in a WPF application and I am unable to do so on paths containing an underscore.
Any thoughts would be greatly appreciated.
Thanks!
This might sound like a trivial problem but for some reason it is not.
Instead of needing to redirect
Response.Redirect("~/folder1/folder2/some.aspx")
I need the location as if it behaved like
string navigatingUrl = Response.Redirect("~/folder1/folder2/some.aspx")
Trying to replicate this I started with
string navigatingUrl = new Uri(HttpContext.Current.Request.Url,
new Uri("~/folder1/folder2/some.aspx", UriKind.Relative));
This instead generates "http://www.fullRequestUrl/~/folder1/folder2/some.aspx"
Edit: Well I've found out why I absolutely hate the URL API from Microsoft. I wish hellfire to whoever wrote this line of code
else if (uriKind == UriKind.Relative)
{
// Here we know that we can create an absolute Uri, but the user has requested
only a relative one
e = GetException(ParsingError.CannotCreateRelative);
}
What would possess someone to throw an error like that? This single if statement completely destroys the API.
I think you are looking for Control.ResolveUrl(). Typically you would probably use the method found on your Page object (if you are using WebForms).
Stealing from Get absolute url for a file in my asp.net project to include HTTP// etc for use externally? the only absolute way to do this is:
string url = Request.Url.GetLeftPart(UriPartial.Authority)
+ VirtualPathUtility.ToAbsolute(relativePath)
Response.Redirect(Page.ResolveUrl("~/folder1/forlder2/some.aspx"), false);
I have found many examples of how to match particular types of URL-s in PHP and other languages. I need to match any URL from my C# application. How to do this? When I talk about URL I talk about links to any sites or to files on sites and subdirectiories and so on.
I have a text like this: "Go to my awsome website http:\www.google.pl\something\blah\?lang=5" or else and I need to get this link from this message. Links can start only with www. too.
If you need to test your regex to find URLs you can try this resource
http://gskinner.com/RegExr/
It will test your regex while you're writing it.
In C# you can use regex for example as below:
Regex r = new Regex(#"(?<Protocol>\w+):\/\/(?<Domain>[\w#][\w.:#]+)\/?[\w\.?=%&=\-#/$,]*");
// Match the regular expression pattern against a text string.
Match m = r.Match(text);
while (m.Success)
{
//do things with your matching text
m = m.NextMatch();
}
Microsoft has a nice page of some regular expressions...this is what they say (works pretty good too)
^(ht|f)tp(s?)\:\/\/[0-9a-zA-Z]([-.\w]*[0-9a-zA-Z])*(:(0-9)*)*(\/?)([a-zA-Z0-9\-\.\?\,\'\/\\\+&%\$#_]*)?$
http://msdn.microsoft.com/en-us/library/ff650303.aspx#paght000001_commonregularexpressions
I am not sure exactly what you are asking, but a good start would be the Uri class, which will parse the url for you.
Here's one defined for URL's.
^http(s?)\:\/\/[0-9a-zA-Z]([-.\w]*[0-9a-zA-Z])*(:(0-9)*)*(\/?)([a-zA-Z0-9\-\.\?\,\'\/\\\+&%\$#_]*)?$
http://msdn.microsoft.com/en-us/library/ms998267.aspx
Regex regx = new Regex("http(s)?://([\\w+?\\.\\w+])+([a-zA-Z0-9\\~\\!\\#\\#\\$\\%\\^\\&\\*\\(\\)_\\-\\=\\+\\\\\\/\\?\\.\\:\\;\\'\\,]*)?", RegexOptions.IgnoreCase);
This will return a match collection of all matches found within "yourStringThatHasUrlsInIt":
var pattern = #"((ht|f)tp(s?)\:\/\/|~/|/)?([w]{2}([\w\-]+\.)+([\w]{2,5}))(:[\d]{1,5})?";
var regex = new Regex(pattern);
var matches = regex.Matches(yourStringThatHasUrlsInIt);
The return will be a "MatchCollection" which you can read more about here:
http://msdn.microsoft.com/en-us/library/system.text.regularexpressions.matchcollection.aspx
//This code return (protocol://)host:port from URL
//Commented URL's with different protocols. Just uncomment to test.
//string url = "http://www.contoso.com:8080/letters/readme.html";
//string url = "ftp://www.contoso.com:8080/letters/readme.html";
//string url = "l2tp://1.5.8.6:8080/letters/readme.html";
string url = "l2tp://1.5.8.6:8080/letters/readme.html";
string host = "";//empty string with host from url
//protocol, (ip/domain), port
host = Regex.Match(url, #"^(?<proto>\w+)://+?(?<host>[A-Za-z0-9\-\.]+)+?(?<port>:\d+)?/", RegexOptions.None, TimeSpan.FromMilliseconds(150)).Result("${proto}://${host}${port}");
//(ip/domain):port without protocol. If HTTPS board loading images from HTTP host.
//host = Regex.Match(url, #"^(?<proto>\w+)://+?(?<host>[A-Za-z0-9\-\.]+)+?(?<port>:\d+)?/", RegexOptions.None, TimeSpan.FromMilliseconds(150)).Result("${host}${port}");
Console.WriteLine("url: "+url+"\nhost: "+host); //display host
see https://rextester.com/PVSO54371
u can also use https://github.com/d-kistanov-parc/DotNetUrlPatternMatching
The library allows you to match a URL to a pattern.
How it works:
an url pattern is split into parts
each non-empty part is matched with a similar one from the URL.
You can specify a Wildcard * or ~
Where * is any character set within the group (scheme, host, port, path, parameter, fragment)
Where ~ any character set within a group segment (host, path)
Only supply parts of the URL you care about. Parts which are left out will match anything. E.g. if you don’t care about the host, then leave it out.