my current url is something like this => http://localhost:4330/Restaurants/?Location=Manchester&Cuisine=0&NetProfit=0&Turnover=0&MaxPrice=120000&SortPriceBy=Low&Page=0
i want it to make something like this => http://localhost:4330/Restaurants/Manchester/?Cuisine=Chinese&MaxPrice=120000
Where Param Query string that doesnt have values (0) will not be included on query string URL
Is it possible?
UPDATED
stringAdd this to Global.asax routes
routes.MapRoute(
"Name of route", // Route name
"Restaurants/{cityid}/", // URL with parameters
new { controller = "Restaurants", action = "Index" } // Parameter defaults
);
This is controller:
public ActionResult Index(string city, int cuisine = 0, int ChineseMaxPrice=0)
{
Return View();
}
Like int cuisine = 0 - this set the default value to parameter if this parameter is not set in querystring
string city - is a parameter that should be in string (not optional)
Try adding add the corresponding route:
routes.MapRoute(
"Restaurants",
"Restaurants/{city}",
new { controller = "Restaurants", action = "Index", city = UrlParameter.Optional }
);
which would map to the Index action on the Restaurants controller:
public ActionResult Index(string city)
{
...
}
Related
I have 3 actions; category, tag and search that has the same type of route signature but the routes start with different values.
Now only the category is working fine but the other two aren't.
Search action shows : localhost/search?s=SOMEWORD in the url and page loads.
But tag action gives me an error: The resource you are looking for has been removed, had its name changed, or is temporarily unavailable.
I wanted my routes to be localhost/{action}/{someWord} but could not.
Controller Actions:
public ActionResult Category(string category, int p = 1)
{
//some caculations
return View("List", viewModel);
}
public ActionResult Tag(string tag, int p = 1)
{
//some caculations
return View("List", viewModel);
}
public ActionResult Search(string s, int p = 1)
{
//some caculations
return View("List", viewModel);
}
RouteConfig:
routes.MapRoute(
"Category",
"Category/{category}",
new { controller = "Blog", action = "Category" }
);
routes.MapRoute(
"Tag",
"Tag/{tag}",
new { controller = "Blog", action = "Tag" }
);
routes.MapRoute(
"Search",
"Search/{s}",
new { controller = "Blog", action = "Search" }
);
Hi. Is this possible to separate URL parameters for two placeholder {Name} and {Surname} like below ?
routes.MapRoute(
name: "Users",
url: "Authorization/{Name}.{Surname}",
defaults: new { controller = "Authorization", action = "Verify" }
);
And in my action method use following code :
private bool Verify (string Name,string Surname)
{
[...]
}
Or do I have to use one placeholder and parse my string to extract information :
routes.MapRoute(
name: "Users",
url: "Authorization/{UserName}",
defaults: new { controller = "Authorization", action = "Verify" }
);
And in Action method use following code :
private bool Verify(string UserName)
{
string name = "UserNameTillDot";
string surname = "UserNameAfterDot";
[...]
}
The first approach is totally fine.
The problem is that your action in controller is defined as private:
Instead of
private bool Verify (string Name, string Surname)
{
[...]
}
It should be
public ActionResult Verify (string Name,string Surname)
{
[...]
}
Also if you want to allow null for Name or Surname you should make them optional:
routes.MapRoute(
name: "Users",
url: "Authorization/{Name}-{Surname}",
defaults: new { controller = "Authorization", action = "Verify", Name = UrlParameter.Optional, Surname = UrlParameter.Optional }
);
You also should place this route before your default route.
EDIT:
There is a issue with "." in the route you can replace it with "-"
I am calling a action with the parameter value. But it is not assigning parameter value to action method parameter.
public ActionResult UserDetail(long? userId)
{
}
localhost/Admin/UserDetail/10 --> 10 is not passed to userId
But
localhost/Admin/UserDetail/?userId=10 --> This works
What causes the first url not working? Any help?
Update:
tried this in global.asax still not working
routes.MapRoute("ExistSiteUser",
"UserDetail/{userId}",
new
{
controller = "Admin",
action = "UserDetail",
// nothing optional
}
);
routes.MapRoute("NewSiteUser",
"UserDetail",
new
{
controller = "Admin",
action = "UserDetail",
userId = UrlParameter.Optional
}
);
change the parameter name to 'id' instead of 'userid' and then try....it should work then
public ActionResult UserDetail(long? id)
{
}
Replace this userID to id :-
public ActionResult UserDetail(long? id)
{
}
I have following patterns
/invitation/mission/busstop -- return the list of busstops
/invitation/mission/busstop/id -- return a specific busstop
/invitation/mission/driver -- return the list of drivers
/invitation/mission/driver/id -- return a specific driver
/invitation/mission/driver/city/model/limit -- query driver accoring to city, model and age limit
...
/invitation/questionair -- return the list of questionairs
/invitation/questionair/id -- return a specific questionair
/invitation/questionair/create -- create a new questionair
/invitation/questionair/update/id -- update a questionair
...
I expect the 'invitation' to be controller, and the rest to be action. Each of the above url should corresponds to a dedicated view page.
Can anyone help me to design the routes?
=====================================================================
I update the patterns, and add my expectation at the end of each url. Any suggest on the url patterns?
Here is the answer to keep your controller simple and still having good url patterns:
Controller:
public class InvitationController : Controller
{
public ActionResult GetAllBusStops()
{
//Logic to show all bus stops
//return bus stops
return View();
}
public ActionResult GetBusStopById(string id) //Assumed your id to be a string
{
//Logic to get specific bus stop
//return bus stop
return View();
}
public ActionResult GetAllDrivers()
{
//Logic for driver list
//return driver list
return View();
}
public ActionResult GetDriverById(int id) //Assumed your id to be an integer
{
//Logic to get specific driver
//return driver
return View();
}
public ActionResult GetDriver(string city, string model,int limit) //Assumed datatypes
{
//Logic to get specific driver with this criteria
//return driver
return View();
}
public ActionResult GetAllQuestionairs()
{
//Logic for questionair list
//return the list
return View();
}
public ActionResult GetQuestionairById(int id) //Assumed your id to be an integer
{
//Logic to get specific questionair
//return it
return View();
}
public ActionResult CreateQuestionair(QuestionairCreateModel model)
{
//logic to create questionair
return View();
}
public ActionResult GetQuestionairById(int id) //Assumed your id to be an integer
{
//Logic to get specific questionair
//return it
return View();
}
public ActionResult UpdateQuestionairById(int id) //Assumed your id to be an integer
{
//Logic to update specific questionair
//return it
return View();
}
}
Now go to your App_Start Folder, Open RouteConfig.cs, start adding the REST urls in the routes as below:
routes.MapRoute(
"List Bus Stops", // Route name
"invitation/mission/busstop", // No parameters for Getting bus stop list
new { controller = "Invitation", action = "GetAllBusStops"}, // Parameter defaults
new { httpMethod = new HttpMethodConstraint("GET") }
);
routes.MapRoute(
"Get Bus stop by id", // Route name
"invitation/mission/busstop/{id}", // URL with parameters
new { controller = "Invitation", action = "GetBusStopById" }, // Parameter defaults
new { httpMethod = new HttpMethodConstraint("GET") }
);
routes.MapRoute(
"Get All Drivers", // Route name
"invitation/mission/driver", // No parameters for Getting driver list
new { controller = "Invitation", action = "GetAllDrivers"}, // Parameter defaults
new { httpMethod = new HttpMethodConstraint("GET") }
);
routes.MapRoute(
"Get Driver by id", // Route name
"invitation/mission/driver/{id}", // URL with parameters
new { controller = "Invitation", action = "GetDriverById" }, // Parameter defaults
new { httpMethod = new HttpMethodConstraint("GET") }
);
routes.MapRoute(
"Get driver for city, model, limit", // Route name
"invitation/mission/driver/{city}}/{model}/{limit}", // URL with parameters
new { controller = "invitation", action = "GetDriver"}, // Parameter defaults
new { httpMethod = new HttpMethodConstraint("GET") }
);
routes.MapRoute(
"Get All Questionairs", // Route name
"invitation/questionair", // No parameters for Getting questionair list
new { controller = "Invitation", action = "GetAllQuestionairs"}, // Parameter defaults
new { httpMethod = new HttpMethodConstraint("GET") }
);
routes.MapRoute(
"Get questionair by id", // Route name
"invitation/questionair/{id}", // URL with parameters
new { controller = "Invitation", action = "GetQuestionairById" }, // Parameter defaults
new { httpMethod = new HttpMethodConstraint("GET") }
);
routes.MapRoute(
"Create New Questionair, // Route name
"invitation/questionair/create", // URL with parameters
new { controller = "invitation", action = "CreateQuestionair" }, // Parameter defaults
new { httpMethod = new HttpMethodConstraint("POST") }
);
routes.MapRoute(
"Update Questionair, // Route name
"invitation/questionair/update/{id}", // URL with parameters
new { controller = "invitation", action = "UpdateQuestionairById" }, // Parameter defaults
new { httpMethod = new HttpMethodConstraint("POST") }
);
Many things are assumed like the datatypes and model names. You can figure out how it works from this....
Add the route in the global.asax
routes.MapRoute(
"Default",
"{controller}/{id}",
new { controller = "invitation", action = "Index" }
);
Then in your controller use something like:
public class InvitationController : Controller
{
public ActionResult Index(string id)
{
switch(id.ToLower())
{
case "mission/busstop/list":
return View("busstop/list");
case "mission/driver/query":
return View("driver/query");
}
//Return default view
return View();
}
}
The other answers are valid, but I think there is a much easier, cleaner, and more maintainable way of defining your routes: use an attribute-based route mapper.
The easiest one I've found to use is the RiaLibrary.Web route mapper. All you have to do is add an attribute on each method you want to have a route for - then specify your route details.
To get set up, you must follow a few steps outlined on the RiaLibrary.Web page. After completing those steps, you can change any Controller action to look like this:
[Url("Articles/{id}")]
public ActionResult Details(int id)
{
// process
return View();
}
If you have any optional parameters, declare them as {param?} in the route string and then as int? param in your method declaration.
That's it! You can also include some other parameters to specify whether only certain types of HTTP calls match this route, to define constraints on parameters, and to fix the order in which this route is matched.
I am working on a website in asp.net mvc. I have a route
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional }
// Parameter defaults
);
which is the default route. And I have a method
public ActionResult ErrorPage(int errorno)
{
return View();
}
Now if I want to run this code with http://something/mycontroller/Errorpage/1
it doesn't work. But if I change the parameter name to id from errorno
it works.
Is it compulsory to have same parameter name for this method? Or do I need to create separate routes for such situations?
So, you have a parameter named errorno, and you want it to have a value from parameter id. This is obviously the binding problem.
How to solve it:
create a class for model binder:
public class ParameterBinder : IModelBinder
{
public string ActualParameter { get; private set; }
public ParameterBinder(string actualParameter)
{
this.ActualParameter = actualParameter;
}
public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
object id = controllerContext.RouteData.Values[this.ActualParameter];
return id;
}
}
create a custom attribute for custom model binding:
[AttributeUsage(AttributeTargets.Parameter)]
public class BindParameterAttribute : CustomModelBinderAttribute
{
public string ActualParameter { get; private set; }
public BindParameterAttribute(string actualParameter)
{
this.ActualParameter = actualParameter;
}
public override IModelBinder GetBinder()
{
return new ParameterBinder(this.ActualParameter);
}
}
apply the new attribute to your action parameters as needed:
public ActionResult ErrorPage(
[BindParameter("id")]
int errorno)
{
return View();
}
Now your errorno will have the value, which was passed as id for your url.
Note: you can remove the paramter id from the example above, if you are sure you need it solved only for id.
Leaving this way will allow you bind other parameters too.
Option 1
routes.MapRoute(
"Default",
"{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
public ActionResult ErrorPage(int id)
{
return View();
}
Option 2
routes.MapRoute(
"Default",
"{controller}/{action}/{errorno}",
new { controller = "Home", action = "Index", errorno = UrlParameter.Optional }
);
public ActionResult ErrorPage(int errorno)
{
return View();
}
Option 3
routes.MapRoute(
"Default",
"{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
public ActionResult ErrorPage(int id)
{
int errorno = id;
return View();
}
use the bind attribute prefix:
public ActionResult Customer([Bind(Prefix = "id")]string cname) {}
#Parminder
The default route can handle all action with one parameter "id". And I think not every action need this parameter. So I change my default route
routes.MapRoute(
"Default",
"{controller}/{action}",
new { controller = "Home", action = "Index"}
);
and you can add a new route:
routes.MapRoute("errorpage", "yourcontroller/errorpage/{errorno}",
new {controller="controllername", action="errorpage"});
this just handle your controll name is "controllername". If you want to handle all controller, you can add this:
routes.MapRoute("errorpage", "{controller}/errorpage/{errorno}",
new {controller="controllername", action="errorpage"});
This method will create very much code in global.asax if you need a lot of custom route.
You could either rename the parameter in the default root (which probably is not a good idea) or rename it in the action method. Adding another root will not help because it will be the same as the default one and given an url the routing engine cannot distinguish between the two and will always take the first one in the list.
try to use the same name of parameter in action method as in in the route table url parameter.
global.asx
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);
myController
public ActionResult ErrorPage(int id)
{
return View();
}