MVC controller id with further actions - c#

So currently been trying to make a website (relatively new with MVC). Say I have the current link:
www.website.com/Project/3
Which works fine. However Inside that project, I am wanting the 3 to pretty much always be there to specify the project in a better manner (as people can have multiple projects). So if they go to a page inside the project I want it to look like so:
www.website.com/Project/3/CreateOption
I have been trying to think about a way to do it, but can't think of any nice way to do it. Done research but either can't figure out what to write into google, or it is impossible.
If anyone could help that would be awesome! If you need more information please let me know.

Not sure your version of MVC.
But Attribute Routing in ASP.NET MVC 5 is what you are looking for

This is relatively easy to do.. if your url structure is very defined. If you don't need standard default routing, then it's just as simple as doing this:
routes.MapRoute(
name: "Project",
url: "Project/{projectId}/{action}",
defaults: new { controller = "Project", action = "Index" }
This will require that the projectId be present.
Then, in your action method, you would have:
public ActionResult Index(int projectId)
{
}
public ActionResult CreateOption(int projectId)
{
}
The key here is that projectId is mandatory, and not optional, and that your route path is hard coded to Project.
You can default action to Index or whatever you like so that /Project/3 results in a default action, as shown above. Or you can make the action mandatory as well. If you need additional parameters, you can also add those as well if they need to be part of the url.

Related

Multiple URL routes to a single action method

This is probably something very simple, but Googling feebly isn't getting me anywhere.
In the web application we're building, we've got Projects, and Templates. Templates are really just Projects, with the IsTemplate flag set to true. So naturally, we've got a single Project controller that handles (or will handle) both cases.
We've got one route to a New action method on the controller:
Project/New
That's just the standard {controller}/{action}/{id} route handling that one. Now, the New action method has an IsTemplate parameter. I'd like to have one route where that's passed in as false (the one above), and a second one where it's passed in as true:
Templates/New
What's the proper way to mask an arbitrary action method parameter with varying URLs like that? I tried the following, but it just confused the routing (Html.ActionLink ends up pointing at Templates/New):
routes.MapRoute(
null,
"Template/New",
new { controller = "Project", action = "New", IsTemplate = true }
);
Or would it be a lot simpler for me to just split this into two action methods, and have those call a single private controller method with a hard-coded parameter value?
Seems like this might be the simplest option. I've split the single New action method into two action methods, both of which have different routes defined, and a third private method that does all the work. I'm still open to recommendations if there's a prettier way to do it.
[HttpGet]
//Action method for a new template
public ActionResult NewTemplate() {
return New(true, null);
}
[HttpGet]
//Action method for a new project
public ActionResult New(int? TemplateProjectID) {
return New(false, TemplateProjectID);
}
private ActionResult New(bool IsTemplate, int? TemplateProjectID) {
//Assorted code follows
Perhaps RouteUrl can help you?
If you named the route to TemplateNew for example, you should be able to create an url for that:
New Template

Handling extra MVC parameter with different ActionResult

I'm working on a website that has 4 individual sections, each with their own controller. These controllers share a few models, however the model will do things slightly differently based on the controller calling it.
The route that I'd like to follow is {controller}/{model}/{id}/{action} so I could use controller1/cars/5/edit rather than controller1/editcar/5.
Is there any way to have my controller understand a model+action combination and handle them with different ActionResults, or am I forced to use an ActionResult on the model name and then use a conditional to figure out what action to take?
In Ruby I could use get "/controller1/cars/:id/edit" do. I'm just looking for something similar in MVC4.
Example routs:
/controller1/cars
(returns a view containing all cars from controller1)
/controller1/cars/5
(returns a view containing car with the ID 5 from controller1)
/controller1/cars/5/edit
(returns a view to edit car with ID 5 from controller1)
/controller2/cars
(returns a view containing all cars from controller2)
/controller2/boats
(returns a view containing all boats from controller2)
I think this route meets your needs. It requires some clever logic in your action methods but should give you the tools to handle it. Read my description of behavior.
routes.MapRoute(
"Default", // Route name
"{controller}/{model}/{id}/{action}", // URL with parameters
new { controller = "Home", action = "View", id = UrlParameter.Optional } // Parameter defaults
);
This route will Default to an action called View (that will presumably be used for Display) and has an option to direct to a different Action.
Model and id will be passed as arguments to you action method. Unfortunately, Model will not be sent as a type but a string (you may feed that into a Factory class).
if if is left out (eg /controller2/boats) it will be passed to your action as a null. This requires logic to handle but gives you the tools to handle it.
Thanks for the responses. The reason that I was having so much trouble with this was because I couldn't figure out how to separate controllers with a rout properly. This resulted in my idea breaking away from MVC standards and almost trying to implement a controller of controllers.
When I finally stumbled upon "Areas", I quickly realized that this is what I needed. I was able to add an Area for each section (or area) of my website, and within each area, I could define individual controllers and views, while my models remained in a shared directory outside of all areas. This now works perfectly.

Correct terminology and examples for nesting/routing views in ASP.NET MVC

I have been doing ASP.NET for a while, and have done very little in MVC (in general), but very new at the ASP.NET MVC framework, as well as the correct terminology on a few things.
Here is my example (actual application I am working on is different, but this is a public example I can use) - I want to create a simpler version of Redmine, but in .net.
I want to list issues, in such a way that if I go to example.org/issues, I see a list of all issues (similar to http://www.redmine.org/issues), across all projects.
But if I go to the project, as in example.org/project/issues, I see just the issues for that project (similar to http://www.redmine.org/projects/redmine/issues). This would be the same for example.org/project2/issues, etc.
What is the correct term for this? I would assume that the developers didn't rewrite the 'issues' code in two places, that they reused this code.
Since I don't know the fully correct term for this, it is hard to find good examples in the ASP.NET MVC world that I can start with. So the second part of this, is what would be an example that I could look at in ASP.NET MVC, and how should this look in Visual Studio to me?
There would also be several other things under /project/, like settings, details, logs, etc, similar on how one would navigate http://www.redmine.org/projects/redmine/.
Finally, what if projects was not on the top level? As in, what if my application was more like:
example.org/
example.org/projects/
example.org/projects/project1
example.org/projects/project1/issues
example.org/projects/project2
example.org/dashboard/
Set up one controller called whatever you'd like (I'll use RedMineController).
In that controller you'll have a single action method named ListIssues. Accept a parameter named ProjectName:
public ActionResult ListIssues(string projectName) {}
Lastly create two routes in your global.asax.cs:
routes.MapRoute(
"Issues Root",
"issues",
new { controller = "RedMine", action = "ListIssues" }
);
routes.MapRoute(
"Project Issues",
"projects/{projectName}/issues",
new { controller = "RedMine", action = "ListIssues" }
);
In your ListIssues action, check if projectName == null, and if so get all issues, otherwise get specific ones. The first route will pass null, the second will pass what is in the URL. Don't forget to throw a 404 if the project name in the URL is invalid.
Hope this helps!
well though not a proper ans. but you can do what you want easily by just reversing the way you are doing them.. ie
instead of doing www.example.org/project/issues do www.example.org/issues/projector just www.example.org/issues
this way you can easily make a issues controller and everything in the url after issues can be this string by which you would be able to determine the resource for which you need to list all the issues. an example route for it can be
"{issues}/{*resource}",new{controller="issues"}

Custom MVC route: changing where the views for a controller are located

So I have a controller called EmployeeController, and all the Views are in /Employee.
I'd like to create a route so that the EmployeeController will use /Employees and /Employees/Add instead of /Employee and /Employee/Add.
I keep finding articles about how to change the route to go to different actions, but I couldn't find any way to do this.
I think you're confusing Views with Routes. ASP.NET MVC relies a lot on convention, and in this example it takes the controller component of the route an applies it to find the controller. You can define a new route:
routes.MapRoute("Employees", "employees/{action}", new {
controller = "Employee",
action = "Index" });
Actually, there are 2 different questions:
First one is about routes mapping and here I'd agree on simple solution suggested by Matthew Abbott and Bugai13.
Second one is about "Views" folder conventions and View files resolution. If you want some custom logic about that you may inherit ViewResult and change the way it finds the appropriate View file. You can also dive deeper into framework and tweak the way View is found and instantiated by creating your own IViewEngine or customizing one of those already existing.
It seems though, that all you need is first thing - just provide more specific route mappings with URL pattern like employees/{action} and you're done.
Why not just rename EmployeeController to EmployeesController? Then you don't have to mess with the route.
Of course you will then have to change your Views\Employee folder to Views\Employees as well.

MVC Routing - Parameter names question

I'm looking for some information on Routing in MVC with C#. I'm currently very aware of the basics of routing in MVC, but what i'm looking for is somewhat difficult to find.
Effectively, what I want to find is a way of defining a single route that takes a single parameter.
The common examples I have found online is all based around the example
routes.MapRoute(
"Default",
"{controller}.mvc/{action}/{id}"
new { controller = "Default", action="Index", id=""});
By mapping this route, you can map to any action in any controller, but if you want to pass anything into the action, the method parameter must be called "id". I want to find a way around this if it's possible, so that I don't have to constantly specify routes just to use a different parameter name in my actions.
Has anyone any ideas, or found a way around this?
If you want to have a different parameter name and keep the same routing variable, use the FromUri attribute like so:
public ActionResult MyView([FromUri(Name = "id")] string parameterThatMapsToId)
{
// do stuff
}
In your routes, all you need is:
routes.MapRoute(
"Default",
"{controller}.mvc/{action}/{id}"
new { controller = "Default", action="Index", id=""});
I don't think that you can do exactly what you are asking. When MVC invokes an action it looks for parameters in routes, request params and the query string. It's always looking to match the parameter name.
Perhaps good old query string will meet your needs.
~/mycontroller/myaction/?foobar=123
will pass 123 to this action:
public ActionResult MyAction(int? foobar)
I know this is centuries ago, but hope it still helps someone. I asked the same question before. I think this is what you are looking for. An answer quoted from my question post:
"The {*pathInfo} bit is called a slug. it's basically a wildcard saying "everything after this point is stuffed into a parameter called pathInfo". Thus if you have "{resource}.axd/{*pathInfo}" and a url like this: http://blah/foo.axd/foo/bar/baz/bing then two parameters get created, one called resource, which would contain foo and one called pathInfo which contains foo/bar/baz/bing."
You can construct the routes as you like
routes.MapRoute(
"Default",
"{controller}.mvc/{action}/{param1}/{param2}/{param3}"
new { controller = "Default", action="Index", param1="", param2="", param3=""});
Also, look at this post, it contains all kind of samples in the comments section
Although you still can't use the FromUri attribute, you can however use the Route attribute, like so
[Route("~/Policy/PriorAddressDelete/{sequence}")]
public ActionResult PriorAddressDelete(int sequence)
{
Policy.RemoveScheduledPriorAddressItem(sequence);
return RedirectToAction("Information", new { id = Policy.Id });
}
Technically this adds a new route, but at least it doesn't clutter up your routeconfig. It puts the route definition right by where it's used, which I like (less hunting things down).
Remember, in order to use attribute routing, this must be in your routeconfig file above your defined routes:
routes.MapMvcAttributeRoutes();

Categories

Resources