Can I modify an MVC route outside of Global.asax? - asp.net

Is it possible to modify the the routes (and thus the RouteTable) outside of the global.asax file, maybe in a controller? Is this even advisable?
My reason for asking has to do with IIS 6 and Integrated Mode not allowing for Request context calls. I'm implementing internationalization for a site and keeping track of the culture in the URL. The culture is originally read from a .config file and loaded as a route default. This file read is what ends up throwing the error (another few steps up the stack). I based this off the method described here.

You can access the routing table pretty much anywhere like so System.Web.Routing.RouteTable.Routes, have tested this from a controller and it worked fine.

Related

HttpHandler with a different extension to .ashx

I've got an image handler on my site which works on the url below. Obviously with being an asp.net httphandler it has the .ashx extension, even though it returns content with mime type image/jpeg
https://xxxxx/image.ashx?id=78164&imagelibraryid=0404fd0c-e681-4a5c-9899-f2709aaf7e0c
We want to use cloudflare for caching and serving images, but for it to work properly you have to use image urls with standard extensions i.e. jpg/gif/png etc.
Is there anyway my httphandler can detect and process any requests to image.jpeg?
Only image.jpeg should be handled by the httphandler, any other XXX.jpeg would still need to be served from the filesystem.
Is it possible?
Thanks
I think you have three options to allow you to serve the same images with a new url that looks like:
https://xxxxx/something-custom/images/78164/0404fd0c-e681-4a5c-9899-f2709aaf7e0c.jpg
Option one - use IIS rewrite rules to serve publically on one url that has proper extensions and rewrite the address inside the webserver so that the fragments get passed into the ashx handler.
Option two - use aspnet routing, originally designed for MVC, with a bunch of plumbing code to pass the data between the two paradigms, as detailed in this SO question
Option three - rewrite the code by moving it out of ashx into a new api controller as ashx handlers are a bit dated these days and mvc and model binding are often easier and more testable. Most of the core logic can probably be done quickly with lift and shift, and just use routing and mvc to map the new url fragments into variables consumed by your business logic.

How to call a local HTTP Handler

I've got a HTTPHandler which returns either an image or some text and want to call it from the local web-app.
One way to do it would be to create a WebClient and point it at the handler and download the data that way but this will have problems when authentication is turned on in production and also doesn't seem that efficient. Is there a better way to do this?
The reason I'm trying to do this is that I have a page which injects content from other sources into panels, some of the resources are local (to the web-app) and others are remote, I wanted one solution to cover every possibility so I can change the source fairly easily.
One of the simplest way is to link the content i.e. use html elements such as image, Iframe and point their source to the handler in question. It will work with local as well as remote handlers as long as URLs are accessible from client/browser.
If you must get the content for some kind of processing etc, then you may use WebClient to download the content - it anyway support HTTP based authentication schemes (including windows/integrated authentication) so it shouldn't be an issue.
If you want to optimize the process for local handlers then you probably need to abstract the interface for content provider - you can have two implementations (one that use WebClient to get remote content and other that will probably use the native API of local handler class directly to get the content).
Extract the code from your handler to a separate assembly
Reference this assembly in the project that has HTTP Handler and make the handler just call your shared code
Reference this assembly in your web app project.
You might want to create a provider for your web app that will either use an assembly in-proc or go to a remote site.

Can MVC handle regular URL path requests, too?

ASP.NET MVC newbie question:
I've set up a MVC site, with a few controllers. Now my site also has a lot of content files, which are stored in a network of subfolders within my web site, and I need to be able to access them directly, e.g.
http://mydomain.com/Content/Images/Geography/Asia/Japan/TokyoAtNight.jpg
Is there a way to make this a direct pass-through to the content folder, as specified by the path, or do I have to make a Content controller that interprets the rest of the URL and returns the file as some kind of ActionResult? Bear in mind, of course, that there will be lots of different content types, not just JPEGs.
Thanks for your help!
This should work without you doing anything - static files are not processed by the routing engine.
You want to look into Routing, and IgnoreRoute specifically. Here are a couple of places to start.
Asp.Net Routing: How do I ignore multiple wildcard routes?
http://www.asp.net/mvc/tutorials/asp-net-mvc-routing-overview-cs
Take a look at the #Url.Content() helper method.
Url.Content("~Content/Images/Geography/Asia/Japan/TokyoAtNight.jpg")
Yes.
The IRouteHandler and the route registration in your global.asax is your extensibility point for configuring how MVC handles url paths.
However, by default ASP.NET MVC will allow you to access image files directly, without any additional configuration.

