MVC3 and Rewrites - c#

I'm writing an MVC3 application that will need to make use of URL rewriting in the form of http://[server]/[City]-[State]/[some term]/ .
As I understand it, MVC3 contains a routing engine that uses {controler}/{action}/{id} which is defined in the Global.asax file:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);
}
Traditionally (in a non-MVC app), I would use some URL rewriting flavor to decode a url such as http://www.myserver.com/City-State/somesearch/ to querystring parameters that look something like this:
http://www.myserver.com/city=City&state=State&query=somesearch
Keep in mind that this request would be coming from http://www.myserver.com/Home
Can this can be accomplished without having to specify a controller... something like this:
routes.MapRoute(
"Results",
"{city}-{state}/{searchTerm}",
new { controller = "Results", action = "Search" }
);
... or is it really best to have the controller listed?
How do you handle this in an MVC3 environment?
Thanks.

URL rewriting in asp.net MVC3:-
you can write code for url rewriting in Global.asax file :-
//Default url
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"Default",
"",
new { controller = "Home", action = "Index", id = "" }
);
//others url rewriting you want
RouteTable.Routes.MapRoute(null, "Search/{City_State}/{ID}", new { controller = "Home", action = "Search" });

Check out these two answers:
ASP.NET MVC Routes: How to define custom route
Defining custom URL routes in ASP.Net MVC
Summary:
Specify custom routes before the default one.
Define specific routes before general as they may match both.
Default values are optional.
Specify default Controller and Action in the default parameter object.

You can do this by registering route in Global.asax file, but order to register the Route is important you must be register first Old route then new one.
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
// for Old url
routes.MapRoute(
"Results",
"{city}-{state}/{searchTerm}",
new { controller = "Results", action = "Search" }
);
// For Default Url
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);

Related

MVC Routing Parameter Not Being Passed

I am trying to do some MVC routing, following online tutorials, but for some reason the routing is not working.
I am trying to do http://www.website.com/news/news-title
The route I am trying to do is below.
routes.MapRoute(
"News",
"{controller}/{url}",
new { controller = "News", action = "Index", url = "" }
);
Within my NewsController I have the following ActionResult.
public ActionResult Index(String url)
{
return View();
}
However, when stepping thorough the code, url is not being populated.
Thanks
== Update ==
Thank you all for your replies.
I have no amended the Route to below
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.LowercaseUrls = true;
routes.Add(new SubdomainRoute());
routes.MapRoute(
"News",
"News/{action}/{slug}",
new { controller = "News", action = "Index" }
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
This URL works: /news/index/?slug=test-news-title
But this URL does not: /news/index/test-news-title
=== Further Edit ===
It appears my subdomain route is messing with it. If i remove the subdomain route it works fine.
Thanks.
Most likely, your route is too broad. But it depends on how the rest of your routes are configured. You would need to post your entire route configuration (including area routes and attribute routing) in order to reasonably get an answer what is wrong with your route.
However, you can be more specific with this route because you know that it needs to start with /News.
routes.MapRoute(
"News",
"News/{url}",
new { controller = "News", action = "Index" }
);
Also, it probably doesn't make sense to make the URL parameter optional by providing a default value. If you remove url = "", the url parameter is required in the URL. If configured as above, if you just pass /News, it won't match this route. However, as you have it this URL will match.
Finally, make sure this route is placed in the right order. It should be placed before your default route (if you still have it).
You have set for the parameter url the empty string. you should use instead UrlParameter.Optional (or removing it at all if is mandatory):
routes.MapRoute(
"News",
"{controller}/{url}",
new { controller = "News", action = "Index", url = UrlParameter.Optional }
);
You are missing the action part in the MapRoute
routes.MapRoute(
"News",
"{controller}/{action}/{url}",
new { controller = "News", action = "Index", url = "" }
);
Hope this help

Action Link to "lose" parameter

I've got the following routes:
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(null,"Conference/{shortName}/Submission/{submission}/{action}", new { controller = "Conference", action = "Show" });
routes.MapRoute(null,"Conference/{shortName}/{action}",new { controller = "Conference", action = "Index" });
routes.MapRoute("Default", "{controller}/{action}/{id}", new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
The following (hopefully obvious) links which are all working:
/Conference/testconf
/Conference/testconf/ShowSubmissions
/Conference/testconf/Submission/firstSub
/Conference/testconf/Submission/firstSub/EditSubmission
When I'm now in Submission/firstSub and create a ActionLink like this
#Html.ActionLink("Show Submissions", "ShowSubmissions", "Conference", new { shortName = Model.confereceShortName },null)
it creates the following Link
/Conference/testconf/Submission/firstSub/ShowSubmissions
How can i let the actionlink forget about Submission/firstSub without hardcoding it there?
Where do you have a placeholder for {controller}?
The default route should look like the following sample.
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{*id}", // URL with parameters
new {controller = "Home", action = "Index", id = UrlParameter.Optional} // Parameter defaults
);
Also try to remove the /Submission/ part in your first route.
Links for posts on custom route creation and ordering:
1) Creating Custom Routes (C#)
2) Custom routing for ASP .NET MVC
3) official source from asp.net mvc
Sometimes searching for 30min isn't enough, you gotta search 2h...
ASP.NET MVC 2 RC2 Routing - How to clear low-level values when using ActionLink to refer to a higher level?
Routlink or delete the values in the constraints.
For me Routelink does the job.
Although Thanks
ElYusubov & Aleksey

