Url.Action not including port number - c#

I have a partial view which is displayed on a non-HTTPS page, but POSTS to a controller that requires SSL. The form definition is this:
<form id="authForm"
method="post"
action="#Url.Action("authenticate", "auth", new {}, "https")">
The problem I'm having is that, within Visual Studio and when debugging, the host and port are localhost:64043. However, the Url.Action call above doesn't put the port number in, meaning the browser directs to my IIS installation. Do I have to add something else, or override this method? I want my application to be location agnostic.
Thanks in advance!

You could include it like this:
#Url.Action(
"authenticate",
"auth",
null,
"https",
Request.Url.Host + ":" + Request.Url.Port
)
Of course this means that your local web server must support SSL which is not the case with Cassini. You could use IIS Express for this to work.

The integrated development server does not support HTTPS, but you can use your local IIS - see HERE.

Http and https connections are usually on two different ports so if you change from one protocol to the other you either need to use the standard port or supply a specific port yourself. There's no sensible way a generic system can determine the right port

Use Request.Host.ToUriComponent():
string actionUrl = Url.Action("Action", "Controller", new { blah = "" }, Request.Scheme, Request.Host.ToUriComponent());
This also correctly omits the port number when it is the default port for the scheme, i.e if the Scheme is HTTP and the port is 80, or the Scheme is HTTPS and the port is 443, it will be omitted.

Related

Configure IIS for internal c# web application

I have a number of C# web applications that I have deployed to our in house web server so they can be available only to our internal users.
The webserver is running IIS 8.5 and I have set up a couple of sites in this that point at the applications, this is working fine except that the url you have to use to navigate to the applications is in the following format serverName:portNumber.
I would like to change this so the urls are more user friendly and they dont have to remember the server name and the port number.
I am an IIS noob so I don't know what to look into/try so any explanation using words of one syllable would be greatly appreciated!
I have seen that this might involve something to do with bindings (?) so I have included my current binding settings for my sites below.
Site1
Name: MySite1
Type: http
Host name: null
Port: 80
IP Address: *
Binding Information: null
Desired URL: www.mysite1.com or something equivalent
Site2
Name: MySite2
Type: http
Host name: null
Port: 81
IP Address: *
Binding Information: null
Desired URL: www.mysite2.com or something equivalent
Thanks in advance
In IIS you can right click on each website and go to Edit Bindings and you will be able to configure IP addresses and ports in there. If you leave the IP address as * (or "All Unassigned" as IIS calls it) and you want to have multiple sites with the same port number (80), then you need to specify the host name for each site. www.mysite1.com for the first site and www.mysite2.com for the second site as in your example. Of course you'll have to make sure those host names are in DNS so that your users will be able to connect to the server when they type in the URL.
Try changing bindings from C:\Windows\System32\drivers\etc
There will be a line '127.0.0.1 localhost' which you can uncomment and add your ip's here.
eg : ip : port staging.yoursite.com

HttpActionContext.Request.RequestUri.AbsoluteUri returns url with port number only on production?

When i log HttpActionContext.Request.RequestUri.AbsoluteUri, it returns:
http://productionurl.com:8083/api/stocks/1/images/
I have no clue how this port number :8083 is getting appended.
Issue it causes is that i am hashing document with url as http://productionurl.com/api/stocks/1/images/ [Same url without port number] and hence hash match fails on production.
How can i find how this port number gets appended and how can i avoid this?
It is related to how you configured your website on production. It looks like that your website is configured using port 8083 on production. Default HTTP port is 80 which means if no port is specified then it is 80.
URL - http://productionurl.com/api/stocks/1/images/ is same as http://productionurl.com:80/api/stocks/1/images/
Just double check in IIS website settings. The port should be 80 if you don't want it to append in URL.
It might be because in your local your website must be running on 8080(which is default) and on your production its running on a different port which is not default.

Hostname with Special Caracteres

