Changing the port of the System.Uri - c#

I have an Uri object which contains an address, something like http://localhost:1000/blah/blah/blah. I need to change the port number and leave all other parts of the address intact. Let's say I need it to be http://localhost:1080/blah/blah/blah.
The Uri objects are pretty much immutable, so I can access the port number through the Port property, but it's read-only. Is there any sane way to create an Uri object exactly like another but with different port? By "sane" I mean "without messing around with regular expressions and string manipulations" because while it's trivial for the example above, it still smells like a can of worms to me. If that's the only way, I really hope that it's already implemented by someone and there are some helpers out there maybe (I didn't find any though).

Have you considered the UriBuilder class?
http://msdn.microsoft.com/en-us/library/system.uribuilder.aspx
The UriBuilder class provides a convenient way to modify the contents of a Uri instance without creating a new Uri instance for each modification.
The UriBuilder properties provide read/write access to the read-only Uri properties so that they can be modified.

I second a vote for UriBuilder. I actually have an extension method for changing the port of a URI:
public static class UriExtensions {
public static Uri SetPort(this Uri uri, int newPort) {
var builder = new UriBuilder(uri);
builder.Port = newPort;
return builder.Uri;
}
}
Usage:
var uri = new Uri("http://localhost:1000/blah/blah/blah");
uri = uri.SetPort(1337); // http://localhost:1337/blah/blah/blah

Related

How to access properties of Uri defined with UriKind.Relative

My method receives a URI as a string and attempts to parse it into a predictable and consistent format. The incoming URL could be absolute (http://www.test.com/myFolder) or relative (/myFolder). Absolute URIs are easy enough to work with, but I've hit some stumbling blocks working with relative ones. Most notable is the fact that, although the constructor for Uri allows you to designate a relative URI using UriKind.Relative (or UriKind.RelativeOrAbsolute), it doesn't appear to have any properties available when you do this.
Specifically, it throws this exception: System.InvalidOperationException : This operation is not supported for a relative URI.
It makes sense that you wouldn't be able to access, say, the Scheme or Authority properties--although it seems weird that they actually throw invalid operation exceptions instead of just returning blank strings--but even properties like PathAndQuery or Fragment exhibit the same behavior. In fact, pretty much the only properties that don't throw exceptions for relative URIs are the IsX flags and OriginalString, which just shows the string you passed in to the the object in the first place.
Given that that constructor explicitly allows you to declare a relative URI, this all seems like a baffling omission. Is there something I'm missing here? Is there any way to handle relative URIs as their component parts, or do I need to just treat it as a string? Am I completely failing to understand what "relative URI" means in this case?
To replicate:
var uri = new Uri("/myFolder");
string foo = uri.PathAndQuery; // throws exception
Visual Studio Pro 2015,
.NET 4.5.2 (if any of that makes a difference)
It's by design that an exception gets thrown when accessing eg. PathAndQuery for a relative uri, see uri source code.
As a rather quick and dirty workaround to parse some segments, you could construct a temporary absolute uri out of the relative one, using a dummy base uri (scheme and host) which you ignore.
String url = "/myFolder?bar=1#baz";
Uri uri = new Uri(url, UriKind.RelativeOrAbsolute);
if (!uri.IsAbsoluteUri)
{
Uri baseUri = new Uri("http://foo.com");
uri = new Uri(baseUri, uri);
}
String pathAndQuery = uri.PathAndQuery; // /myFolder?bar=1
String query = uri.Query; // ?bar=1
String fragment = uri.Fragment; // #baz

How to get all urls from a webpage belonging to same Domain

Currently i am using this code to get the above :
Uri baseUri = new Uri(url);
Uri myUri = new Uri(baseUri, strRef);
domain = baseUri.Host;
Console.WriteLine(myUri.ToString());
strRef = myUri.ToString();
if (strRef.Contains(domain))
{
//THIS MEANS IT BELONGS TO SAME DOMAIN...
}
But using this code i am having some issue like suppose we have a main url = http://www.xxx.co.uk
Then the above code also treats a url like http://www.news.xxx.co.uk as external link ? Is this correct should it do that if not any one know a better solution for this?
I think you are in the correct path. But, to grab the latter mentioned URL (http://www.news.xxx.co.uk/) you could do a quick fix like this.
domain = baseUri.Host.Replace("www.", string.Empty);
Cheers!
vote if helpful.

Selenium: Find the base Url

I'm using Selenium on different machines to automate testing of a MVC Web application.
My problem is that I can't get the base url for each machine.
I can get the current url using the following code:
IWebDriver driver = new FirefoxDriver();
string currentUrl = driver.Url;
But this doesn't help when I need to navigate to a different page.
Ideally I could just use the following to navigate to different pages:
driver.Navigate().GoToUrl(baseUrl+ "/Feedback");
driver.Navigate().GoToUrl(baseUrl+ "/Home");
A possible workaround I was using is:
string baseUrl = currentUrl.Remove(22); //remove everything from the current url but the base url
driver.Navigate().GoToUrl(baseUrl+ "/Feedback");
Is there a better way I could do this??
The best way around this would be to create a Uri instance of the URL.
This is because the Uri class in .NET already has code in place to do this exactly for you, so you should just use that. I'd go for something like (untested code):
string url = driver.Url; // get the current URL (full)
Uri currentUri = new Uri(url); // create a Uri instance of it
string baseUrl = currentUri.Authority; // just get the "base" bit of the URL
driver.Navigate().GoToUrl(baseUrl + "/Feedback");
Essentially, you are after the Authority property within the Uri class.
Note, there is a property that does a similar thing, called Host but this does not include port numbers, which your site does. It's something to bear in mind though.
Take the driver.Url, toss it into a new System.Uri, and use myUri.GetLeftPart(System.UriPartial.Authority).
If your base URL is http://localhost:12345/Login, this will return you http://localhost:12345.
Try this regular expression taken from this answer.
String baseUrl;
Pattern p = Pattern.compile("^(([a-zA-Z]+://)?[a-zA-Z0-9.-]+\\.[a-zA-Z]+(:\d+)?/");
Matcher m = p.matcher(str);
if (m.matches())
baseUrl = m.group(1);

Is it possible to override the UserHostAddress property of the HttpRequest class?

I have a situation where I need to put my application behind a proxy server, this causes all the request's that are coming to my application to have the same set of IP addresses used by the proxy servers. However the Proxy server provides the real IP address of the requestor in a custom header, that I can use through my application so I can know the real IP address of the requestor. This is mainly used for logging and tracking. Is there a way I can have the UserHostAddress property return the value from this custom header? This would save a lot of work, because this property referenced about a few hundred time.
It's not possible to change the behavior of the UserHostAddress property, however what you can do is add an extension method to the Request class (something like GetRealUserHostAddress()) and just do a global replace on UserHostAddress -> GetRealUserHostAddress() to rapidly sort out all the instances of it in your solution.
public static string GetRealUserHostAddress(this HttpRequestBase request)
{
return request.Headers["HeaderName"] ?? request.UserHostAddress;
}
If you are saying that the proxy returns the real ip address of the client making the request, you don't need to use the UserHostAddress to read it; you can simply read the header directly:
string realIP = HttpContext.Request.Headers["actual_header_key"];
No, it's not possible. You can read the custom header and place in the request context and use that later.

Converting a web address to a valid href value

Firstly, this seems like something that should have been asked before, but I cannot find anything that answers my question.
A basic overview of my task is to render an anchor link on a web page which is based on a user defined web address. As the address is user defined this could be in any format, for example:
http://www.example.com
https://www.example.com
www.example.com
example.com
What I need to do with this value is to set it as the href property of an anchor tag. Now, the problem is that (in Chrome at least) only the first two examples will work due to the fact they are recognised as absolute URL paths. The last two examples will redirect to the same domain (i.e. treated as relative paths)
So the ultimate question is: What is the best way to format these values to ensure a consistent absolute path is used? I could check for http/https and add it if missing, but I was hoping there might be an out of the box .Net class that would be more reliable.
In addition, as this is a user defined value, it could be complete junk anyway so a function to validate the URL would be a nice bonus too.
We ran into this problem a few months back, and needed a consistent way of ensuring the URLs were absolute. We also wanted a way of removing http(s):// for displaying the URL on the web page.
I came up with this function:
public static string FormatUrl(string Url, bool IncludeHttp = null)
{
Url = Url.ToLower();
switch (IncludeHttp) {
case true:
if (!(Url.StartsWith("http://") || Url.StartsWith("https://")))
Url = "http://" + Url;
break;
case false:
if (Url.StartsWith("http://"))
Url = Url.Remove(0, "http://".Length);
if (Url.StartsWith("https://"))
Url = Url.Remove(0, "https://".Length);
break;
}
return Url;
}
I know you're after an "out of the box" library, but this may be of some help.
I think the problem with an "out of the box" solution would be that the function won't know whether the URL should be http:// or https://. With my function I've made an assumption that its going to be http://, but for some URLs you need https://. If Microsoft were to build something like this into the framework, it would be buggy from the start.
You can try using this overload of the Uri class:
Uri Constructor (String)
This constructor creates a Uri instance from a URI string. It parses the URI, puts it in canonical format, and makes any required escape encodings.
This constructor does not ensure that the Uri refers to an accessible resource.
This constructor assumes that the string parameter references an absolute URI and is equivalent to calling the Uri constructor with UriKind set to Absolute. If the string parameter passed to the constructor is a relative URI, this constructor will throw a UriFormatException.
This will try to construct a canonical Uri from the user input. And you have lots of properties to check and extract the URL parts that you need.

Categories

Resources