I have the following controller:
public class MyController : BaseController
{
public ActionResult Index(string id) { /* Code */ }
public ActionResult MyAjaxCall(string someParameter) { /* Code */ }
}
I have also added the following in the RouteConfig.cs
routes.MapRoute(
name: "MyController",
url: "MyController/{id}",
defaults: new { controller = "MyController", action = "Index" }
)
So my idea is to be able to go directly to the index action using this url /MyController/{Id}, and that seems to work.
However when on the Index page I need to make an Ajax call to /MyController/MyAjaxCall/{someParameter}. However this url is pointing to the Index controller, and is interpreting MyAjaxCall as the id in the Index action.
Any ideas how I can exclude this action from following the newly added route config setting?
If that your id can only be integer number, you can add a constraint to your id field, which specifies that your id can only be numbers:
routes.MapRoute(
name: "MyController",
url: "MyController/{id}",
defaults: new { controller = "MyController", action = "Index" },
constraints: new { id = #"\d+" } // <- constraints of your parameters
)
Here you can use any regular expression that works for your business logic.
Also make sure to register this route before your default route registration, in that case MVC will first try to match this route, and only if it doesn't match it will try to match the default route.
It sounds like you have the routes in the wrong order. When using MVC routing, the first match always wins, so you must place the most specific routes first before general routes.
routes.MapRoute(
name: "MyControllerAJAX",
url: "MyController/MyAjaxCall/{someParameter}",
defaults: new { controller = "MyController", action = "MyAjaxCall" }
)
routes.MapRoute(
name: "MyController",
url: "MyController/{id}",
defaults: new { controller = "MyController", action = "Index" }
)
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
Related
I am having an issue while dealing with routing in MVC.
I have defined the following routes in Route.Config
routes.MapRoute(
name: "Test",
url: "{controller}/{action}/{param}",
defaults: new { controller = "Home", action = "FirstAction" }
);
routes.MapRoute(
name: "Testy",
url: "{controller}/{action}/{secondparm}",
defaults: new { controller = "Home", action = "SecondAction" }
);
routes.MapRoute(
name: "Test2",
url: "{controller}/{action}/{encodedparam}",
defaults: new { controller = "User", action = "UserInfo" }
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
Problem is that the first route is working fine but in second and third I got null values for the respective parameter.
Did I miss something?
Thanks in advance
You must match the parameter name for the third. If you write :
{id}
You must write
public ActionResult AnyAction(int id)
id could be of any type
i think there is conflict beetween your routes. You need only this mapping :
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);
if you need custom routing for other elements don't put "{controller}/{action}/..." inside, because he will take the first route config that is matching with.
You can call all your routes precising the name of your parameter if its different from "id" :
http://localhost/home/firstaction?param=123
http://localhost/home/secondaction?secondparam=123
http://localhost/user/userinfo?encodedparam=123
As you want to use the URL in such way: localhost:portnumber/home/secondaction/value instead of localhost:portnumber/home/secondaction?secondparam=value.
You have to follow the below approach, which would behave as generic for all your Action Methods, whether they are containing parameters or not.
Declare default route in RouterConfig.cs as:
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
Then Parameter name in method must be same as in default route:
public ActionResult SecondAction(string id)
{
return View();
}
Paramter type could be any type.
In this way you do not need to declare other routes.
I've added new action to my asp.net mvc application and add specific rule for it inside RouteConfig.cs.
But all parameters passed as null.
Here is my route rule:
routes.MapRoute(
"toekn_submit_route",
"{controller}/SendToken/{platform}/{token}/{uid}",
new { controller = "Home", action = "SendToken" }
, new[] { "MvcApplication.Controllers" }
);
And here is action deceleration:
public JsonResult SendToken(string platform, string token, string uid) { ... }
I call action using this URL: http://localhost:51650/Home/SendToken/platform/token/uid
Order of how routes are added is important. First matched route wins.
Make sure that this added route is added before more general routes otherwise they would be matched by another route that doesn't populate the placeholders as intended.
routes.MapRoute(
name: "token_submit_route",
url: "{controller}/SendToken/{platform}/{token}/{uid}",
defaults: new { controller = "Home", action = "SendToken" },
namespaces: new[] { "MvcApplication.Controllers" }
);
//...other more general routes.
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
For example if the Default route was placed before the token route it would still match http://localhost:51650/Home/SendToken/platform/token/uid
where
controller = "Home",
action = "SendToken",
id = "platform/token/uid"
I have an MVC page for creating an entity. Upon completion, I want to redirect to the parent entity. I do it like this:
return RedirectToAction("Edit", new { id = vm.Parent });
When I use any other parameter name, it is interpreted as an URL param:
return RedirectToAction("Edit", new { foo = vm.Parent });
renders as /Entities/Edit?foo=234
But ASP MVC picks up a route param named id as a special case and the URL looks like: /Entities/Edit/234. This does not work for me because the routing is not set up to work with this. I am looking to get an URL like /Entities/Edit?id=234.
How do I force it to work this way? Route setup:
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
By the looks of it, you're only using the default route config route, which only specified id as a defined UrlParameter. If you want a custom parameter, then you'll need to define it as such:
routes.MapRoute(
name: "ControllerName",
url: "controllername/edit/{foo}"
);
Or if you wish to use foo instead of id globally, just alter your existing route:
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{foo}",
defaults: new { controller = "Home", action = "Index", foo = UrlParameter.Optional }
);
Or if you don't want good looking URLs with an unnecessary query string parameter, alter your default:
routes.MapRoute(
name: "Default",
url: "{controller}/{action}",
defaults: new { controller = "Home", action = "Index" }
);
When I pass multiple parameters to a controller action, I get question marks in the parameters like this:
http://localhost:57728/Home/AddAndManageProperties?BaseCategoryId=11&SubCategoryId=14
I want to remove the question marks to be like this:
http://localhost:57728/Home/AddAndManageProperties/BaseCategoryId=11/SubCategoryId=14
here is my code:
public class RouteConfig
{
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 }
);
routes.MapRoute(
name: "MyRout",
url: "{controller}/{action}/{BaseCategoryId}/{SubCategoryId}",
defaults: new { controller = "Home", action = "AddAndManageProperties", BaseCategoryId = UrlParameter.Optional, SubCategoryId = UrlParameter.Optional }
);
}
}
And here is the Action Method:
public ActionResult AddAndManageProperties(int? BaseCategoryId, int? SubCategoryId)
{
}
And i call the method AddAndManageProperties by this method
[HttpPost]
public ActionResult AddSubCategory(SubCategory subCategory)
{
return RedirectToAction("AddAndManageProperties", new { BaseCategoryId = subCategory.BaseCategoryId, SubCategoryId = subCategory.SubCategoryId });
}
I am new to ASP.NET MVC so please help me!
Move the MyRout to be before the Default route and change it to
routes.MapRoute(
name: "MyRout",
url: "Home/AddAndManageProperties/{BaseCategoryId}/{SubCategoryId}",
defaults: new { controller = "Home", action = "AddAndManageProperties" }
);
Note that only the last parameter can be marked UrlParameter.Optional so the method needs to be
public ActionResult AddAndManageProperties(int BaseCategoryId, int SubCategoryId)
for the above route, or
public ActionResult AddAndManageProperties(int BaseCategoryId, int? SubCategoryId)
if you modify the above route definition to
defaults: new { controller = "Home", action = "AddAndManageProperties", SubCategoryId = UrlParameter.Optional }
Note, if you also want to include the text "BaseCategoryId" and "SubCategoryId" in the route, use
url: "Home/AddAndManageProperties/BaseCategoryId/{BaseCategoryId}/SubCategoryId/{SubCategoryId}",
That question marks are used for query strings, and they are required because this is how data is assigned to parameters your actions expect. You should not try to remove them, but you could use the [FromBody] attribute, not to send the parameters in query string.
Firstly, and most importantly, your routes are in the wrong order and you have multiple possible URLs that result in calling the wrong route. See Why map special routes first before common routes in asp.net mvc for an explanation.
Secondly, routes cannot contain more than one UrlParamter.Optional.
Third, the = sign is only valid within a query string, unless it is encoded. But IMO, you should not use unsafe characters in a URL to avoid all of the headaches that come with them. A better alternative in this case would be to replace the = with a -.
Finally, if you want to truly make the parameters optional, one approach is to provide multiple routes that allow the parameters in certain routes but not others.
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "BaseCategoryAndSubCategoryId",
url: "{controller}/{action}/BaseCategoryId-{BaseCategoryId}/SubCategoryId-{SubCategoryId}",
defaults: new { controller = "Home", action = "AddAndManageProperties" }
);
routes.MapRoute(
name: "BaseCategoryIdOnly",
url: "{controller}/{action}/BaseCategoryId-{BaseCategoryId}",
defaults: new { controller = "Home", action = "AddAndManageProperties" }
);
routes.MapRoute(
name: "SubCategoryIdOnly",
url: "{controller}/{action}/SubCategoryId-{SubCategoryId}",
defaults: new { controller = "Home", action = "AddAndManageProperties" }
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
}
NOTE: Stephen's answer is also a good alternative to this approach if your parameters are required to be passed in the URL. IMO, it makes more sense to use required parameters if your action method requires both of them in order to function.
But by far the simplest option is to simply use the query string. The parameters can naturally be optional and appended in any order if you do it that way, and you don't need anything more than your Default route.
I have a URL request in the following format: http://localhost/activate?activationCode=X
I would like this request to be handled in the Home controller, by the Activate action.
I am not sure how to proceed. I have looked at RouteConfig.cs and see the way routes are defined here:
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
But how can I make Home/Activate handle URL's of the following format? http://localhost/activate?activationCode=X
...so as to add a special case where activate proceeding the host name goes to the Home controller, and Activate action?
You need to create a specific route
routes.MapRoute(
name: "Activate",
url: "Activate/{id}",
defaults: new { controller = "Home", action = "Activate", id = UrlParameter.Optional }
);
and place this one before the default route.
In addition if you want http://localhost/activate/X rather than http://localhost/activate?activationCode=X, then change it to
routes.MapRoute(
name: "Activate",
url: "Activate/{activationCode}",
defaults: new { controller = "Home", action = "Activate", activationCode = UrlParameter.Optional }
);
and make the method in HomeController
public ActionResult Activate(string activationCode)