asp.net custom HttpHandler and URL routing - url

I want handle the requests to my application "http://example.com/whateverpath" by a custom HttpHandler but the return things depending of the value of "whateverpath".
So users accessing "http://example.com/path1" will get different response than users accessing "http://example.com/path2", but both request must be handled in the same HttpHandler. The idea is find "whateverpath" in a database and depending of the result, return the response content.
I hear about URL routing and I already have a custom Http handler working, but can I combine both technique to get what I need?
I will appreciate any comment respect this issue.
Cheers
Frank Abel

So you have a class that implements IHttpHandler called: MyHandler and it's in the namespace Example, you need to make the following entries in the site's Web.Config in the httpHandlers section:
<httpHandlers>
<add verb="*" path="*" type="Example.MyHandler"/>
</httpHandlers>
Since this redirects all URLs for your web site/application to your handler you have to consider how to serve static content (imgs, scripts, style sheets etc). One way is to store such static content in a consistent URL like http://example.com/static/..., you can then set your handlers as such:
<httpHandlers>
<add verb="*" path="*" type="Example.MyHandler"/>
<add verb="GET,HEAD" path="static/*" type="System.Web.StaticFileHandler" />
</httpHandlers>
For your local dev webserver (embedded in Visual Studio) this is all that's needed. For IIS, you also need to tell IIS how to deal with these URLS (since the server first analyses a request to decide where to send it - including whether to send it to ASP.NET or some other extension).
Open: IIS Manager ->
Section: Websites ->
Right click on your website ->
Option: Properties ->
Tab: Home Directoy ->
Button: [Configuration...] ->
Tab: Mappings ->
Section: "Wildcard application maps (order of implementation):" ->
Button: [Insert...] ->
Executable: "C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\aspnet_isapi.dll" (or whichever version of the .NET runtime your handler uses) ->
Uncheck "Verify that file exists" ->
Button: [OK]
Now both IIS and ASP.NET know how to deal with your URLS.
The above approach means when requesting static files, ASP.NET is actually serving the files, not IIS - which leads to a few disadvantages (discussed here). You can override this behaviour (disable wildcard mapping from the static directory) by switching the directory to an application (in IIS Manager), removing the wildcard mapping statement (added above) and switching it back from an application. VoilĂ  - static files are handled by IIS without pestering your ASP.NET.

I do not recommend combining URL routing and HTTP handlers.
This seems like a perfect job for URL routing. However, I would not use an HTTP handler for it.
Simply map "~/CustomData/whateverpath" to an ASPX page. Then have the page load the data from the database. Afterall, if the logic to look up the data is the same no matter what "whateverpath" is, you don't want to repeat your logic for every variation. Instead, you want to map it to a single file that will load the correct data for all cases.
HTTP handlers are a completely different matter and should not be used for this purpose. (BTW, I just published an article on HTTP handlers. You can view it at http://www.blackbeltcoder.com/Articles/asp/writing-a-custom-http-handler-in-asp-net).

First off, I would concur with the previous post by Jonathan Wood, that using routing within HttpHandler isn't a good idea. But I am pretty sure he was referring to the standard MVC routing there.
A good approach would be in using custom routing. I published an article about it - Basic Routing for HttpHandler

Related

Redirecting legacy URLs in DotNetNuke

We are building a revamped version of our old site in DotNetNuke. There are many pages that link to pages on our old site and we would like those old URLs to still lead to relevant information on the new site. The old URLs end in a variety of extensions, and sometimes in no extension (our old site is a mishmash of several platforms as well as static files). Does a DNN plugin exist that allows for such redirects? Friendly URLs aren't entirely adequate.
note: I realize that this could be handled in IIS, but we would like our non-coder, non-admin site manager to be able to handle this dynamically.
You will probably want to use a Module like this
http://www.dnnsoftware.com/forge/open-url-rewriter-for-dnn-dotnetnuke/view/extensiondetail/project/openurlrewriter
There is another option though. You can actually put URL records into the database directly, I believe you would simply add a record to the TabUrls table, the TABID is the page in DNN you want to point to. Then you put in the URL, and the HTTPStatus of 301.
You could do that for all the old pages if you know where they need to be mapped to in DNN.
You have to force all request through the ASP.NET pipeline, and you can do that by adding only this single line to the web.config of your application:
<system.webServer>
<modules runAllManagedModulesForAllRequests="true" />
</system.webServer>

MvcSiteMapProvider - Prevent display/serving sitemap.xml

I have a web app that uses MvcSiteMapProvider, but I don't want it to server /sitemap.xml as every page but the login page requires authentication, so there is no need for the public to see my sitemap.
Is there a way to turn off the the /sitemap.xml file in config? Or a way to do it with RoutesConfig?
As per the documentation, if using internal DI, you can disable the /sitemap.xml endpoint using the MvcSiteMapProvider_EnableSitemapsXml setting.
<appSettings>
<add key="MvcSiteMapProvider_EnableSitemapsXml" value="false"/>
</appSettings>
If using external DI, you need to remove this line from the /App_Start/MvcSiteMapProviderConfig.cs file (or anywhere else it may exist in your application startup code).
// Register the Sitemaps routes for search engines
//XmlSiteMapController.RegisterRoutes(RouteTable.Routes);
FYI - although this setting does what you asked, there really was no problem to begin with. Search engines do not scan web sites for XML sitemap files, they have to be explicitly submitted. According to the sitemap protocol, they can be submitted via HTTP request, via search engine control panel, or by adding the location to the \robots.txt file. But none of these are done without explicit intervention on the part of the webmaster. In all cases, the webmaster chooses the URL that the XML sitemap will be hosted at. Unlike the \robots.txt file, there is no default location for it. We chose the most reasonable logical path \sitemap.xml, but technically it could be anything.

Creating a custom error page for asp.net MVC 3, need to disable http modules

I've a MVC 3 web application using WIF (only thing that matters here is that it's a http module and integrated into the processing pipeline), I've added in normal error handling via global.asax.cs's application_error handler. This works well for most of the cases where the basic application is up and running.
however, there is a class of errors where if the web.config is not configured correctly. (i.e. after a fresh install), the http modules, i.e. WIF assemblies throw exceptions.
I'm trying to put a custom error page for that as well to ask the user to look at the configuration,
however, any page hosted on the same website, even for static html still goes to the standard asp.net error page. My guess is that its still invoking the modules for static pages. Any one have idea on how to disable the httpmodules for certain areas or what the standard practice is?
This is how i'm configuring the custom error page
<customErrors mode="RemoteOnly" defaultRedirect="~/error.htm">
it's a simple static html page. page loads fine when the website is configured properly, but does not show when there is a http module level problem.
You can specify default websites setting in machine.config file. And even protect them from overwrites.
The machine.config file is located in x:\\Microsoft.NET\Framework\\config\machine.config
So if after deployment web.config file will be broken (or some settings) - proper settings will be taken from machine.config.

