Yeah, this might sound odd but we have a third party library which enable a sort of service consumed by a JavaScript application. This third party library take care of calling the correct controller and action.
This works all very well but we now need to restrict the routes to this "ServiceController" and maybe one or two other controllers. In the current version (MVC2) we simply override the controller factory which statically checks for a valid controller. Yeah it worked but it was more a workaround which then stayed there forever. So is there any clean way for archiving this (by configuring the routes? Note that we don't use the authorize attribute. And we will be using MVC4 in the next release)
Add global filter and put logic into OnActionExecuting (http://msdn.microsoft.com/en-us/library/gg416513(v=vs.98).aspx)
Option 1: Check routeValues for a correct controller and action
var controllerName = filterContext.RouteData.Values["controller"];
var actionName = filterContext.RouteData.Values["action"];
Option 2: Check this value Request.Url
Actually you allow only the routes defined and nothing else, so the question is really a little odd.
Related
I'm building an API using WebAPI that will be accessed via AJAX calls. However, the API controller will need more than just one POST method. I understand I can specify {action} in my routing, but because I've seen that this is not recommended - am I using the right tool? So 2 questions:
Is Web API the best tool for this, or is there something else I should be using?
Why should I not use more than one POST method in a WebApiController? Is including {action} in my routing a good enough solution to this problem?
1. Is Web API the best tool for this, or is there something else I should be using?
I think WebAPI is a fine choice for you, regardless of whether you have one or many POST calls per controller.
2. Why should I not use more than one POST method in a WebApiController?
To remain RESTFul you'll want a controller per entity type. Without getting too deep into details, a POST against a specific type of entity should be the 'ADD entity' call, and why would you have more than one of those? Having said that, you don't have to be fully RESTFul... if your requirements suite a multi-POST model then go for it, you can always refactor later if necessary.
...Is including {action} in my routing a good enough solution to this problem?
Again, if your goal is to be RESTFul then this isn't a great practice. However, if you have needs that are best achieved using action routings then go for it. REST is not the only model.
I am working on the MVC application that loads controller at runtime from an external assembly with MEF and registers routes using custom route handler I have implemented with help of this tutorial:
http://haacked.com/archive/2010/01/17/editable-routes.aspx/
However recently I discovered a powerful features in MVC 5.1, called Attribute Routing.
I would like to know if that is possible to create a custom Attribute Routing that registers Attribute Routing at runtime?
No. This method basically just turns RouteConfig.cs into a runtime-compiled assembly instead of something that's pre-built by the time your application runs. Frankly, I think that is just about one of the most horrible ideas ever. I give credit to the author for being clever enough to figure out how to do something like that. It's a wonderful thought exercise, but as production code: OMFG, no way.
With Attribute Routing, all your routes are in your controllers, so to do the same thing would require making all your controllers individual runtime-compiled assemblies, and that goes beyond scary. Don't do that.
I have a RouteCollection and a string with an URL.
Has anybody an idea how can I get the name of the route that would be executed?
Some method like RouteCollection.PredictRoute(url) that will return the route name or the physical file that would be executed.
I want to create some statistics from web server log files. It would be very nice to reuse the used RouteCollection for that statistic.
Many thanks!
Here is a snippet of code I used to test that URLs were being mapped to their correct controller and action. You should be able to inspect the route name as well.
RouteConfig.RegisterRoutes(routes);
RouteData routeData = routes.GetRouteData(context);
string controller = routeData.Values["controller"];
string action = routeData.Values["action"];
The variable routes is a RouteCollection object and context is a HttpContextBase object.
I assume you want to do this outside of your MVC application, where requests and contexts are not available (only the log files, as you mentioned).
Unfortunately, that is not very easy to do. In order to write such a matching method you need to reuse (or worse, rewrite) the MVC framework code for URL parsing found in various classes in namespace System.Web.Http.Routing. The source code is available on CodePlex, under Apache 2.0 license.
Instead, I think there's an easier way you can include the route names in the log files and use them later in statistics. Have a look below.
What you could to do is extend the default MvcHandler class and override its ProcessRequest method. In there, you can call the base class implementation and right after it do your stuff by using RequestContext.RouteData.
The class RouteData contains, besides other things, also the current route (which you defined in your route collection. That is accessible through the RouteData.Route property.
This works because MvcHandler is always delegated (unless you've created your own MVC infrastructure) by the MvcRouteHandler, to handle the processing for each request. It is the one that gets the controller data from the existing route data, instantiates an IController implementation, and ultimately executes it.
I would like to build a web application on Castle MonoRail, I was wondering how can we use an action with extension and another action without extension? How can HTML helper generator url for us?
Ex:
http://mysite.com/Products/list
http://mysite.com/Products/abc.castle
The answer is Yes, you can, by using routing.
The exact method you need to use to get the routing working depends upon which version of Monorail you are using. However, adding routing can have some negative impact on performance unless you are careful.
It is also worth noting that you don't have to use the extension ".castle" or ".rails" in case this is what is distasteful to you.
You can try creating a routing role like
/<controller>/<action>.castle
and it would do the trick.
I don't see a need for this. Why would you want to access an action without using .rails or .castle?
I'd like to ignore multiple wildcard routes. With asp.net mvc preview 4, they ship with:
RouteTable.Routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
I'd also like to add something like:
RouteTable.Routes.IgnoreRoute("Content/{*pathInfo}");
but that seems to break some of the helpers that generate urls in my program. Thoughts?
There are two possible solutions here.
Add a constraint to the ignore route to make sure that only requests that should be ignored would match that route. Kinda kludgy, but it should work.
RouteTable.Routes.IgnoreRoute("{folder}/{*pathInfo}", new {folder="content"});
What is in your content directory? By default, Routing does not route files that exist on disk (actually checks the VirtualPathProvider). So if you are putting static content in the Content directory, you might not need the ignore route.
This can be quite tricky.
When attempting to figure out how to map route data into a route, the system currently searches top-down until it finds something where all the required information is provided, and then stuffs everything else into query parameters.
Since the required information for the route "Content/{*pathInfo}" is entirely satisfied always (no required data at all in this route), and it's near the top of the route list, then all your attempts to map to unnamed routes will match this pattern, and all your URLs will be based on this ("Content?action=foo&controller=bar")
Unfortunately, there's no way around this with action routes. If you use named routes (f.e., choosing Html.RouteLink instead of Html.ActionLink), then you can specify the name of the route to match. It's less convenient, but more precise.
IMO, complex routes make the action-routing system basically fall over. In applications where I have something other than the default routes, I almost always end up reverting to named-route based URL generation to ensure I'm always getting the right route.