Clean Url for MVC index method with parameter - asp.net-mvc-3

I'm new to MVC and Google hasn't been much help so I will ask here.
What I'm trying to do is simple (I would had thought) I want to pass a string to the index method but it generally looks like:
http://mydomain.com/home/index/mystring
and I want:
http://mydomain.com/mystring
How do I go about that?

You could define the following route in Global.asax:
routes.MapRoute(
"MyStringRoute",
"{*mystring}",
new { controller = "Home", action = "Index" }
);
which will invoke the Index action of the Home controller:
public class HomeController : Controller
{
public ActionResult Index(string mystring)
{
return View();
}
}

Related

How to rewrite a URL in MVC3

I have this url http://example.com/Book/Details?Bookid=15 this url
I want rewrite url like this http://example.com/Book/Details/BlackBook/
Add the following route to your global.asax.cs RegisterRoutes:
routes.MapRoute(
"Book By Name",
"Book/Details/{bookName}",
new { controller = "Book", action = "BookDetails" }
);
And you'll need a BookController with the following Action method:
public Book BookDetails(string bookName)
{
// Your logic here to get a book by name and return it
}
Alternatively you can use the default route and create a Details(string id) action method within a BookController to achieve the same result

Recommended API design with ASP.NET MVC3

I'm working with ASP.NET MVC 3. I'm kind of new to it. I think I'm starting to get the hang of it. But there is something that I'm trying to do, that I think makes sense, but maybe I'm wrong.
I'm trying to create an API around Order objects in my database. In order to get all of the orders in the system, I was going to expose an API that looks like the following:
/orders/
In cases where I wanted to get a specific Order, I would simply append an ID. In other words, the URL would look like this:
/orders/12345
In an effort to accomplish this, I created the following controller:
public class OrdersController : Controller
{
// GET: /Orders/
[AcceptVerbs(HttpVerbs.Get)]
public ActionResult Index()
{
string result = "list of orders";
return Json(result, JsonRequestBehavior.AllowGet);
}
//
// GET: /Orders/{orderID}
public ActionResult Index(int id)
{
string result = "order:" + id;
return Json(result, JsonRequestBehavior.AllowGet);
}
}
In my AreaRegistration class, I have the following:
public override void RegisterArea(AreaRegistrationContext context)
{
context.MapRoute(
"OrderList",
"{controller}/{action}",
new { action = "Index", controller="Orders" }
);
context.MapRoute(
"Order",
"{controller}/{action}/{id}",
new { action = "Index", controller = "Orders" }
);
}
When I attempted to access "/orders/", via the browser address bar, I get the JSON like I would expect. However, if I attempt to access "/orders/12345", I receive a 404. What am I missing?
Thank you
You need to also define proper routes in global.asax or use the default route which looks like {controller}/{action}/{id} where controller is defaulted to "Home", action is defaulted to "Index" and id is optional.
So /orders works because you have defined controller (orders), default action (Index) and missing id (which doesn't matter as it is optional)
But when you try /orders/12345 then you have defined controller (orders), action (12345) and missing id
So to make this work with only the default route the request should be /orders/index/12345
edit: for registering area routes you should use AreaRegistration class

Add route for asp.net mvc 3

I need to be able to hande routes like this:
appdomain/city/City-state, so in case somebody used
appdomain/Washington/Washington-DC he retrieves proper info from proper controller action. For now can`t get what controller and action it should be to get this url and handle it properly.
To clear it a bit, there`s like no controller and action, but 2 parameters instead of them.
Why not adding a little help from a fixed path, like Show-City
routes.MapRoute(
"CityAndState",
"Show-City/{city}/{state}",
new { controller = "Cities", action = "Index", id = UrlParameter.Optional }
);
this will never interfere with your existing routes, and then you can use:
http://domain.com/Show-City/New York/NY
at your Index Action inside the Cities Controller you would have something like:~
public class CitiesController : Controller
{
public ActionResult Index(string city, string state)
{
// use city and state variables here
return View();
}
}
Try this:
routes.MapRoute("Foo", "{state}/{city}",
new { controller = "ControllerName", action = "ActionName" });
and in your class you'd have:
public class ControllerNameController : Controller {
public ActionResult ActionName(string state, string city) {
...
}
}

Parameter works in ActionResult, but doesn't exist in RouteData in MVC3?

I have a simple ActionResult in my controller:
public ActionResult Index(int productId)
{
return View();
}
If I breakpoint it, I can confirm the productId is being passed through and is not null. However, if I examine my RouteData:
(int)RouteData.Values["productId"]
There's nothing there. There's a key for controller and a key for the action, but nothing for the parameter? What's going on?
Did you declare the productId as token somewhere in your routes?
routes.MapRoute(
"Default",
"{controller}/{action}/{productId}",
new { controller = "Home", action = "Index", productId = UrlParameter.Optional }
);
If you haven't don't expect to find it in the RouteData collection. This collection contains only tokens that were declared in your routes.
The default route uses id (the one generated by Visual Studio wizard), so you could rename your action parameter:
public ActionResult Index(int id)
{
return View();
}
which would totally make sense in a ProductsController for example. And now you will find it in RouteData.Values["id"].

Overriding routevalues for childaction

I have an index view that takes the page parameter like so:
/News?page=2
But in the layout for that view I have this childaction:
#{Html.RenderAction("Index", "Comments", new {page=1, pagesize = 10});}
But the querystring "page" remains 2.. how come? And how to override page for the childaction?
That's because the child action first looks at the original request query string when binding for values and after that the one passed as argument to the RenderAction helper. You could use a different name for this parameter to avoid this ambiguity.
UPDATE:
Unable to reproduce the behavior you are describing.
Controller:
public class HomeController : Controller
{
public ActionResult Index()
{
return View();
}
[ChildActionOnly]
public ActionResult Test(string page)
{
return Content(page, "text/html");
}
}
View (~/Views/Home/Index.cshtml):
#{Html.RenderAction("Test", "Home", new { page = 1 });}
When querying /Home/Index?page=5 the correct value 1 is shown and the page parameter in the child action is 1.
Obviously if inside your child action you are fetching this value manually from the request it won't work but that's not something you should be doing anyways:
[ChildActionOnly]
public ActionResult Test()
{
string page = Request["page"] as string;
return Content(page, "text/html");
}

Resources