I have the following action. I can hit this with
/basket/address?addressId=123
However i wonder how i can hit it with
/basket/address/123
public ActionResult Address(int addressId)
{
return RedirectToAction("Index");
}
my routes
routes.MapRoute(
"Default", // Route name
"{controller}.aspx/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = "" } // Parameter defaults
);
Change:
public ActionResult Address(int addressId)
to
public ActionResult Address(int id)
Related
why use custom routing in asp.net MVC
for example
RouteConfig.cs
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
//Enable Routing
routes.MapMvcAttributeRoutes();
//custom route for about page
//routes.MapRoute(
// name:"about",
// url: "Home/About",
// defaults: new { controller = "Home",action= "About", id=UrlParameter.Optional}
// );
//custom route for contactus page
//routes.MapRoute(
// name: "about",
// url: "Home/ContactUs",
// defaults: new { controller = "Home", action = "ContactUs", id = UrlParameter.Optional }
// );
//default route
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
}
HomeController.cs
public class HomeController : Controller
{
// GET: Home
public ActionResult Index()
{
return View();
}
//[Route("Home/About")]
public ActionResult About()
{
return View();
}
//[Route("Home/ContactUs")]
public ActionResult ContactUs()
{
return View();
}
}
Index.cshtml
IndexPage
About.cshtml
AboutPage
Contactus.cshtml
ContactusPage
when I run the project then write the URL manually then also give output then why use the routing attribute
home/index
home/about
home/contactus
I comment the route attribute and custom route code and above URL give the proper output then why use route attribute
my question is without route attribute easily run the action method then why need to use route attribute above the controller
If you are happy with the default routes, then you don't need to use the route attributes, or put any custom routes in the RouteConfig.
You can add routes to customise how users get to your pages, either through parameters for more dynamic pages, or to make page urls more friendly - for example:
//make about us page url "/about"
routes.MapRoute(
name:"about",
url: "about",
defaults: new { controller = "Home",action= "About"}
);
//make a product page expect an id param in the url
//for example "/catalog/product/pid1"
//"/catalog/product/pid2"
//"/catalog/product/pid3"
//"/catalog/product/pid4" all match this route
routes.MapRoute(
name:"product",
url: "catalog/product/{productId}",
defaults: new { controller = "Catalog",action= "Product"}
);
The same can be achieved in route attributes:
[Route("about")]
public ActionResult AboutUs()
{
return View();
}
[Route("catalog/product/{productId}")]
public ActionResult GetProduct(string productId)
{
//Get product, build view data etc...
return View();
}
I have a web page www.example.com which points to a HomeController index. When I run the website I get the HomeView.
Now the requirement is when I type www.example.com/Japan I need to run a different view.
What I did:
public ActionResult Index(string country)
{
ViewBag.Message = "my country=" + country;
return View();
}
But it gives me an error:
The current request for action 'Index' on controller type 'HomeController'
is ambiguous between the following action methods:
System.Web.Mvc.ActionResult Index() on type MvcApplication_2.Controllers.HomeController
System.Web.Mvc.ActionResult Index(System.String) on type MvcApplication_2.Controllers.HomeController
What should I be doing to achieve this one?
I do not want to use http://example.com/country/japan.
I want to use http://example.com/japan.
my code:
RouteConfig.cs
namespace MvcApplication_2
{
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: "ByCountry",
url: "{country}",
defaults: new { controller = "Home", action = "IndexByCountry" }
);
}
}
}
Homecontroller.cs
public class HomeController : Controller
{
[HttpGet]
public ActionResult Index()
{
ViewBag.Message = "Modify this template to jump-start your ASP.NET MVC application.";
return View();
}
[ActionName("IndexByCountry")]
public ActionResult Index(string country)
{
ViewBag.Message = "Japan man.";
return View("Index");
}
public ActionResult About()
{
ViewBag.Message = "Your app description page.";
return View();
}
public ActionResult Contact()
{
ViewBag.Message = "Your contact page.";
return View();
}
}
You can't have the same HTTP verb for the same action name. In other words, having HttpGet for the same action name, even an overload, isn't possible.
You have three options:
Change one or your action methods to a different HTTP action verb...
[HttpGet]
public ActionResult Index()
{
//..
}
[HttpPost]
public ActionResult Index(string country)
{
//..
}
Or, change the name of your action method...
public ActionResult CountryIndex(string country)
{
ViewBag.Message = "my country=" + country;
return View();
}
Or, you can change the action name from the overloaded method...
public ActionResult Index()
{
//..
}
[ActionName("IndexByCountryName")]
public ActionResult Index(string country)
{
//..
}
Working example
This uses the last option, keeping the method name overloaded but specify the ActionNameAttribute for the overload
Actions
public ActionResult Index()
{
ViewBag.Message = "no country selected!";
return View();
}
[ActionName("IndexByCountry")]
public ActionResult Index(string country)
{
ViewBag.Message = string.Format("County selected :: {0}", country);
// the below ActionResult reuses the Index view but
// here you could have a separate view for the country
// selection if you like
//
return View("Index");
}
Routes
routes.MapRoute(
name: "ByCountry",
url: "{country}",
defaults: new { controller = "Home", action = "IndexByCountry" }
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
You can use AttributeRouting.
[Route("Home/Index/{country}")
public ActionResult Index(string country)
{
ViewBag.Message = "my country=" + country;
switch(country)
{
case "Country1":
return View("ViewName")
}
// To do
}
string actionName = "Users";
[HttpGet]
[ActionName(actionName)]
public ActionResult GetMe()
{
}
...gives: An object reference is required for the non-static field, method, or property
That was just a test though, is there a way to do this? If so, I could re-use the same Controller and possibly create new URIs on the fly... right?
Assuming you have the following controller:
public class HomeController : Controller
{
public ActionResult Index()
{
return View();
}
}
you could write a custom route handler:
public class MyRouteHander : IRouteHandler
{
public IHttpHandler GetHttpHandler(RequestContext requestContext)
{
var rd = requestContext.RouteData;
var action = rd.GetRequiredString("action");
var controller = rd.GetRequiredString("controller");
if (string.Equals(action, "users", StringComparison.OrdinalIgnoreCase) &&
string.Equals(controller, "home", StringComparison.OrdinalIgnoreCase))
{
// The action name is dynamic
string actionName = "Index";
requestContext.RouteData.Values["action"] = actionName;
}
return new MvcHandler(requestContext);
}
}
Finally associate the custom route handler in your route definitions:
routes.MapRoute(
"Default",
"{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = UrlParameter.Optional }
).RouteHandler = new MyRouteHander();
Now if you request /home/users it's the Index action of the Home controller that will be served.
You can just take another routing argument in and do a switch statement.
I have two actions in a controller and yet the parameters are not being passed into one of them.
This one: /RouteStop/List/1
And this one: /RouteStop/Details/100
And my global.asax:
routes.MapRoute(
"List",
"{controller}/{action}/{id}",
new { controller = "RouteStop", action = "List", id = UrlParameter.Optional }
);
routes.MapRoute(
"Details",
"{controller}/{action}/{routeID}",
new { controller = "RouteStop", action = "Details", routeID = UrlParameter.Optional }
);
And here's the actions from my Controller:
public ActionResult List(string id)
{
return View();
}
public ActionResult Details(string routeID)
{
return View();
}
When I access this URL (/RouteStop/Details/100) the parameter gets passed just fine. But when I access the other one (/RouteStop/List/1) the parameter is null. The names match up as they should but I can't figure it out.
Try replacing {controller} with List and Details in respective routes. but for your scenario the default routing that you get when you create an MVC app should work.
Let's say I have the following rule
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);
And in the controller
public ActionResult Forums(int id)
{
Response.Write(id); // works
Response.Write(Request.QueryString["id"]); // doesn't
return View();
}
How can I get it with Request.QueryString?
I think you need to go through RouteData to access the routing parameters.
E.g.
Routedata.Values["id"]