MVC routing vs. partial class

I have a request controller that is getting out of hand, and I want to divide the actions on several controllers while maintaining a clean URL. I'm trying to experiment with routing, but without success. I've read some examples and tutorials on routing, but, though I understand the examples, nothing seems to apply to my case, and I feel non the wiser. What I want is for the URL Requests/Approval to be handled on my ApprovalController instead of my RequestController, so I wrote the following.
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);
routes.MapRoute(
"Approval",
"Request/{controller}/{action}",
new { controller = "Approval", action="Index", id = "" }
);
}
But it's not working. Why? I have a folder in the my Views called Approval, and in there I have a file called Index.cshtml. How should I code the MapRoute?
Edit
I added all the routes I've got
You need to swap the two MapRoute statements, like so:
routes.MapRoute(
"Approval",
"Request/Approval/{action}",
new { controller = "Approval", action="Index", id = "" }
);
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);
The reason it is currently not working is because the first statement ('Default' route name) is getting matched before the second one is even evaluated.
In addition (as noted in my above example,) you need to remove '{controller}' in the Approval route and replace with 'Approval'... unless you specifically want the URL /Request/{ANY controller}/{action} to go through, which I doubt. From your question it seems you only want /Request/Approval/ to go to your Approval controller.
Don't forget to keep the Default route at the bottom, so as to match your other controllers and actions. It serves as a catch-all should no other matches exist.
The order you map your routes matters. Move the second route before the default route.
You will still have a problem though, as any thing /request/something will look for the SomethingContoller. To fix this, change your route to this:
routes.MapRoute(
"Approval",
"Request/Approval/{action}",
new { controller = "Approval", action="Index", id = "" }
);

MVC Routing problem

I am learning MVC and I need to understand why it doesn't work the way it should.
Here is my routing :
public static void RegisterRoutes(RouteCollection routes)
{
// Note: Change the URL to "{controller}.mvc/{action}/{id}" to enable
// automatic support on IIS6 and IIS7 classic mode
//http://localhost/store/category/subcategory/product
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"Category", // Route name
"store/{category}/{subcategory}", // URL with parameters
new
{
controller = "Catalog",
action = "Index",
category = "Featured Items",
subcategory = "All Items"
}
);
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = "" }, // Parameter defaults
new { controller = #"[^\.]*" } // Parameter constraints
);
}
The way I understand routing I should see the following url when I start the web app :
http:/localhost/store/
What I get is the second route....
Furthermore if I change the second route to "home/{action}/{id} it doesn't catch any routes.
Could you help me understand this please..Thanks
Routes do not specify default URL; the default URL is handled by your app. Routing specifies that when it sees http://localhost/store/bikes/mountain, it will use the catalog controller. But that doesn't specify the default URL; you have to enter that in the project properties.
I would recommend not changing the second one because unless you are creating groupings for all of your controllers, it's best to have the default as it is so you can catch all URL's. Your change to the second one would require the url to be:
http://localhost/home/home/index to match the HomeController's index action, whereas the default setup catches http://localhost/home/index...
Does that make sense?
Try this: http://haacked.com/archive/2008/03/13/url-routing-debugger.aspx

How can I create a friendly URL in ASP.NET MVC?

How do I generate friendly URLs within the ASP.NET MVC Framework? For example, we've got a URL that looks like this:
http://site/catalogue/BrowseByStyleLevel/1
The 1 is Id of the study level (Higher in this case) to browse, but I'l like to reformat the URL in the same way StackOverflow does it.
For example, these two URLs will take you to the same place:
https://stackoverflow.com/questions/119323/nested-for-loops-in-different-languages
https://stackoverflow.com/questions/119323/
EDIT: The friendly part of the url is referred to as a slug.
There are two steps to solve this problem. First, create a new route or change the default route to accept an additional parameter:
routes.MapRoute( "Default", // Route name
"{controller}/{action}/{id}/{ignoreThisBit}",
new { controller = "Home",
action = "Index",
id = "",
ignoreThisBit = ""} // Parameter defaults )
Now you can type whatever you want to at the end of your URI and the application will ignore it.
When you render the links, you need to add the "friendly" text:
<%= Html.ActionLink("Link text", "ActionName", "ControllerName",
new { id = 1234, ignoreThisBit="friendly-text-here" });
This is how I have implemented the slug URL on my application.
Note: The default Maproute should not be changed and also the routes are processed in the order in which they're added to the route list.
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home",
action = "Index",
id = UrlParameter.Optional
} // Parameter defaults
);
routes.MapRoute("Place", "{controller}/{action}/{id}/{slug}", new { controller = "Place", action = "Details", id = UrlParameter.Optional,slug="" });
you have a route on the global.asax
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = ""}
// Parameter defaults )
you can define your own route like :
controller is the cs class inside the the controllers folder.
you can define your id - with the name you choose.
the system will pass the value to your actionResult method.
you can read more about this step here : http://www.asp.net/learn/mvc/tutorial-05-cs.aspx

Categories

Resources