Why does ASP.NET Routing take precendence over web.config Http Handlers section?

Our shop is integrating ASP.NET MVC into a large web application that utilizes custom & 3rd party HTTP Handlers defined in web.config under system.webServer\handlers. Leveraging HTTP Handlers in this way has been great for us because we don't need to recompile the app or have the actual handler page sitting on disk somewhere in the web scope for each instance of the product.
Is it really necessary to add explicit Ignore Routes in our global.asax so the Runtime can honor our Handlers defined in web.config? I would have thought Web.Routing would be invoked after the handlers defined in system.webServer\handlers have been checked (not the other way around).
We use a modular design that allows adding/dropping Handlers from web.config when features are added. With the introduction of MVC routing it appears we need to add ignore routes in the global.asax file for every possible handler defined in web.config.
Note the actual file to these Handlers don't exist on disk - they are virtual and embedded in an assembly. Here's an example of a 3rd party handler that now requires an explicit Ignore Route in global.asax:
<system.webServer>
<handlers>
<!-- telerik radcontrols -->
<add name="TelerikDialogHandler" verb="*" path="Telerik.Web.UI.DialogHandler.aspx" type="Telerik.Web.UI.DialogHandler, Telerik.Web.UI, Version=2009.1.402.20, Culture=neutral, PublicKeyToken=121fae78165ba3d4"></add>
</handlers>
</system.webServer>
So for the record if you use System.Web.Routing you must include Ignore Routes for Http Handlers specified in Web.Config? Or perhaps I'm doing something wrong?
ASP.NET request processing is based on a pipeline model in which ASP.NET passes http requests to all the modules in the pipeline. Each module receives the http request and has full control over it. Once the request passes through all of the HTTP modules, it is eventually processed by an HTTP handler. The HTTP handler performs some processing on it, and the result again passes through the HTTP modules in the pipeline.
I think that the best way to think about these is that HttpModule is a filter that adds or subtracts something from the request object when an event occurs and the HttpHandler is a processor that actually serves the request. The ASP.NET request lifecycle is setup in such a way that all filters are applied to the request first before processing occurs.

ASP.NET MVC Application in Sharepoint 2007 virtual directory

I have MOSS 2007 installed at lets say http://localhost:4999/ and I want to have my custom ASP.NET MVC (1.0) application at http://localhost:4999/mvcapp/ - logic dictates that, in IIS, i should create a new application virtual directory under my MOSS site and point it at my custom MVC app.
I've done this and it works for executing my controllers etc, however, none of my /Content content is being returned! All referenced images, javascript and css aren't retrieved.
If I put this app into it's own site, or a virtual application within a non-sharepoint site, this works fine and pulls down the images, js and css as normal.
Note - I'm creating a new application in IIS, not just a virtual directory and I have no requirement for integrating with sharepoint, I just want it to have the same domain and port number.
Any ideas?
Cheers
Tony
** EDIT **
To clarify - the URL's that are being generated aren't the issue - they are correct and are being generated in the same way as they would be if this wasn't hosted under sharepoint. IE: /mvcapp/Content/Scripts/jquery.js etc.
** EDIT 2 **
More clarification - the MVC app has it's own web.config file - but it appears that when using a virtual directory withn a sharepoint site, many of the handler mappings still get pushed up to the child site (Note: This is a virtual directory configured as a seperate application not just a virtual directory).
Whilst I don't want or need SharePoint integration, I need my MVC app to come from the same domain and port to overcome some cross domain issues (a lot of MVC content is iframed into sharepoint in various ways). So sharepoint would be at http://site and my app at http://site/mvc
I would keep them on separate web sites (MVC and SharePoint that is). You could create a new website entirely for your MVC app, and then through IIS, right click your MVC web site, edit bindings, and redirect the traffic from your MVC website to URL you want.
I set up a couple of WebForms apps to run in much the same way you say that you want: a separate virtual application with its own web.config, etc. I had to tweak the web.config to make it work, though. My app uses things like session state and view state, but I reckon those aren't applicable to your MVC app. As I look at my web.confing, I think this section might be applicable for what you're trying to do:
<location>
<system.web>
<xhtmlConformance mode="Legacy" />
<trust level="Full" />
<httpModules>
<remove name="PublishingHttpModule" />
</httpModules>
</system.web>
</location>
Hope that helps. I also have an <authorization> section in there, but it wasn't necessary to make the app work.
Look at the following:
Configuring Specific Files and Subdirectories (MSDN)
Disabling Configuration Inheritance For ASP.NET Child Applications (Blog)
HTH

Resources