Posts tagged with 'asp-net'

Solution for ASP.NET routing on GoDaddy shared hosting

Panning for Goldphoto © 2009 Caitlin Childs | more info (via: Wylio)I was doing a bit of research to try and find some nuggets of information on URL rewriting, especially with regard to GoDaddy’s shared hosting (I run this website (and others) on GoDaddy). I found this article in Google’s cache but the original site (codebeater.com) has gone away (I presume the domain wasn’t renewed). The article was by CodeBeater’s admin.

I didn’t want it to disappear into the ether as I can certainly see me using it in the future. So I copied it here verbatim, just cleaning up some look-n-feel.

[UPDATE 21-Feb-2011: Jeff from the CodeBeater site has revived his blog and has republished this post there.]

Solution for ASP.NET MVC Routing issue on Godaddy shared hosting

This is actually not an issue related to GoDaddy shared hosting at all but an issue with hosting an ASP.NET MVC site in a virtual directory. When you use the shared hosting provided by GoDaddy you get a root folder and limitless subfolders, each of which can be its own domain, by way of virtual directory. Unfortunately, MVC’s routing engine produces URLs that will include the virtual directory name appended to the domain name.

For example, let’s say you have a domain named http://www.example.com and your folder/virtual directory name is /File. If you take the MVC template project without making any modifications and upload it to your folder and then go to your url everything will look fine. You will notice the ‘Home’ and ‘About’ tabs at the top right of the page. When you click on the ‘About’ tab, since it is routed to the Home controller’s About action, you would rightly expect the URL to be www.example.com/Home/About. What you will see, though, is that the URL generated by the ActionLink method includes the name of the virtual directory. Therefore, the URL will be www.example.com/File/Home/About.

If this problem doesn’t bother you then kudos to you. It bothers me and I was really hoping to find a resolution that involved configuration, rather than writing a bunch of custom code for something I felt should work ‘out of the box’. After posting the question here and scouring various forums I found many others having the same problem but not one solution.

Luckily for me, I have a couple of friends and former coworkers that now work at GoDaddy who jumped on this issue when I posted it to their forums. I want to first say thanks to both of them for taking the time to dive into this and finding a configuration-based solution that works perfectly. You know who you are!

So now for the solution, and I probably should have mentioned this at the beginning but hopefully you’re using IIS7 with the URL rewriting module installed (it is installed by default when you use IIS7 on GoDaddy).

Simply add the following into your web.config’s system.webServer element:

<rewrite>
  <rules>
    <rule name="Remove Virtual Directory">
      <match url=".*" />
      <action type="Rewrite" url="{R:0}" />
    </rule>
  </rules>
</rewrite>

All this does is “rewrite” the URL with itself. This causes URL Rewrite to add the original URL (the one with no folder name) to a ServerVariable which is used by ASP.NET MVC to generate other URLs.

Again, this only works when you’re using IIS7 with the url rewriting module installed.

Good luck!

Album cover for Safe Trip HomeNow playing:
Dido - Northern Skies (Remix)
(from Safe Trip Home)


IIS and ASP.NET 404 redirects and GoDaddy

So, last night I was working on my URL shortening website (jmbk.nl) and the application that generates the short URLs and that redirects existing ones to the actual URLs. And for some unknown reason, the redirections just weren’t working on the actual website. I’d get server errors (even “404-Not Found” server errors) and my redirection ASPX page just didn’t seem to get called. It was, to be polite, a mess. And, because it was late at night and I was tired I was flailing around trying stupid stuff to see what stuck and nothing would.

This morning I was more calm and collected and finally worked out what the issue was. Trouble is, when laid out like this, it sounds ruddy obvious and I should not have had a problem in the first place.

