How do I force a relative URI to use https? - c#

I have a relative URI:
Uri U = new Uri("../Services/Authenticated/VariationsService.svc",
UriKind.Relative);
The problem is that depending on whether the user has typed https:// or http:// into their web browser to get to the silverlight application, it may use either http or https when trying to contact the service.
I want to force the program to use https for connecting to the service eitherway.
Initially I tried this:
Uri U = new Uri("../Services/Authenticated/VariationsService.svc",
UriKind.Relative);
string NU = U.AbsoluteUri;
U = new Uri(NU.Replace("http://", "https://"), UriKind.Absolute);
But it fails at U.AbsoluteUri because it can't convert the relative Uri into an absolute Uri at that stage. So how do I change the Uri Scheme to https?

The relative path has to be converted to absolute first. I do that using the Uri of the excuting Silverlight XAP file.
There might be ways to reduce this a bit (it feels wrong doing string operations with Uris) but it's a start:
// Get the executing XAP Uri
var appUri = App.Current.Host.Source;
// Remove the XAP filename
var appPath = appUri.AbsolutePath.Substring(0, appUri.AbsolutePath.LastIndexOf('/'));
// Construct the required absolute path
var rootPath = string.Format("https://{0}{1}", appUri.DnsSafeHost, appUri.AbsolutePath);
// Make the relative target Uri absolute (relative to the target Uri)
var uri = new Uri(new Uri(rootPath), "../Services/Authenticated/VariationsService.svc");
This does not include transferring a portnumber (which you might want to do in other circumstance). Personally I would put the above code in a helper method that also handles the port (and whatever you want to do differently when running localhost).
Hope this helps.

Instead, you should change your ASPX file which hosts your silverlight, and force user to redirect to SSL only if he/she is logged in using non SSL url. Because ideally it would be perfect if silverlight opens connection only to the same domain and scheme it loaded from.

The protocol is a separate component, so I think that you can just put it in front of your relative address:
Uri U = new Uri("https:../Services/Authenticated/VariationsService.svc", UriKind.Relative);

"Scheme" does not have any meaning in a relative URI. You'll have to convert it to an absolute URI at some point to change the scheme.

Related

How to maintain the right URL in C#/ASP.NET?

I am given a code and on one of its pages which shows a "search result" after showing different items, it allows user to click on one of records and it is expected to bring up a page so that specific selected record can be modified.
However, when it is trying to bring up the page I get (by IE) "This page cannot be displayed".
It is obvious the URL is wrong because first I see something http://www.Something.org/Search.aspx then it turns into http://localhost:61123/ProductPage.aspx
I did search in the code and found the following line which I think it is the cause. Now, question I have to ask:
What should I do to avoid using a static URL and make it dynamic so it always would be pointing to the right domain?
string url = string.Format("http://localhost:61123/ProductPage.aspx?BC={0}&From={1}", barCode, "Search");
Response.Redirect(url);
Thanks.
Use HttpContext.Current.Request.Url in your controller to see the URL. Url contains many things including Host which is what you're looking for.
By the way, if you're using the latest .Net 4.6+ you can create the string like so:
string url = $"{HttpContext.Current.Request.Url.Host}/ProductPage.aspx?BC={barCode}&From={"Search"}";
Or you can use string.Format
string host = HttpContext.Current.Request.Url.Host;
string url = string.Format("{0}/ProductPage.aspx?BC={1}&From={2}"), host, barCode, "Search";
You can store the Host segment in your AppSettings section of your Web.Config file (per config / environment like so)
Debug / Development Web.Config
Production / Release Web.Config (with config override to replace the localhost value with something.org host)
and then use it in your code like so.
// Creates a URI using the HostUrlSegment set in the current web.config
Uri hostUri = new Uri(ConfigurationManager.AppSettings.Get("HostUrlSegment"));
// does something like Path.Combine(..) to construct a proper Url with the hostName
// and the other url segments. The $ is a new C# construct to do string interpolation
// (makes for readable code)
Uri fullUri = new Uri(hostUri, $"ProductPage.aspx?BC={barCode}&From=Search");
// fullUrl.AbosoluteUri will contain the proper Url
Response.Redirect(fullUri.AbsoluteUri);
The Uri class has a lot of useful properties and methods to give you Relative Url, AbsoluteUrl, your Url Fragments, Host name etc etc.
This should do it.
string url = string.Format("ProductPage.aspx?BC={0}&From={1}", barCode, "Search");
Response.Redirect(url);
If you are using .Net 4.6+ you can also use this string interpolation version
string url = $"ProductPage.aspx?BC={barcode}&From=Search";
Response.Redirect(url);
You should just be able to omit the hostname to stay on the current domain.

strip off prefix of URL's

