.NET MVC Routing works, except for one piece - asp.net-mvc-3

Little help here and advice.
Working on my first MVC application and I've got an entity of Students setup.
Student Controller and views with basic CRUD capabilities.
mysite.com/Student gets me there.
Now I want to add Payments, so I've added a Payments controller and views with basic crud.
that gives me mysite.com/Payments
I want payments to go a URL that looks like: mysite.com/Student/Payments
So I researched URL routing and (I think) I had it backwards for a long time as nothing seemed to work. But now, I've created this additional Route:
routes.MapRoute(
"Payments",
"Student/Payments/{action}/{id}",
new { Controller = "Payments", action = "Index", id = UrlParameter.Optional }
);
And now it all seems to work properly. When I send an ActionLink to any action in the Payment controller, the URL is correct. For example: www.mysite.com/Student/Payments/Edit/5 comes up as the URL.
The problem I'm having is that Payments is still a base URL route. So I can also get to payments by going to www.mysite.com/Payments
How do I "remove" that route, so that mysite.com/Payments is not valid? Or am I doing this all ass-backwards in some way?
Any help appreciated.

Your kind of thinking about it the wring way around. The mapping configuration just supplies a hierachical list of rule to specify where a particular url's code lives.
So when you say it's still hitting mysite.com/Payments. That's because it's hitting the default rule in your Global.asax
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional} // Parameter defaults
);
You could remove this but then no default rules will work.
or you can add an ignore rule. In your case something like
routes.IgnoreRoute("Payments/{action}/{id}");
make sure you put this above the default rule.

You need to use overload of MapRoute method for your default route i.e.:
routes.MapRoute(
"Default",
"{controller}/{action}/{id}",
new { controller = "Home", action = "Index" },
new { controller = ""}); //there constraints for controller goes
Look at this blog post about creating custom constraints, there is example for "not equals"

Related

MVC3 Url Routing to create member area

I would like to create a member area on my site with the following URL patterns:
Pattern for logged out user:
domain.com
domain.com/About
domain.com/Blog
domain.com/Blog/1 (where 1 is the post ID)
But I also have a member area where I prefix the Url with Member like this:
domain.com/Member/MyProfile
domain.com/Member/MySettings
This seems simple, but I can't see an obvious way to make routing rules for this. I have:
routes.MapRoute(
"Member", // Route name
"Member/{controller}/{action}/{id}", // URL with parameters
new { controller = "Task", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);
This works great for the member when you are logged in, but unfortunately the first rule also matches the logged out view and Url.Action("Blog", "Home") produces a Url that looks like this:
domain.com/Member/Home/Blog
How do I tell Url.Action that it must form Urls with the default rule outside the member area?
You could use a real MVC area instead of trying to simulate one. There's also a video you might checkout. The idea is that you leave your default route definition in Global.asax and then add a Member area to your site which will have a separate route configuration.

Controller not being properly activated

I have added a controller to my project named UserManager (automatically generated from the ado.net framework)
When I start the application, attempts to navigate to http://server/UserManager/ are met with a 404 error, but if I go to http://server/UserManager/Index the action is found and executes properly.
Is this a case of the controller not being called or is it just not treating index as the default action. Where are these properties set?
UPDATE
It seems that the problem derived from the fact that the default route is set to
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Permits", action = "ListApplications", id = UrlParameter.Optional }
This conflicts with the naming scheme for Usermanager (where the default is Index)
I struggled with ohow to add alternate routes that provided for default actions, but eventually figured out that the order of route addition determines which route takes the request (the earlier the route is added, the more chances it has to meet the criteria.)
Thanks
You need to ensure that the default route mapping specifies "Index" as the default action in your global.asax file.
Check that you have the following setting in your global.asax file:
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
IN REPLY TO YOUR COMMENT:
Only by way of adding new route mappings. You also need to be aware that the first matching route mapping will be applied, so the order you specify the mappings in Global.asax is crucial.
For example, we wanted our FAQ controller to work with a URL http://domain/faq/{id} without the action specified in the URL, so we declared the following mapping before the default:
routes.MapRoute("Faq", "Faq/{id}", new { controller = "Faq", action = "Answer" });
In Global.asax.cs, check the default route is set up:
routes.MapRoute(
"Default",
"{controller}/{action}/{id}", new {
controller = "Home",
action = "Index",
id = UrlParameter.Optional}
);
Also, check that the controller is called UserManagerController, and derives from Controller

Routes and Url helpers confusion

I'm a little confused on the MVC front for this reason, I have the following default route defined;
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);
When I use a Url helper, i.e.
#Url.Action("MyAction")
it generates this url;
/?action=MyAction&controller=MyController
and never finds my action method. How are the Urls generated by the helpers and how do I correct this?
Just use the overload to specify the action and controller:
#Url.Action("MyAction", "MyController")
If you use the overload which only takes the action name, the controller is taken from the current route data. Default routing doesn't come into it.
i.e.
#Url.Action("MyAction")
is equivalent to
#Url.Action("MyAction", (string)ViewContext.RouteData.Values["controller"])
I had the same issue, I had a web app that was built used WebForms and slowly migrating parts to MVC, to support both I had a route entry which ended up breaking the routing evaluation code and caused the funny action urls
this blog post fixed my issue