Let’s briefly explain how it all works. The application has a routine that converts a long URL (such as http://blog.boyet.com/blog/pcplus/pcplus-285-calculating-pi/) and converts it to a short URL (like http://jmbk.nl/d3T7A) and stores it in a database. That bit is easy. Now the fun stuff: the short URL does not actually exist. When you click on it, magic happens, a 404 error is raised and my redirection page is supposed to gain control, work out what short URL was used, and convert it back to the long URL (it just looks it up in the database essentially). It then does a Response.Redirect to that URL. To the end-user, it was as if he just clicked on a short URL and he got the actual web page.

The problem is in that phrase “magic happens”. I was assuming one thing and some entirely different other thing was happening.

This is what I was assuming. I had a section in my web.config that said:

<customErrors mode="On">
	<error statusCode="404" redirect="Redirection.aspx" />
</customErrors>    

(This is in the system.web section.) I was reading this as “Got a 404? Go to Redirection.aspx”. Right? Wrong. All right, it’s partially correct but the bit I was assuming was correct was hopelessly wrong.

The other thing to point out is that the jmbk.nl website is being run on GoDaddy. It is hosted on a Windows server running IIS7 and ASP.NET 3.5. I’d also set the “404 Error Behavior” option on the hosting dashboard to the same ASPX page, although part of me was wondering why. Surely my web.config setting was enough?

Therein lies the rub. No, it isn’t. You see, there are two different ways a 404 error could be generated. My issue was I thought that there was only one.

First things first: when you try and follow a link to your domain, it is IIS that will get the request and decide what to do. (I’m assuming my case here, obviously I should say “the web server” to be more generic.) Part of IIS’ configuration is a list of file extensions and what to do with those extensions. GoDaddy have got their IIS set up such that if you request an ASPX page (or ASHX, ASMX, etc, etc), IIS will just pass the whole request over to ASP.NET and let it do with it what it will.

So, if I request http://jmbk.nl/DoesNotExist.aspx, IIS will pass it on to ASP.NET, and ASP.NET will work out that that ASPX page is bogus; it does not exist. It’s a 404. ASP.NET then goes to the web.config file, finds out what I wanted it to do with 404 errors and then redirects the request to http://jmbk.nl/Redirection.aspx?aspxerrorpath=http://jmbk.nl/DoesNotExist.aspx. My redirection page gains control, works out the original URL (using Request.QueryString["aspxerrorpath"]) and can do some valuable work with it.

But what if the original request was not for an obvious ASP.NET page? Say, for a short URL like http://jmbk.nl/d3T7A? In this case, IIS will not pass the request onto ASP.NET. Instead it tries to find that page itself. If it can’t find the page, it’s a 404 again, but this time generated by IIS itself. IIS looks to its own custom error page list to see what to do with a 404. The way I’ve set up the hosting of this website with GoDaddy, the custom error page is the same Redirection.aspx page. IIS redirects the request (and, yes, it gets transferred to ASP.NET). This time however, the redirected request is very different: http://jmbk.nl/Redirection.aspx?404;http://jmbk.nl:80/d3T7A.

Notice a couple of things: there is no aspxerrorpath key, and in fact the query string (the bit after the question mark) is not even a name/value dictionary. There’s no key=value pairs to be seen anywhere; Request.QueryString[...] is going to get you nothing.

The solution is to either have two different redirection pages, one for ASP.NET 404s and one for IIS 404s with different processing, or to use a different way to get at the query string. In the end, I went for the second option and used Request.ServerVariables["QUERY_STRING"] to get the entire query string. Once I had that it was pretty easy to extract the non-existing URL, no matter how the query string had been created.

As I said, it all sounds very obvious describing it like this, but I was seriously confused about it all last night. My research showed me that I’m not the only person so confused.

Professional DevExpress ASP.NET Controls now in print

Just a quick post to say I received a copy of Professional DevExpress ASP.NET Controls in my hot little hands this afternoon. Also, Amazon.com also have it in stock here.

Just to prove it, here's an iPhone shot, taken just now on my desk in DevExpress' Glendale office:

image

Yay! I'll be bringing it home after PDC and adding it to my little collection of books I've had a hand in (one sole author, two co-authored, two edited/typeset). Getting to be quite the bookworm…

Book: Professional DevExpress ASP.NET Controls

Over the summer I spent quite a bit of time on top of my normal work activities (at least those I couldn't put aside) writing a couple of chapters for Professional DevExpress ASP.NET Controls. Yes, I've been saying for a while that I'd never write a book again, but this was an opportunity to quickly write something that would appear in a book form, without my name being on the cover. Unfortunately Wrox didn't listen to me and put it there anyway :).

PDXASPControls

Originally Paul Kimmel was going to be writing all of it, but, as anyone who's written a technical book will tell you, it's very intensive, hard work and difficult to complete in a relatively short period of time. We, DevExpress, also had a deadline: we had to have copies of the book at PDC in November. In order to make sure that this happened, Joe Kunk and I agreed to take off some of the more specialized chapters (that is, chapters on single specialized products) off Paul and write them ourselves. Joe did the XtraReports chapter, and I did the XtraCharts and asynchronous programming chapters. I also did the section on Javascript for another chapter, basing it quite a bit on my series on writing Javascript. Paul wrote the rest, the vast majority of the book and is the real hero.

So, a book author again...

Now playing:
Jellybean - Little too good to me
(from Just Visiting This Planet)


<!--

Extras

Search

About Me

I'm Julian M Bucknall, the M because it's my middle initial and because I and the other Julian Bucknall (the movie guy) would like to differentiate ourselves.

I'm a programmer by trade, an actor by ambition, and an algorithms guy by osmosis. I write articles for PCPlus in my spare time, not that there's much of that.

Julian M Bucknall Apart from that, an ex-pat Brit, atheist, microbrew enthusiast, Pet Shop Boys fanboy, slide rule and HP calculator collector, amateur photographer, Altoids muncher.

DevExpress

I'm Chief Technology Officer at Developer Express, a software company that writes some great controls and tools for .NET and Delphi. I'm responsible for the technology oversight and vision of the company.

Validation

Validate markup as HTML5 (beta)     Validate CSS

Bottom swirl

Archives

May 2012 (4)
SMTWTFS
« Apr  
12345
6789101112
13141516171819
20212223242526
2728293031

Like this Archive Calendar widget? Download it here.

Social networking

The OUT Campaign

The OUT Campaign

My Tweets

  • Honest Movie Trailer of Phantom Menace http://t.co/sif8y4Ns and then Battleship, er, Transformers http://t.co/sif8y4Ns
  • Damn, Donna Summer and Chuck Brown both gone in the last 24 hours. Different types of music, sure, but enjoyed them both. :(
  • Just saw a company page showing a list of tweets with "Join the conversation" linked to their Twitter a/c. The tweets are 6 months old #fail
Bottom swirl