MVC 3 Route question - asp.net-mvc

I'm trying to put in some new routes but not sure where to start. What I would like to do is to have my routes translate as follows:
/transport class A/23 translated to /info/classes/A-23
I understand the basics of using MapRoute but can I do things like the above?
I hope someone can give advice.

This seems to me that you're actually after something like UrlRewrite since you're going from one Url to another.
But MVC doesn't rewrite Urls - it maps them to controller actions based on route patterns you provide.
So, if you're asking if you can split up the first url to a controller/action pair (with parameters) then of course you can. You just set up a route with the necessary parameters in the right place. So you could call MapRoute with something like (I would use hyphens for the spaces):
/*route pattern:*/ "transport-class-{class1}/{class2}"
/*with route defaults:*/ new { controller = "Info", action = "ViewInfo" }
Then you could write a controller as follows:
public class InfoController : ControllerBase
{
public ActionResult ViewInfo(string class1, string class2)
{
//presumably get model data from the class parameters here
//and pass it as parameter to below:
return View();
}
}
Although it would depend also if the transport and class constants in this route are actually also variable I guess - in which case you could push those down as route parameters, and into the parameter list of your controller method.

Related

MVC Routes With Embedded IDs

We want to have a route that looks like this:
/account/123/dosomething/234
In this case, account would be the controller and requesttrafficid would be the action, I guess. I am assuming I can define this route like this:
{controller}/{accountId}/{action}/{id}
In this case, the two IDs just become parameters of the action.
The question is: can do something like this for Web API?
Our normal MVC controllers are just returning views and other static content.
All of our data comes from the API.
We want our routes to be as close as possible, something like this:
api/account/123/dosomething/234
Based on my understanding, account wouldn't be the API controller, it would be dosomething. The two IDs just become parameters again. But how do I define this route? Do I just hard-code the 'account' part?
If you're only concern is being able to make the action portion of the route the same, you have two choices:
You're not required to use the naming convention of [Method]Action. If you don't follow this convention, you just need to specify which method applies with the appropriate attribute:
// These are functionally equivalent:
public JsonResult GetSomething(int id) { ... }
[HttpGet]
public JsonResult DoSomething(int id) { ... }
If you want to follow convention, but you want to customize the action name for routing purposes, you can use the ActionName attribute:
[ActionName("dosomething")]
public JsonResult GetSomething(int id) { ... }
With AttributeRouting, this is a piece of cake: http://attributerouting.net. You just put the placeholders at the right spot in your URL and MVC handles the rest.

ASP.NET MVC Dynamic Action with Hyphens

