I am trying to figure out how to create custom routes in composite C1. I have been searching around for hours and came up with noting. I realise you can use pathinfo to slightly customise the route but this really just doesnt do what I need. I basically want to add a few custom routes to override composite C1 if there are any matches
For example I need to map
www.domain.com/job-detail/Executive_Management/HR_Executive/136307 or
www.domain.com/job-detail/Executive_Management/HR_Executive?job=136307
to
www.domain.com/job-seekers/job-search/job-detail?job=136307
Please help. I really like Composite C1 but when it comes to custom routes I find it hard to find any help online.
I figured this one out by having a further dig through the code. I noticed I could add custom routes to the App_Code\Composite\AspNet\MvcPlayer\Route.cs class.
I added this line of code to the RegisterRoutes method....
routes.MapRoute("Job-Listing", "job-detail/{category}/{title}/{id}", new { controller = "JobSearchModule", action = "JobDetail" });
I added this directly above the default route which is important
routes.MapRoute("Default","{controller}/{action}/{id}",new { action = "Index", id = "" });
Related
As we know, when we create an MVC application, it creates its own typical structure which is known as convention over configuration and its a good practice .
It configure views, controller and model separately .
My concern is, can i architect(design) it like :
If I do that, My viewengine will search views inside view not inside subfolders and there are so many things like routing will get changed.. and so on..
Actually I dont want to construct my view,controller or model in a typical way, I want to put my view separately according to my domain, not according to controller like MVC does.
However in case of controller we can use any folder structure . I am specific about model,views and routing should not be affected as well.
And it is all about "Convention over My own Configuration".
Can someone please explain, how to get it done or any other alternatives.
Thanx
Anupam.
It sounds like what you are looking for is 'Areas'. This allows you to separate your controllers & views into separate 'area' folders.
More information can be found here, as including the necessary information to get this set up in this answer is probably not practical:
http://msdn.microsoft.com/en-GB/library/ee671793(v=vs.100).aspx
The location and folder structure of your controllers and models doesn't really matter, should work either way. Controllers are located by their type and classname.
The viewengine by default does search subfolders, trying to match with the naming of your controller. It searches multiple locations.
Now, if you want to change how the view engine searches for files you can configure it in global.asax. Have a look here regarding RazorViewEngine for example.
Personally I have gone away from the view engine auto locating my views and instead use relative paths for all of them because I think it makes it more readable overall.
Below is an example of a configured view engine and a relative path.
global.asax
ViewEngines.Engines.Clear();
var razorEngine = new RazorViewEngine() { FileExtensions = new string[] { "cshtml" } };
ViewEngines.Engines.Add(razorEngine);
controller action
return View("~/Views/Home/Index.cshtml", model);
Hope I understood your question correctly.
So far I have reached to conclusion.
The thing we have to consider for this are :
1.Need to override ControllerFactory : we have to search controller in specific location or assembly reference.(by default controller factory just chak the controller name )
2.Need to override ViewEngine : We have to change view search location according to our need.
3.Little modification in Route : we have to specify module name in routs for proper redirection.
route will be something like :
routes.MapRoute(
name: "Default",
url: "{module}/{controller}/{action}/{id}",
defaults: new { module = "HR", controller = "Home", action = "Index", id = UrlParameter.Optional }
);
will implement it soon. Your suggestions are most welcome.
I have a specific routing need that I can't get to work. I've found quite a few answers here on StackOverflow that takes me a bit on the way, but not all the way.
Im naming my controllers and actions in the standard C# way, i.e. the first letter of every word is uppercase:
MyController.MyAction()
To reach this action method, I'd like all of these urls to work:
/my-controller/my-action
/my-cöntroller/my-äction
/MyController/MyAction
/MyCöntroller/MyÄction
(the two last ones are not super important though...)
So there's two things here:
Dashes may be used to separate the words (for readability and SEO
purposes).
Some non-english characters can be used (all replacements
specified - no "magic").
I want to create the links with helpers like this:
#Html.ActionLink("My link text", "MyController", "MyAction")
i.e. the standard way, and this will create the following link:
/my-controller/my-action
Hopefully this could be done without making my routing configuration too messy (e.g. with one route for every action or something), or putting attributes on all action methods, but if thats the only solution I'd like to know.
What I've tried so far is implementing a custom route class overriding GetRouteData() and GetVirtualPath(). It got me closer but not all the way, but I might do something wrong
I had an idea for solving the problem with non-english characters by doing the replacement before the routing is performed, but I haven't found a way to do this yet (see this question).
I'd be really greatful if someone could help me with this, or at least point me in the right direction! :)
Edit: Note that the example urls above are just to describe what I want. In reality there is a lot of urls that must be handled, so I'd prefer some generic solution and not one involving one route for every action or something like that.
Create your resource file
Name Value
myaction1 my-äction
myaction2 my-action
mycontroller1 my-cöntroller
mycontroller2 my-controller
Add following routes in RegisterRoute method in global.asax
routes.MapRoute(
name: "route1",
url: Resources.Actions.mycontroller1 + "/" + Resources.Actions.myaction1 ,
defaults: new { controller = "mycontroller1", action = "myaction1" }
);
routes.MapRoute(
name: "route2",
url: Resources.Actions.mycontroller2 + "/" + Resources.Actions.myaction2,
defaults: new { controller = "mycontroller2", action = "myaction2" }
);
In controller,
[HttpGet]
public ActionResult myaction1()
{
return View("");
}
[HttpGet]
public ActionResult myaction2()
{
return View("");
}
In _Layout.cshtml
#Html.ActionLink(Resources.Actions.myaction1, "myaction1", "mycontroller1")
#Html.ActionLink(Resources.Actions.myaction2, "myaction2", "mycontroller2")
Is it possible to define a route in MVC that dynamically resolves the action based on part of the route?
For example:
`/products/create/widget`
Would resolve to ProductsController.CreateWidget(Widget);
I want the route to be dynamic:
routes.MapRoute(
"Create",
"/products/create/{productType}",
new { controller = "Products", action = "Create{productType}" }
);
I need to have multiple Create actions that take in different model types but I don't want to add a new route every time I add one. Without appending the name to the action I get an ambiguous method error. Is it possible to do this?
I think you probably need to create your own custom route object derived from the RouteBase where you can assign action based on particular part of the Url. Take a look at this example.
I was recently asked to modify a small asp.net mvc application such that the controler name in the urls contained dashes. For example, where I created a controller named ContactUs with a View named Index and Sent the urls would be http://example.com/ContactUs and http://example.com/ContactUs/Sent. The person who asked me to make the change wants the urls to be http://example/contact-us and http://example.com/contact-us/sent.
I don't believe that I can change the name of the controller because a '-' would be an illegal character in a class name.
I was looking for an attribute that I could apply to the controller class that would let me specify the string the controller would use int the url, but I haven't found one yet.
How can I accomplish this?
Simply change the URL used in the route itself to point to the existing controller. In your Global.asax:
routes.MapRoute(
"Contact Us",
"contact-us/{action}/",
new { controller = "ContactUs", action = "Default" }
);
I don't believe you can change the display name of a controller. In the beta, the controller was created using route data "controller" with a "Controller" suffix. This may have changed in RC/RTM, but I'm not sure.
If you create a custom route of "contact-us/{action}" and specify a default value: new { controller = "ContactUs" } you should get the result you are after.
You need to configure routing. In your Global.asax, do the following:
public static void RegisterRoutes(RouteCollection routes)
{
...
routes.MapRoute(
"route-name", "contact-us/{action}", // specify a propriate route name...
new { controller = "ContactUs", action = "Index" }
);
...
As noted by Richard Szalay, the sent action does not need to be specified. If the url misses the .../sent part, it will default to the Index action.
Note that the order of the routes matter when you add routes to the RouteCollection. The first matched route will be selected, and the rest will be ignored.
One of the ASP.NET MVC developers covers what Iconic is talking about. This was something I was looking at today in fact over at haacked. It's worth checking out for custom routes in your MVC architecture.
EDIT: Ah I see, you could use custom routes but that's probably not the best solution in this case. Unless there's a way of dealing with the {controller} before mapping it? If that were possible then you could replace all "-" characters.
I will take the example of the SO site. To go to the list of questions, the url is www.stackoverflow.com/questions. Behind the scene, this goes to a controller (whose name is unknown) and to one of its actions. Let's say that this is controller=home and action=questions.
How to prevent the user to type www.stackoverflow.com/home/questions which would lead to the same page and would lower the rank of the page as far as SEO is concerned. Does it take a redirect to solve this? Does it take some special routing rules to handle this kind of situation? Something else?
Thanks
I assumed that the controller was questions and the action was index, i.e., the default action as defined by the route handler. Thus there isn't an alternative path to the page.
During Phil Haack's presentation from PDC, Jeff shows some of the source code for Stack Overflow. Among the things he shows is the code for some of the route registrations. He's got these in the controllers, and it's not clear to me that he uses a default route at all. With no default route, you wouldn't need to worry about /home/questions, for example.
As for /questions/index, yes, a permanent redirect is the way to go. You won't get any search engine penalty for a permanent redirect.
Another way to eliminate /home/questions would be to use a route constraint.
You want to use the following route. It is really easy you just create a new route that eliminates the need for the controller to be in the route. You create a template string that just contains the action and you default the controller to the controller you want to use such as "Home".
routes.MapRoute(
"MyRoute",
"{action}",
new { controller = "Home", action = (string)null },
new { action = "[a-zA-z_]+" }
);
Hope this helps.