New MVC Tutorials Posted
Steven Walther has posted a new set of MVC tutorials @ http://www.asp.net/learn/mvc/#MVC_SampleApp that are almost full-lifecycle. Might be worth a read.
Steven Walther has posted a new set of MVC tutorials @ http://www.asp.net/learn/mvc/#MVC_SampleApp that are almost full-lifecycle. Might be worth a read.
Just finished a SharePoint / KnowledgeBin bridge for KnowledgeBin. The company provides a custom document management solution but they needed some larger integration with SharePoint to handle some issues outside of their domain. The bridge is only a Proof-of-Concept at the moment, but it works well and can certainly be hardened to be an exceptionally robust solution to their particular problem — and that of their client.
Sometimes it’s necessary to host applications behind a reverse proxy. While the application may appear locally as http://somehost.com/someapp, the outside world would see the application as http://somecompany.com/ — so this is the opposite of the typical scenario, but the premise is the same. This is all fine and good and is easy enough to setup with Apache in the front end on the cheap.
The problem occurs with how ASP.NET tells the client to retrieve embedded resources. Embedded resources are typically returned to the web client by a call to WebResource.axd that exists in the application root (~/) — the file’s not actually there, it’s a handler. From the ASP.NET application’s perspective, ~/ maps to /someapp. However, the web client is assuming that the application root is / because they’re looking at the pages through the reverse proxy, a proxy of which ASP.NET is blissfully unaware.
As stated earlier, the true application root is /someapp and ASP.NET tells the client to access WebResource.axd at /someapp/WebResource.axd. The web client assumes that this is appended to the current root which is http://somecompany.com/ and then tries to retrieve WebResource.axd at http://somecompany.com/someapp/WebResource.axd, a location that the proxy then maps to http://somehost.com/someapp/someapp/WebResource.axd. This isn’t accounted for in the http handler’s mapping and the request returns a 404.
The 404 File Not Found code is problematic in that WebResource.axd is the handler responsible for returning all of the embedded resources in the application — typically JavaScript for ASP.NET user controls, ASP.NET validation controls, and 3rd party controls. The application breaks and it’s bad times for all. Enter UrlRewritingNet.UrlRewrite.
This free open source library will allow rewrites to be performed simply by adding a couple entries in the application’s web.config and including the library in the application’s bin folder. This is perfect for shared hosting environments where access to the actual server to install isapi rewrite is not possible.
The documentation is pretty clear, though the English is a bit broken, and contains the enumerated steps for installation into the application. Once the library has been installed, all that’s left is to write some simple rewrite rules.
Inside the web.config, for this application, we would add the following rewrite rules
<urlrewritingnet xmlns="http://www.urlrewriting.net/schemas/config/2006/07" > <rewrites> <add name="WebResourceFix" virtualUrl="^~/WebResource.axd(.*)" rewriteUrlParameter="IncludeQueryStringForRewrite" destinationUrl="~/WebResource.axd$1" ignoreCase="true"/> <add name="ScriptResource" virtualUrl="^~/(.*)/ScriptResource.axd(.*)" rewriteUrlParameter="IncludeQueryStringForRewrite" destinationUrl="~/ScriptResource.axd$2" ignoreCase="true"/> <add name="ReplaceRoot" virtualUrl="^~/(.*)/(.*)" rewriteUrlParameter="IncludeQueryStringForRewrite" destinationUrl="~/$2" ignoreCase="true"/> </rewrites> </urlrewritingnet>
This rewrite rule will take any inbound request to /someapp/WebResource.axd and map it to /WebResource.axd. This ends the 404 and its good times for all.
So far, I’ve had nothing but success with this approach and have extended it to handle the ASP.NET Ajax resource tool ScriptResource.axd that suffers from the same fate. Additionally, if Web Service callbacks are used in the application for Ajax invocation, the same rules will need to be applied to the page and it may be easier to simply remap anything that comes in for /someapp to /.
Note, there are other methods that will allow you to fix some of these issues, but they’re not always achievable in shared hosting environments or in environments where configuration is tightly controlled. Further, this does not handle problems with using web.sitemap in an application that is behind a reverse proxy but that will be left as an exercise to the reader.