I have got the following log of URL strings. The logs contain millions of records.
www.example.com/p1?q=k
example.com/p1?q=k
http://example.com/p1?q=k
https://example.com/p1?q=k
http://www.example.com/p1?q=k
I used the C# Uri class but it throws an excepition for format of type "example.com/p1?q=K"
I was wondering if there is a generally/standard accepted method for dealing with such different types of URL to get websitename & the relative URL.
P.S: I could strip off http:// & https:// by using a regex or string comparision, but curious to know if there are any elegant solutions
If you try it with your existing example it will not work.. however you can play around with this and do some appending code where needed which means you will need to create a few variables to store the http://, https://, and www.
System.Uri uriPre = new Uri ("http://www.example.com/p1?q=k");
string uriString = uriPre.Host + uriPre.PathAndQuery;
uriString = uriString.Replace("www.", "");
yields
"example.com/p1?q=k"
the rest of the coding you will have to figure out because only you would know when to utilize the different protocols base on the example I've provided
to expand on Alexei Levenkov answer here is an example that you can use to try to create a new Uri.
Uri tempValue;
var uriPre = new Uri(string.Empty, UriKind.Relative);
if (Uri.TryCreate("example.com/p1?q=k", UriKind.Relative, out tempValue))
{
// do something or retrun tempValue;
}
Uri it the class that is designed to deal with Uris
var noSchemaRelativeUri = new Uri("example.com/foo", UriKind.Relative);
Either UriBuilder or Uri(Uri base, Uri relative) can be used to construct absolute Uri.
To pick between relative and aboslute you can use Uri.TryCreate.
Note. "www.example.com" and "example.com" strictly speaking are unrelated domain names, converting one to another is not guaranteed to always produce registered domain name (also indeed most sites register both and do some sort of redirect between).

UriBuilder points to localhost instead of domain name

My site has a public section that is accessed by http and a https part to requires logging in. When logging out of the site, it redirects to the http public index page.
Previously I had done this with stating the full url to point too. Recently I had to get rid of such things so the site can be run on numerous domains, for testing.
I tried using UriBuilder to convert https links to http link so that a website no longer has to use direct pointing to a specific url. This should allow the site to use any domain name. Right now it points to the computer name.
if (Request.IsSecureConnection)
{
UriBuilder ub = new UriBuilder();
ub.Path = "/html/index.html";
ub.Scheme = Uri.UriSchemeHttp;
ub.Port = -1; // use default port for scheme
Response.Redirect(ub.Uri.ToString(), true);
//An old direct link to the site
//Response.Redirect("http://www.someaddress.com/html/index.html");
}
When the code is triggered remotely on the test server instead of pointing to the right domain it returns me to the address
http://localhost/html/index.html
Instead of
http://testserver/html/index.html
I have no idea why it is doing this instead of returning the address I am connecting to the server via.
If you don't specify host than default host ("localhost") will be used - see UriBuilder() constructor article on MSDN.
Fix: specify host (probably based on incoming request's host).
ub.Host = GetMeIncomingHost();
Because in the URI to which you are redirecting, you haven't specified an authority (host). Thus, your redirect sends a 302 Found HTTP status and the response contains a location: header that looks like something like this:
location: /html/index.html
That is a relative URI, relative to the current URI from which the redirected request originated. That means it inherited the scheme and authority component of the requesting page (which, obviously, in your case, was an http://localhost:xx/....
To fix this, seed your UriBuilder in its constructor with HttpContext.Current.Request.Url. That should about do it:
UriBuilder ub = new UriBuilder( HttpContext.Current.Request.Url );
ub.Path = "/html/index.html";
Response.Redirect(ub.Uri.ToString(), true);

Extract domain with subdomain in side class

I have an ASP.NET 3.5 Web application with C# 2008.
What I need to do is, I want to extract full domain name in side a class method from Current URL.
For example :
I do have Current URL like :
http://subdomain.domain.com/pagename.aspx
OR
https://subdomain.domain.com/pagename.aspx?param=value&param2=value2
Then the result should be like,
http://subdomain.domain.com
OR
https://subdomain.domain.com
You're looking for the Uri class:
new Uri(str).GetLeftPart(UriPartial.Authority)
Create a Uri and query the Host property:
var uri = new Uri(str);
var host = uri.Host;
(Later)
I just realized that you want the scheme and the domain. In that case, #SLaks answer is the one you want. You could do it by combining the uri.Scheme and uri.Host, but that can get messy for things like mailto urls, etc.

Getting full URL from URL with tilde(~) sign

I am trying to get a typical asp.net url starting with the tilde sign ('~') to parse into a full exact url starting with "http:"
I have this string "~/PageB.aspx"
And i want to make it become "http://myServer.com/PageB.aspx"
I know there is several methods to parse urls and get different paths of server and application and such. I have tried several but not gotten the result i want.
Try out
System.Web.VirtualPathUtility.ToAbsolute("yourRelativePath");
There are various ways that are available in ASP.NET that we can use to resolve relative paths to a resource on the server-side and making it available on the client-side. I know of 4 ways -
1) Request.ApplicationPath
2) System.Web.VirtualPathUtility
3) Page.ResolveUrl
4) Page.ResolveClientUrl
Good article : Different approaches for resolving URLs in ASP.NET
If you're in a page handler you could always use the ResolveUrl method to convert the relative path to a server specific path. But if you want the "http://www.yourserver.se" part aswell, you'll have to prepend the Request.Url.Scheme and Request.Url.Authority to it.
string.Format("http://{0}{1}", Request.Url.Host, Page.ResolveUrl(relativeUrl));
This method looks the nicest to me. No string manipulation, it can tolerate both relative or absolute URLs as input, and it uses the exact same scheme, authority, port, and root path as whatever the current request is using:
private Uri GetAbsoluteUri(string redirectUrl)
{
var redirectUri = new Uri(redirectUrl, UriKind.RelativeOrAbsolute);
if (!redirectUri.IsAbsoluteUri)
{
redirectUri = new Uri(new Uri(Request.Url.GetLeftPart(UriPartial.Authority) + Request.ApplicationPath), redirectUri);
}
return redirectUri;
}

Categories