I want use AnotherController name in SomeController.
But, RoutePrefix Attribute is can only be declared by Controller level.
Prepare the following.
namespace KRSMART.Controllers
{
public class SomeController : Controller
{
/* localhost:0000/Some/Index */
public ActionResult Index()
{
return View();
}
/* I want Url */
/* localhost:0000/Another/Test */
[Route("Another/Index")]
public ActionResult Test()
{
return View();
}
}
}
It didn't work as I wanted it to.
I know I can create a new controller and do it, but I didn't want to.
I'd like to get some advice from you who are familiar with Route.
You need to add routes.MapMvcAttributeRoutes(); before default route register,
your RegisterRoutes function should be like,
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute(“{resource}.axd/{*pathInfo}”);
routes.MapMvcAttributeRoutes();
routes.MapRoute(
name: “Default”,
url: “{controller}/{action}/{id}”,
defaults: new { controller = “Home”, action = “Index”, id = UrlParameter.Optional }
);
}
Related
Let's say I have following simple controller:
public class DataController: Controller
{
[HttpGet]
public ActionResult Index()
{
// some code
}
}
Now I'd like Index action to be allways called if there is a GET request to DataContoller. I other words to ignore action name and any other parameters. For example all of following calls should be handled by Index action:
https://localhost:5000/data
https://localhost:5000/data/anything
https://localhost:5000/data/anything/secondAnything
https://localhost:5000/data/anything?someParameter=3
How can I achieve this?
You should update your RouteConfig like so:
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.MapRoute(
name: "RouteOverwrite",
url: "data/{*catchall}",
defaults: new { controller = "Data", action = "Index" }
);
}
}
Make sure you use this in Application_Start:
public class MvcApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
System.Net.ServicePointManager.SecurityProtocol = (SecurityProtocolType)3072;
// register route config
RouteConfig.RegisterRoutes(RouteTable.Routes);
}
}
you can do this by using routetable. check out system.web.routing in asp.net mvc.
I have controller: DoomPlaceController
In route: I have used: doom-place/{parameter} // no action
and In controller :
[Route("doom-place/{parameter}")]
public ActionResult Index(string parameter)
{
return View();
}
What I want: when I hit URL: www.xyz.com/doom-place
it should open Doom-Place/index page.
But right now, I am able to access the page with doom-place/index but I want when I hit www.xyz.com/doom-place, it will automatically open index page.
Help will be appreciated.
You can make the parameter optional
[RoutePrefix("doom-place")]
public class DoomPlaceController : Controller {
//Matches GET /doom-place
//Matches GET /doom-place/some_parameter
[HttpGet]
[Route("{parameter?}")]
public ActionResult Index(string parameter) {
return View();
}
}
Given that attribute routing is being used, the assumption is that attribute routing has been enabled in RouteConfig.RegisterRoutes
public static void RegisterRoutes(RouteCollection routes) {
routes.IgnoreRoute(“{resource}.axd/{*pathInfo}”);
//enable attribute routing
routes.MapMvcAttributeRoutes();
//covention-based routes
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
Reference Attribute Routing in ASP.NET MVC 5
I have a situation where I want the ThisAction controller to look like this :
public ActionResult Index()...
public ActionResult Index(int programId)...
public ActionResult Index(string programKey)...
With the goal of a route being set up like so
www.website.com/ThisAction/ <- matches first function
www.website.com/ThisAction/123 <- matches second function
www.website.com/ThisAction/ABC <- matches third function
Is this possible to set up in the global.asx route?
You would need to use attribute routing with route constraints to easily get that flexibility.
[RoutePrefix("ThisAction")]
public class ThisActionController : Controller {
[HttpGet]
[Route("")] //Matches GET ThisAction
public ActionResult Index() {
//...
}
[HttpGet]
[Route("{programId:int}")] //Matches GET ThisAction/123
public ActionResult Index(int programId) {
//...
}
[HttpGet]
[Route("{programKey}")] //Matches GET ThisAction/ABC
public ActionResult Index(string programKey) {
//...
}
}
Make sure that attribute routeing is enabled in RouteConfig
public class RouteConfig {
public static void RegisterRoutes(RouteCollection routes) {
//...other code removed for brevity
//Attribute routes
routes.MapMvcAttributeRoutes();
//convention-based routes
//...other code removed for brevity
routes.MapRoute(
"Default",
"{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = "" }
);
}
}
The route will work along side convention-based routing.
Just note that once you use it on a controller you have to use it on the entire controller. So the controller is either all convention-based or all attribute routing.
So I am trying to do this:
http://localhost:43751/api/doWork/asdfasfsaf
And here is Controller:
public class DoWorkController : ApiController
{
public User GetWork(String input) {
Dictionary<int, Work> users = DataObjects.Work.find(input);
return users.Values.First<Work>();
}
}
I run it and it doesn't work:
No HTTP resource was found that matches the request URI 'http://localhost:43751/api/doWork/asdfasfsaf'.
and
No action was found on the controller 'DoWork' that matches the request.
What am I doing wrong?
Here is my Routing Configuration:
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 }
);
}
It seem that all I needed to do to get this to work is this:
public class DoWorkController : ApiController{
public User GetDoWork(String ID) {
Dictionary<int, Work> users = DataObjects.Work.find(input);
return users.Values.First<Work>();
}
}
Because MVC believes you're referring to a different URL. You need to either define a method that is listening to your requests of type HttpGet or HttpPost:
[HttpGet]
public ActionResult doWork(string input) {
// do processing and return the selected user as a model back to the view
User user = YourGetUserMethod(input);
return View(user);
}
so you could invoke it as: /api/doWork?input=asdfasfsaf
Or if what you want is to change your URL routing to accept the last portion of your URL as a parameter, you'd need to add something like this to your RouteConfig.cs file:
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "DoWork", action = "doWork", id = UrlParameter.Optional }
);
You might want to follow this post for additional information regarding route mapping
What would be the easiest way to make a page title to be the url?
Currently I have:
http://localhost:53379/Home/Where
http://localhost:53379/Home/About
http://localhost:53379/Home/What
and would like to have
http://localhost:53379/where-to-buy
http://localhost:53379/about-us
http://localhost:53379/what-are-we
I thought about adding a route to each page (there's only 9 pages) but I wonder if there's something better, for example for big sites.
routes.MapRoute(
name: "Default",
url: "where-to-buy",
defaults: new {
controller = "Home",
action = "Where",
id = UrlParameter.Optional
}
);
...
and I would like to have it in English and Local language as well, so adding more routes would not make that much sense...
If you need to fetch pages dynamically from the database, define a new route which will catch all requests. This route should be defined last.
routes.MapRoute(
name: "Dynamic",
url: "{title}",
defaults: new {
controller = "Home",
action = "Dynamic",
title = ""
}
)
Then in your controller:
public class HomeController {
public ActionResult Dynamic(string title) {
// All requests not matching an existing url will land here.
var page = _database.GetPageByTitle(title);
return View(page);
}
}
Obviously all pages need to have a title (or slug, as it's commonly referred to) defined.
If you have static actions for each page, you could use AttributeRouting. It will allow you to specify the route for each action using an attribute:
public class SampleController : Controller
{
[GET("Sample")]
public ActionResult Index() { /* ... */ }
[POST("Sample")]
public ActionResult Create() { /* ... */ }
[PUT("Sample/{id}")]
public ActionResult Update(int id) { /* ... */ }
[DELETE("Sample/{id}")]
public string Destroy(int id) { /* ... */ }
[Route("Sample/Any-Method-Will-Do")]
public string Wildman() { /* ... */ }
}
I use it on a mid-sized project and it's working pretty well. The big win is that you always know where your routes are defined.