ASP.NET Controller name conflicted with a folder name

In my ASP.NET MVC3 project, I have a folder called Content (the default folder for an MVC project). But I also have a controller called Content. And when I want to use the default actions of this controller, I simply use http://domain/content/, which is equivalent to http://domain/content/index. But IIS returns 403 error and thinks that I'm gonna get the directory list of the Content Folder. Well, this question is already discussed in this question. But I don't know how to rewrite my URL to append the default action to it. May someone help please.
You can get around this by changing routing configuration to specify:
routes.RouteExistingFiles = true;
You will then need to set up some ignore rules to prevent genuine static content being gobbled up by the routing engine.
For example, I have a folder called Touch in my app, and I also have a specific route for Touch. So the working config is:
routes.RouteExistingFiles = true;
routes.IgnoreRoute("Touch/Client/{*touchclientversion}", new { touchclientversion = #"(\d*)(/*)" });
I agree that this kind of thing should generally be avoided, but sometimes it's nice to have pretty URLs :-)
You can add a default route like this:
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = "" } // Parameter defaults
);
In your case:
routes.MapRoute(
"DefaultContent", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Content", action = "Index", id = "" } // Parameter defaults
);

Make three-part route url for controller in ASP.NET MVC3

I am using ASP.NET MVC3 and curious about how to make routes like /Account/Ajax/Action map to controller AccountAjaxController method Action
Is there any way to do so?
Already solved issue using following code in Global.asax.cs file:
routes.MapRoute(
"Default",
"{controller}/{action}/{id}",
new {controller = "Home", action = "Index", id = UrlParameter.Optional},
new[] {"MyProjectName.FrontEnd.Web.Logic.Controllers"}
);
routes.MapRoute(
"Ajax",
"Ajax/{controller}/{action}/{id}",
new[] {"MyProjectName.FrontEnd.Web.Logic.Controllers.Ajax"}
);
One way that I've done this is with RouteCollection.MapRoute(). See http://msdn.microsoft.com/en-us/library/dd470521.aspx. You can do all kinds of stuff with routes.
In the code below I would typically call this from my global.asax.cs Application_Start():
RouteCollection routes = RouteTable.Routes;
routes.MapRoute(
"ArbitraryRouteName", // Route name
"Account/Ajax/Action/", // URL with parameters
new
{
controller = "AccountAjax",
action = "Action"
}, // Parameter defaults
new
{
}
);
There are many ways to use this in order to generate links. You can use Html.RouteLink() in your views as an example. I believe that you can also call Html.ActionLink("link text", "AccountAjax", "Action"). I think that providing there is only one Route mapped to your controller and action name, ASP.NET MVC automatically figures out the proper URL to generate from your route mappings.
See http://msdn.microsoft.com/en-us/library/dd492585.aspx for an example of the RouteLink extension method.

Resources