In my WCF service, I need to publish it in the Bonjour service. The reason for this is to make the customers that consume my service know which computer it is running.
This works well.
But when I have machines with special characters in HostName, customers of this service can not eat because an error occurs in time to resolve the url.
Example: "http://máchine:8888/service.svc"
One solution would be to use thought to solve here the IP of the machine in place of the hostname. But when the computer works only with IPv6, I can not publish the service because the following error occurs: "Inalid URI: Invalid port specified."
How can I solve this problem without changing the HostName?
In my experience, when mapping zeroconf services to URLs, it's best to not rely on the service's host name. Resolve the service to an IP address (for example, with avahi, using avahi_service_resolver_new) and use the IP address in the URL. This avoids all sorts of problems with fancy hostnames and system resolvers that can't resolve zeroconf names (often the case on embedded systems).
If you got an error like "Inalid URI: Invalid port specified.", it sounds like you might simply have neglected to enclose the IP address in [square brackets]. The pseudocode for forming your URL should be:
if IP address contains ":"
url = "http://[" + ip address + "]:port/whatever"
else
url = "http://" + ip address + ":port/whatever"
There are two additional complications:
If you are using HTTPS, certificate matching will probably fail because the common name on the certificate won't match. It's not clear what to do about this in general because the very nature of an autodiscovered service usually means you can't meaningfully authenticate the server anyway. So you might be able to get away with just turning off certificate verification in your HTTP client.
You might not be able to use IPv6 link local address because there is a deficiency in the standard (RFC) for URL syntax that means it is not possible to attach a % character and an interface name to the address in the URL. Some HTTP clients allow the obvious extension to the standard to support scoped addresses, but others don't (for example, all of the major web browsers don't!).

IP address v/s machine name

My server name : server, my server ip is 192.168.10.200
SPSite site = new SPSite("192.168.10.200:7000") throws the following exception:
The Web application at
http://192.168.10.200:7000 could not
be found. Verify that you have typed
the URL correctly. If the URL should
be serving existing content, the
system administrator may need to add a
new request URL mapping to the
intended application
.
while
SPSite site = new SPSite("server:7000") works perfectly.
any ideas?
OS: Windows 7 64 bits + Sharepoint 2010
Your server is set up for serving more than one website and uses a Host header in the http request to sort out which one a request is for.
If you give it the IP address, it doesn't know which web server is meant.
The site could be configured with a host header for server and thus only answering on that and not on IP.
One clue is that your code says the port number is 7000 but the error message says it is 8000. Is that a typo in your actual code, or did you make a mistake in transcribing the code or message into your Question?
Also, the IP addresses don't match.

Ping always succeeds, cant easily check uptime using ping on a url

