Routes and Url helpers confusion - asp.net-mvc-3

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

Related

difference between URL rewriting and URL routing mvc

I am trying to learn MVC and need help in understanding the difference between URL rewriting and URL routing in MVC.
URL Routing is the routing done by MVC which is , When we type something in the url space, then it will first invoke the
RouteConfig.RegisterRoutes(RouteTable.Routes);
which is in Global.asax.cs Application_Start() method if you put a break point in that then you could understand the routing method , then it will call the
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
Which is in App_start=>RouteConfig class you can find out the RegisterRoutes method here . Here we can define the structure of our url and here it will decide which controller and action should be invoked.
This process is url Routing
URL rewriting is entire diff concept
Let us assume our controller name is Customer and action name is Login
when we run the application our url will be like the below
http://Localhost:233/Customer/Login
but the client ended http://Localhost:233/Login only, for SEO purposes
In order to achieve this we have to rewrite the url by keeping the same controller and action name
to know more about url rewriting i have explained attribute rewriting in http://grandhah.blogspot.in/2015/07/url-rewriting-in-mvc-4-attribute-routing.html Please visit and let me know you are clarified enough.. good day

MVC3 MapRoute to convert aspx query params into the route

I'm working on a project to rewrite an aspx site as MVC3. I want to make the old URLs work on the new site. I have named my controllers and actions such that the URLs actually contain enough info in the query string to route correctly but I'm having trouble getting the routing to work since it doesn't like the ? in the URL.
Basically I have old URLs like this:
www.example.com/Something/SomethingElse/MyPage.aspx?Section=DetailSection&TaskId=abcdef
I tried to create a route using:
routes.MapRoute(
"OldSite",
"Something/SomethingElse/MyPage.aspx?Section={action}Section&Id={id}",
new { controller = "Task", action = "Index", id = UrlParameter.Optional }
);
I want it to route to the correct new URL which is:
www.example.com/Task/Detail/abcdef
I know that all traffic to the MyPage.aspx page should go to my new Task controller and the beginning of the Section parameter always matches one of a few corresponding actions on that controller.
Unfortunately I have found that I get an error that a route can't contain a question marks. How should I handle this? Would it be better to use URL rewriting? Because this is a private site I'm not concerned with returning permanent redirects or anything - no search engine will have links to the site anyway. I just want to make sure that customers that have a URL in an old email will get to the right page in the new site.
In this one case I think the simplest way would be to have your old page mapped to a route:
routes.MapRoute(
"MyPage",
"Something/SomethingElse/MyPage.aspx",
new { controller = "Task", action = "MyPageHandler" }
);
And have this route mapped to an action method in TaskController:
public ActionResult MyPageHandler(string section, string taskId)
{
if (section.Contains("Detail"))
{
// execute section
}
}
This way you're treating your old site's query string for what it is: a query string. Passing those parameters straight into an action method is the most MVC-y way to interpret your old site.

.NET MVC Routing works, except for one piece

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"

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