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.
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();
}
}
Why is
new Uri("temp/file.txt")
throwing the following exception
UriFormatException: Invalid URI: The format of the URI could not be determined.
instead of creating a relative Uri? It doesn't know the format so why do I need to specify the UriKind.Relative argument? It still doesn't know the format when I do it. This is counterintuitive.
Is there a way to create a relative Uri without having to use the UriKind argument? Having to do this untermines the purpose of the Uri class because I now cannot use it for implicit string --> Uri converstion without checking the string myself each time.
You may want to create it by specifying RelativeOrAbsolute as UriKind:
var uri = new Uri("temp/file.txt", UriKind.RelativeOrAbsolute);
So I tried this in several different formats and produced different results. I will include all relevant information below.
My company uses a web-based application to schedule the generation of reports. The service emails a URL that can be clicked on and will immediately begin the "Open Save As Cancel" dialogue box. I am trying to automate the process of downloading these reports with a C# script as part of a Visual Studio project (the end goal is to import these reports in SQL Server).
I am encountering terrible difficulty initiating the download of this file using WebClient Here is the closest I have gotten with any of the methods I have tried:
*NOTE: I removed all identifying information from the URL, but left all special characters and the basic architecture intact. Hopefully this will be a happy medium between protecting confidential info and giving you enough to understand my dilemma. The URL does work when manually copied and pasted into the address bar of internet explorer.
Error Message:
"Invalid URI: The hostname could not be parsed."
public void Main()
{
using (var wc = new System.Net.WebClient())
{
wc.DownloadFile(
new Uri(#"http:\\webapp.locality.company.com\scripts\rds\cgigetf.exe?job_id=3058352&file_id=1&format=TAB\report.tab"),
#"\\server\directory\folder1\folder2\folder3\...\...\...\rawfile.tab");
}
}
Note also that I have tried to set:
string sourceUri = #"http:\\webapp.locality.company.com\scripts\rds\cgigetf.exe?job_id=3058352&file_id=1&format=TAB\report.tab\abc123_3058352.tab";
Uri uriPath;
Uri.TryCreate(sourceUri, UriKind.Absolute, out uriPath);
But uriPath remains null - TryCreate fails.
I have attempted doing a webrequest / webresponse / WebStream, but it still cannot find the host.
I have tried including the download URL (as in my first code example) and the download URL + the file name (as in my second code example). I do not need the file name in the URL to initiate the download if I do it manually. I have also tried replacing the "report.tab" portion of the URL with the file name, but to no avail.
Help is greatly appreciated as I have simply run out of thoughts on this one. The only idea I have left is that perhaps one of the special characters in my URL is getting in the way, but I don't know which one that would be or how to handle it properly.
Thanks in advance!
My first thought would be that your URI backslashes are being interpreted as escape characters, leading to a nonsense result after evaluation. I would try a quick test where each backslash is escaped as itself (i.e. "\" instead of "\" in each instance). I'm also a little puzzled as to why your URI is not using forward slashes...?
// Create an absolute Uri from a string.
Uri absoluteUri = new Uri("http://www.contoso.com/");
Ref: Uri Constructor on MSDN
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!
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/");