ASP.NET Friendly URLs

In my research, I found 2 ways to do them.
Both required modifications to the Application_BeginRequest procedure in the Global.Asax, where you would run your code to do the actual URL mapping (mine was with a database view that contained all the friendly URLs and their mapped 'real' URLs). Now the trick is to get your requests run through the .NET engine without an aspx extension. The 2 ways I found are:
Run everything through the .NET engine with a wildcard application extension mapping.
Create a custom aspx error page and tell IIS to send 404's to it.
Now here's my question:
Is there any reason one of these are better to do than the other?
When playing around on my dev server, the first thing I noticed about #1 was it botched frontpage extensions, not a huge deal but that's how I'm used to connecting to my sites. Another issue I have with #1 is that even though my hosting company is lenient with me (as I'm their biggest client) and will consider doing things such as this, they are wary of any security risks it might present.
`#2 works great, but I just have this feeling it's not as efficient as #1. Am I just being delusional?
Thanks
I've used #2 in the past too.
It's more efficient because unlike the wildcard mapping, the ASP.NET engine doesn't need to 'process' requests for all the additional resources like image files, static HTML, CSS, Javascript etc.
Alternatively if you don't mind .aspx extension in your URL's you could use: http://myweb/app/idx.aspx/products/1 - that works fine.
Having said that, the real solution is using IIS 7, where the ASP.NET runtime is a fully fledged part of the IIS HTTP module stack.
If you have the latest version of IIS there is rewrite module for it - see here. If not there are free third party binaries you can use with older IIS (i.e. version 6) - I have used one that reads the rewrite rules from an .ini file and supports regular expression but I cant remember its name sorry (its possibly this). I'd recommend this over cheaping it out with the 404 page.
You have to map all requests through the ASP.NET engine. The way IIS processes requests is by the file extension. By default it only processes the .aspx, .ashx, etc extensions that are meant to only be processed by ASP.NET. The reason is it adds overhead to the processing of the request.
I wrote how to do it with IIS 6 a while back, http://professionalaspnet.com/archive/2007/07/27/Configure-IIS-for-Wildcard-Extensions-in-ASP.NET.aspx.
You are right in doing your mapping from the database. RegEx rewriting, like is used out of the box in MVC. This is because it more or less forces you to put the primary key in the URL and does not have a good way to map characters that are not allowed in URLs, like '.
Did you checked the ASP .Net MVC Framework? Using that framework all your URLs are automatically mapped to Controllers which could perform any desired action (including redirecting to other URLs or controllers). You could also set custom routes with custom parameters. If you don't have seen it yet, maybe it will worth the look.

ASP.NET URL rewriting not working with folder URLs

I wrote a custom URL rewriting module, to take certain paths and map them to our catalog out of the database.
I am using the technique outlined in the link at the bottom of my post.
I'm using .NET 3.5. The problem is that it only works when there is a page name on the end of the original URL, but if the page name is left off, then it never even calls my handler.
So for example, the URL
http://mysite.com/folder/index.aspx works but
http://mysite.com/folder/ does not.
The one with just the folder never gets into my handler class at all. Is there something you need to do to enable folders to work properly?
http://www.simple-talk.com/dotnet/asp.net/a-complete-url-rewriting-solution-for-asp.net-2.0/
Is a know issue when using .NET rewriting. You need to correctly configure the wildcard mapping. Here is a good link:
http://devtalk.dk/2007/03/19/Wildcard+Mapping+And+URL+Rewriting+On+IIS7.aspx
Another option will be rewriting by IIS ISAPI with regular expressions.
In my company we actually use both.
Check out this link for references:
http://www.kowitz.net/archive/2006/09/15/url-rewriting-using-ihttpmodule-vs-isapi-rewrite.aspx
I'm not sure how to solve it but the reason is becaus IIS is treating it as a directory (which it is) and doesn't have any knowledge about how to pass the folder to the ASP.NET isapi filter and trigger the .Net handler.
You could try doing it with IIS7 and inserting the handler in the actuall IIS pipeline. Or check the bottom of the article you referenced below the heading "Using RewriteModule".

Resources