How do I set up RESTFul URLs using ASP.NET MVC routing? - asp.net-mvc

I have this URL:
/controller/action/value
and this action:
public ActionResult Get(string configName,string addParams)
{
}
How do I set up my routing table to get the routing engine bind the value to the configName parameter for any action in the Config controller?

Well, first off, that is incomplete. You don't have a method name.
Secondly, this will already work with URLs of the format:
/controller/action?configName=foo&addparams=bar
Here's how to do it with pretty routes:
routes.MapRoute(
"YourMapping",
"{controller}/{action}/{configName}/{addParams}");
or
routes.MapRoute(
"YourMapping",
"{controller}/{configName}/{addParams}",
new {
controller = "YourController",
action = "YourAction"
},
new {
controller = "YourController" // Constraint
});
if you want to exclude the action from the URL.

You could add a new route above the default
routes.MapRoute(
"Config",
"config/{action}/{configName}/{addParams}",
new { controller = "Config", action = "Index" }
);
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);
Which will allow you to use the route /config/actionName/configName/addParamsValue. Your other routes should be unaffected by this.

routes.MapRoute(
"ValueMapping",
"config/{action}/{configName}/{addParams}",
new { controller = "Config", action = "Index", configName= UrlParameter.Optional, addParams = UrlParameter.Optional } // Parameter defaults);
Setting default Controller to Home, with a Default Action of Index
So the Url:
/config/get/configNameValue/AddParamValue
would match this Method:
public ActionResult Get(string configName,string addParams)
{
//Do Stuff
}

Related

ASP.NET MVC 5 - Removing controller name from url fails for other controllers

I followed the answer to this question but when I apply it I get an error if I try to access views under other controllers.
If I go to http://mydomain/MyActionUnderHome it works fine, but if I go to http://mydomain/SomeOtherController/MyAction it throws
"The resource cannot be found."
Shouldn't the Default route take over if the URL doesn't match the route definition above the Default route?
Are there perhaps new ways in MVC 5 to do this?
My routes:
routes.MapRoute(
"HomeRoute",
"{action}/{id}",
new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
routes.MapRoute(
"AccountRoute",
"{action}/{id}",
new { controller = "Account", action = "Index", id = UrlParameter.Optional }
);
routes.MapRoute(
"Default",
"{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
Better to use Route attribute.
public class HomeController : Controller
{
[Route("")]
public ActionResult Index() { return View(); }
[Route("MyAccount")]
public ActionResult Account() { return View(); }
}
Then add this line t your RouteConfig class before the routes.MapRoute
routes.MapMvcAttributeRoutes();
The issue is that you have is conflicting routes that the router can't resolve correctly
routes.MapRoute(
"HomeRoute",
"{action}/{id}",
new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
routes.MapRoute(
"AccountRoute",
"{action}/{id}",
new { controller = "Account", action = "Index", id = UrlParameter.Optional }
);
When the router looks at the path /youraction/yourparameter it will resolve to the first route.
The next part of this is that when you provide two values as your URL (as in your example the default router never gets called because the router interprets your input as /action/id rather than controller/action/id
If you change your routes to be:
routes.MapRoute(
"HomeRoute",
"index/{id}",
new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
routes.MapRoute(
"Default",
"{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
Then you'll get your effect. But your second route can still never be called, as your scheme isn't correct.

ASP.Net MVC - Create Custom Routing?

I'm trying to create a custom routing. Here is what I've tried but does not work, what am I doign wrong?
Expected Call:
MyWebsite/Friend/Respond/55/4
routes.MapRoute(
name : "Friend",
url : "Friend/Respond/{id}/{state}"
);
// This method is in a Controller Named FriendController
[HttpPost]
public ActionResult Respond(int id, int state)
{
// Do stuff
}
ANSWER:
routes.MapRoute(
name : "ExtraParameter",
url : "{controller}/{action}/{id}/{state}",
defaults : new { }
);
Can you post an example ActionLink to trigger your route?
Have you set-up defaults for your route:
routes.MapRoute(
"Default",
"{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = UrlParameter.Optional });
Specifically the third argument in MapRoute. You might need to set your id and state parameters as UrlParameter.Optional
You can set id and state UrlParameter.Optional.
routes.MapRoute(
"Default",
"{controller}/{action}/{id}/{state}",
new { controller = "yourcontrollername", action = "youraction", id = UrlParameter.Optional, state = UrlParameter.Optional
});

rewrite routes for URl

I have the following URl:
http://localhost:12981/BaseEvent/EventOverview/12?type=Film
This is route:
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);
I want that in a browser the url looks like:
http://localhost:12981/Film/Overview/12
How can I do this?
One more example:
http://localhost:12981/BaseEvent/EventOverview/15?type=Sport
should be
http://localhost:12981/Sport/Overview/15
Thanks.
This should work:
routes.MapRoute("", "{type}/Overview/{id}", new { controller = "Events", action = "Overview");
Then you have a controller named EventsController with an action like this one
public ViewResult Overview(string type, int id)
{
//Your code
return View(model);
}

MVC3 maproute where first value of URL is querstring for default controller and action

I want to make a route something like this:
routes.MapRoute(
"Default", // Route name
"{s}", // URL with parameters
new { controller = "Home", action = "Index", s = UrlParameter.Optional }
);
Where s is a parameter for the default controller and action.. Is this possible? i would also settle for something like:
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{s}", // URL with parameters
new { controller = "Home", action = "Index", s = UrlParameter.Optional }
);
routes.MapRoute(
"qMap", // Route name
"sc/{s}", // URL with parameters
new { controller = "Home", action = "Index", s = UrlParameter.Optional }
);
But neither work.. i suspect because the first element/paramater is always expected to be a controller?
If you have only the following route definition (make sure you have removed all other route definitions from your RegisterRoutes method):
routes.MapRoute(
"Default",
"{s}",
new { controller = "Home", action = "Index", s = UrlParameter.Optional }
);
and the following controller:
public class HomeController: Controller
{
public ActionResult Index(string s)
{
...
}
}
a request of the form http://foo.com/abc would be routed to the Home controller and the Index action will be invoked and passed s=abc.

Setting up Index as the default route for a controller

I have a url
http://www.roadkillwiki.org/Page/Index/documentation
which I want to turn into
http://www.roadkillwiki.org/Page/documentation
That could also be something like http://www.roadkillwiki.org/Page/my-url-with-spaces - the parameter is a string. The route setup I've tried is:
routes.MapRoute(
"ControllerDefault",
"{controller}/{id}",
new { controller = "Page", action = "Index", id = UrlParameter.Optional }
);
However this is interfering with the default "id" route that MVC projects come with. Is there any way of achieving this?
You don't need to lose the default route. The key to avoiding your routes interfere with each other is to order them so the more specific rules precede the less specific ones. For example:
// Your specialized route
routes.MapRoute(
"Page",
"Page/{slug}",
new { controller = "Page", action = "Index" }
);
// Default MVC route (fallback)
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);
Then your PageController would look like this:
using System.Web.Mvc;
public class PageController : Controller
{
public string Index(string slug)
{
// find page by slug
}
}
That said, I would strongly advice you to do this instead:
// Your specialized route
routes.MapRoute(
"Page",
"Page/{id}/{slug}",
new { controller = "Page", action = "Index", slug = UrlParameter.Optional }
);
// MVC's default route (fallback)
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);
And your PageController:
using System.Web.Mvc;
public class PageController : Controller
{
public string Index(int id)
{
// find page by ID
}
}
By including the page ID either at the beginning of your URL (like StackOverflow does) or at the end, you can then just ignore the slug, and instead retrieve your pages by ID. This will save you a ton of headaches if your users change the page name. I have gone through this and it's painful; you basically have to keep a record of all names your pages have had in the past, just so your visitors/search engines don't get a 404 every time a page is renamed.
Hope this helps.
If you don't need a default route that came with project template you can set up one like this:
routes.MapRoute(
"ControllerDefault",
"{controller}/{pagename}",
new { controller = "Page", action = "Index" }
);
And than in your controller you would have an action:
public ActionResult Index(string pagename)
{
//do something
}

Resources