I am working on an ASP.NET MVC project. I need to be able to map a route such as this:
http://www.mysite.com/Products/Tennis-Shoes
Where the "Action" part of the URL (Tennis-Shoes") could be one of a list of possibilities. I do not want to have to create a separate Action method in my controller for each. I want to map them all to one Action method and I will handle the View that is displayed from there.
I have this working fine by adding a route mapping. However, there are some "Actions" that will need to have a hyphen in them. ASP.NET MVC routing is trying to parse that hyphen before I can send it to my action. I have tried to create my own custom Route Handler, but it's never even called. Once I had a hyphen, all routes are ignored, even my custom one.
Any suggestions? Details about the hyphen situation? Thanks you.
Looking at the URL and reading your description, Tennis-Shoes in your example doesn't sound like it should be an action, but a Route parameter. Let's say we have the following controller
public class ProductsController : Controller
{
public ActionResult Details(string product)
{
// do something interesting based on product...
return View(product);
}
}
The Details action is going to handle any URLs along the lines of
http://www.mysite.com/Products/{product}
using the following route
routes.MapRoute(
null,
"Products/{product}",
new
{
controller = "Products",
action = "Details"
});
You might decide to use a different View based on the product string, but this is just a basic example.

Combining values in ASP.Net Routes for MVC

Can anyone suggest a way to accomplish the following in ASP.Net Routing (for MVC 3)?
I want to have URLs where the value which determines the controller is actually part of the id for the page:
/{id}-{controller}/{action}/{further-values}
But I need the id value to include the value used for the controller as well, so in the above if we have the following URL:
/chelsea-football-team/view/2010-2011
I want the {id} value to, ideally, be "chelsea-football-team", the controller to be "football-team", the action to be "view" and the additional value to be "2010-2011".
I have no issues having several routes with the controller value hard coded into the route definition, but I need to be able to have several controller values.
I know that I can simply combine the values in the controller, but that adds a lot of additional, repeated code - so is this accomplishable in any other way?
Why do I want to do this? Because I need to have the team name in full, but part of the team name will always match the controller name so why not combine them in the route?
I want the {id} value to, ideally, be "chelsea-football-team", the controller to be "football-team", the action to be "view" and the additional value to be "2010-2011".
...MapRoute(null, "{id}/{action}/{*furtherValues}",
new {
controller = "FootballTeam",
});
Update after comment 1
You can't combine route parameters in a URL such that a single parameter represents both a variable (id) and a controller, using the standard routing implementation. If you want the id to be "chelsea-football-team", that has to be a self-contained route parameter. You can't combine it in a way that MVC extracts the controller name from the id.
To meet this requirement, you may have to create a custom RouteBase implementation:
public class MyCustomRoutingPattern : RouteBase
{
public override RouteData GetRouteData(HttpContextBase httpContext)
{
// do your coding and return an instance of RouteData
}
}
You would then use it like so:
routes.Add(new MyCustomRoutingPattern(
"{id}/{action}/{*furtherValues}"));
Your RouteBase implementation can then extract the controller from the id parameter. The Pro ASP.NET MVC3 Framework book by Steve Sanderson and Adam Freeman has a section on how to override the RouteBase class.

ASP.Net MVC Route not passing parameter to controller

I'm trying to learn MVC and having a rough start.
routes.MapRoute(
"Test",
"Test/{stringInput}",
new { controller = "Test", action = "TestMethod", stringInput = "" }
);
doesn't pass stringInput to the method TestMethod in the controller. It comes over null.
Not sure what I'm missing, it seems very simple and straightforward. This route was placed above the default.
Override the Execute method of your controller and then put a breakpoint in it so you can see the request context. One of the properties is the key/value pair being passed in. Make sure the key for stringInput has the correct value.
Make sure your controller is setup properly. It should be in folder
Controllers/TestController.cs
and inside the controller should be
public ActionResult TestMethod( string stringInput )
{
return View();
}
It uses conventions, so the naming you setup in your route needs to match the files, methods, and parameters of the controller.
The url to get to this should be
/Test/TestMethod/MyStringInput
and "MyStringInput" would be the value of the variable stringInput.
Are you sure that route is the one being used? Try moving it to the top of your list of routes to make sure.

Areas And Routes

I'm using areas everywhere and I'm wanting something like the following:
http://localhost/MyArea/MySection/MySubSection/Delete/20
Usually I access things by doing the following:
http://localhost/MyArea/MySection/MySubSection/20
But if I want to delete then I have to say
http://localhost/MyArea/MySection/DeleteEntryFromMySubSection/20
With routes, how do you do this? (the routes aren't realistic by the way, they're much more concise than this in my system)
EDIT: This is specifically related to the use of Areas, an ASP.NET MVC 2 Preview 2 feature.
It would depend on how your routes & controllers are currently structured.
Here's an example route you might want to use.
If you want to be able to call the following route to delete:
http://localhost/MyArea/MySection/MySubSection/Delete/20
And let's assume you have a controller called "MyAreaController", with an action of "Delete", and for the sake of simplicity let's assume section and subsection are just strings e.g.:
public class MyAreaController : Controller
{
public ActionResult Delete(string section, string subsection, long id)
{
Then you could create a route in the following way (in your Global.asax.cs, or wherever you define your routes):
var defaultParameters = new {controller = "Home", action = "Index", id = ""};
routes.MapRoute("DeleteEntryFromMySubSection", // Route name - but you may want to change this if it's used for edit etc.
"{controller}/{section}/{subsection}/{action}/{id}", // URL with parameters
defaultParameters // Parameter defaults
);
Note: I'd normally define enums for all the possible parameter values. Then the params can be of the appropriate enum type, and you can still use strings in your path. E.g. You could have a "Section" enum that has a "MySection" value.

Resources