Im getting frustrated because of OpenDNS and other services (ie: roadrunner) that now always returns a ping even if you type any invalid url ie: lkjsdaflkjdsjf.com --- I had created software for my own use that would ping a url to verify if the site was up or not. This no longer works. Does anyone have any ideas about this?
Requirements:
It should work with any valid web site, even ones i dont control
It should be able to run from any network that has internet access
I would greatly appreciate to hear how others now handle this. I would like to add, im attempting to do this using System.Net in c#
Thank you greatly :-)
New addition: Looking for a solution that i can either buy and run on my windows machine, or program in c#. :-)
Update:
Thank you all very much for your answers. Ultimately i ended up creating a solution by doing this:
Creating a simple webclient that downloaed the specified page from the url (may change to just headers or use this to notify of page changes)
Read in xml file that simply lists the full url to the site/pages to check
Created a windows service to host the solution so it would recover server restarts.
On error an email and text message is sent to defined list of recipients
Most values (interval, smtp, to, from, etc) are defined in the .config for easy change
I will be taking some of your advice to add 'features' to this later, which includes:
AJAX page for real-time monitoring. I will use WCF to connect to the existing windows service from the asp.net page
Download Headers only (with option for page change comparison)
make more configurable (ie: retries on failure before notification)
Wget is a nice alternative. It will check not only whether the machine is active, but also whether the HTTP server is accepting connections.
You could create a simple web page with an address bar for the website and some javascript that uses AJAX to hit a site. If you get any HTTP response other than 200 on the async callback, the site isn't working.
<html>
<head>
<script language="javascript" type="text/javascript">
<!--
var ajax = new XMLHttpRequest();
function pingSite() {
ajax.onreadystatechange = stateChanged;
ajax.open('GET', document.getElementById('siteToCheck').value, true);
ajax.send(null);
}
function stateChanged() {
if (ajax.readyState == 4) {
if (ajax.status == 200) {
document.getElementById('statusLabel').innerHTML = "Success!";
}
else {
document.getElementById('statusLabel').innerHTML = "Failure!";
}
}
}
-->
</script>
</head>
<body>
Site To Check:<br />
<input type="text" id="siteToCheck" /><input type="button" onclick="javascript:pingSite()" />
<p>
<span id="statusLabel"></span>
</p>
</body>
This code depends on the browser not being IE and I haven't tested it, but it should give you a really good idea.
To see if a service is up, not only should you ping, but it's good to have scripts that will hit a service, such as a website, and get back a valid response. I've used What's Up Gold in the past, rather than write my own. I like all the features in products like that. such as sending me a page when a service is down.
For the record, lkjsdaflkjdsjf.com is a hostname (which at the moment is not registered to anyone). ping does not work with URLs, ping works with hostnames. hostnames are looked up using the Domain Name System. DNS is supposed to fail when hostnames are not registered.
The problem is that some services (apparently your ISP, and definitely OpenDNS) do NOT fail DNS requests for hostnames that aren't registered. Instead they return the IP address of a host on their network that presents a search page to any http request.
You appear to want to know two things: Is the name real (that is, is there a host with this name registered to some actual machine)? and Is that machine functioning?
If you already know that the name in question is real (for instance, you want to know if www.google.com is up), then you can use ping because you know that the name will resolve to a real address (the ISP can't return their IP for a registered name) and you'll only be measuring whether that machine is in operation.
If you don't know whether the name is real, then the problem is harder because your ISP is returning false data to your DNS request. The ONLY solution here is to find a DNS server that is not going to lie to you about unresolved names.
The only way I can think of to differentiate between your ISP's fake records and real ones is to do a reverse lookup on the IP you get back and see if that IP is in your ISP's network. The problem with this trick is that if the ISP doesn't have reverse DNS info for that IP, you won't know whether it's the ISP or just some knucklehead who didn't configure his DNS properly (I've made that mistake many times in the past).
I'm sure there are other techniques, but the fact that DNS lies underneath everything makes it hard to deal with this problem.
Don't directly know of any off the shelf options in c#, although I'd be very suprised if there aren't a few available.
I wrote something similar a few years ago, don't have the code anymore cos it belongs to someone else, but the basic idea was using a WebClient to hit the domain default page, and check for a http status code of 200.
You can then wire any notification logic around the success or fail of this operation.
If bandwidth is a concern you can trim it back to just use a HEAD request.
For more complex sites that you control, you can wire up a health monitoring page that does some more in depth testing before it sends the response, eg is DB connection up etc.
Often a machine that is dead on port 80 will still respond to a ping, so testing port 80 (or whatever other one you are interested in) will be a much more reliable way to go.
I've found ping to be very unreliable just because of all the hops you're having to jump through, and something in between can always interfere.
Trying to open up an http connection with a web server is probably the best way to go.
You could try running 'httping' if you have cygwin available or
http://freshmeat.net/projects/httping/
As far as I can see, the problem here that OpenDNS resolves invalid domains back to themselves to forward you on to something close to what you're after (so if you typo ggooggllee.com you end up at the right place via a bounce from the OpenDNS servers). (correct me if I'm wrong)
If that's the case, you should just be able to check whether the IP you've resolved == any of the IPs of OpenDNS? No more ping - no protocol (HTTP) level stuff - just checking for the exceptional case?
If you tend toward the sys-admin solution rather than the programming solution you could install a local name server and tell it not to accept anything but NS records for delegation only zones. This was the fix I (and I assumed everyone else on the internet) used when Network Solution/Verisign broke this last time. I installed BIND on a couple of local machine, told my DHCP servers to hand out those addrs as the local name servers, and set up something like the following for each of the delegation only zones that I cared about:
zone "com" { type delegation-only; };
zone "net" { type delegation-only; };
Come to think of this, I think this might be turned on by default in later BIND versions. As an added bonus you tend to get more stable DNS resolution than most ISPs provide, you control your own cache, a little patching and you don't have to rely on your ISP to fix the latest DNS attack, etc.
i like CALM for this sort of thing as it logs to a database and provides email notifications as well as a status dashboard
you can set up a test page on the site and periodically do a GET on it to receive either a 'true' result (all is well) or an error message result that gets emailed to you
caveat: i am the author of CALM

Categories

Resources