Reddit links are normally like this:
https://www.reddit.com/r/<subreddit>/<topic>
meaning that, the subreddit can be anything depending on how the user created it.
Usually on ASP MVC, We can do it like this:
local/controller/action?subreddit=subname&topic=topicname
but what if I want it to be something like this:
local/controller/action/subname/topicname ?
The keyword for this feature is attribute routing in ASP.NET MVC. There is a lot of information availbale in blogs etc.
With the Route-Annotation you can decorate your action and define a mapping between URL parts and parameters for the action call.
public class ExampleController : Controller
{
[Route("r/{subreddit}/{topic}")]
public ActionResult Topic(string subreddit, string topic)
{
//Logic goes here
}
}
Furthermore the attribute routing has to be activted in the RouteConfig.cs with routes.MapMvcAttributeRoutes(); like
public class RouteConfig
{
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 }
);
}
}
Then you can call the Topic-Action of the ExampleController by http://localhost:PORT/r/reddit/topic.
Related
How can I do route configuration as below?
My current url is: http://localhost:4815/Home/ByCategory/1
But I want it to be: http://localhost:4815/CategoryTitle
public ActionResult ByCategory(int? id)
{
...
}
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "ByCategory", id = UrlParameter.Optional }
);
You can use Attribute Routing. for doing this at first you must Enable it by
adding below code top of your MapRoute in RouteConfig:
routes.MapMvcAttributeRoutes(); //Enables Attribute Routing
then you can add Attribute Routing at top of your classes and methods:
[Route("CategoryTitle")]
public ActionResult ByCategory(int? id)
{
...
}
for deep dive in Routing, you can follow this link.
good luck.
If you want to parametrize a route with Category Title, you can use Attribute Routing like so
[Route("~/{categoryTitle}")]
public ActionResult ByCategory(string categoryTitle)
...
Thank you for your suggestions. I have added the following code to routeconfig. I used on the view page to go to the relevant controller
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "AddQuestion",
url: "AddQuestion",
defaults: new { controller = "Question", action = "Create" }
);
Lots of similar questions and yet none quite like this problem:
I'm using attribute routing on an MVC5 project.
When trying to define a simple route like this:
[HttpGet]
[Route("Empresa/Filial/{id:int}/Editar")]
public ActionResult UpdateFilial(int id)
{
...
}
and generate a URL on the view, like this:
EDIT
I end up with something like:
http://localhost:59936/Empresa/Filial/Editar?id=1
which results a 404, since it should be:
"http://localhost:59936/Empresa/Filial/1/Editar"
What am I doing wrong here?
EDIT:
My RouteConfig looks like this:
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
//Acionando rotas por atributos (annotations)
routes.MapMvcAttributeRoutes();
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
}
(the default on MVC5 template on VisualStudio2017)
So, I guess, attribute routing has precedence over convention based routes.
Make sure that attribute routing has been enabled in RouteConfig before convention-based routes
public class RouteConfig {
public static void RegisterRoutes(RouteCollection routes) {
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
//enable attribute routing
routes.MapMvcAttributeRoutes();
//convention-based routes
//...other routes
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
}
I am trying to configure routing with both Conventional & Attribute based.
If I just use the default Conventional route included with MVC everything works. but if I add this Route attribute, I get a 404.
Here is the GET request URL: http://localhost:52386/Home/SimpleSearch?searchTerms=test&dateRange=0
Here is my RouteAttributes in Code:
[RoutePrefix("Home")]
public class HomeController : Controller
{
[Route("SimpleSearch/{searchTerms}/{dateRange}/{page?}")]
[HttpGet]
public ActionResult SimpleSearch(string searchTerms, DateRangeEnum dateRange, int page = 1)
{
//Code here
}
}
Also the Route Config looks like this:
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapMvcAttributeRoutes();
//Default
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
}
I don't see what is wrong with this RouteAttribute, but even if something is wrong with it, why doesnt it fall back onto the default Conventional Route and work?
With the attribute route definition, you explicitly specified the route pattern to be
Home/SimpleSearch/{searchTerms}/{dateRange}/{page?}
So you should try to access your action method with same url pattern.
This should work.
http://localhost:52386/Home/SimpleSearch/test/0
and Model binder will be able to map "test" to searchTerms parameter and 0 to dateRange parameter.
Your conventional (explicitly using querystring) will not work when you have an attribute route with a different pattern
i have an MVC .Net C# project. have Plan Action under Home Controller.
but i dont want to access this page as http://....../Home/Plans
but i want to access it as http://....../Plans
but i dont want to create Plans Controller. so i dont want to do a redirectToAction.
i am trying to use the Route Annonation as the following:
[Route("plans/")]
public ActionResult Plans()
[Route("plans/{actions}")]
public ActionResult Plans()
[Route("plans/index")]
public ActionResult Plans()
but none of the above worked for me. can you guys help me in this.
Updated:
this is my action under HomeController
[Route("plans")]
public ActionResult Plans()
{
var servicePlansDto = SubscriberApiManager.SubscriptionSellingService.GetServicePlans(ServiceId).FindAll(sp => !sp.HasPromotionCode);
List<ServicePlanVm> servicePlansVm = Mapper.Map<List<ServicePlanDto>, List<ServicePlanVm>>(servicePlansDto);
return View(servicePlansVm);
}
and this is my configurations
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 }
);
}
First of all remember to configure attribute routing:
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 }
);
}
Then take care that each controller function has to have a different name. In the example they have the same name and this is not accepted by the compiler.
Lat but not least, what's the need of the {actions} parameter in the routing attribute? When you define an attribute routing you don't need to define an action, as you your attribute is already decorating an action / method. You can have required / optional parameters in your routing but they usually correspond to a matching parameter in the method's sugnature:
//Example http://www.domain.com/plans/123
[Route("plans/{productId}")]
public ActionResult Plans(string productId)
{
...
}
I would like to suppress the controller from the route, and it worked fine using this:
routes.MapRoute(
name: "HomePages",
url: "{action}",
defaults: new { controller = "Home", action = "Index" }
);
The problem is when doing the same for a different controller like "Account", the first option only will take effect :
routes.MapRoute(
name: "LoginRoute",
url: "{action}",
defaults: new { controller = "Account", action = "Login" }
);
My objective is to hide the controller from the route, so i can directly access mysite.com/login and mysite.com/index, how to achieve that when login is under Account controller and index is under Home controller?
How to specify the second option for the Account actions, and keep the first for the Home actions?
Have you thought about using the Routing attributes e.g:
[Route("{getId:int}")]
public ActionResult Show(int getId) { ... }
you can use this in conjunction with the old way of routing. You do need to explicitly set this functionality in your config:
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapMvcAttributeRoutes();
}
}
I have found the routing Attributes makes it very easy to set good routes on my controller methods. This also bleeds into web api and RESTFul stuff as well.