mvc3 IModelBinder and url - asp.net-mvc-3

I'm having a problem using iModelBinder with url in the format of
http://localhost/controller/action/id/value
the action would be the function in the controller
the id/value is ie. id=12
When I try the above link i receive a 404 error page not found, and looking at the stack I can understand that MVC is looking for a path it does not understand.
using the following works
http://localhost/controller/action?id=value
If anyone as any idea if this problem can be resolved, I would really like to be able to use "/" as separators.
Vince

The url should really be in the format:
http://localhost/controller/action/id
For example:
http://localhost/products/index/1
And the id should then be specified in the controller action. For example:
public ActionResult Index(int id)
{
...
The route specified in the global.asax file will specify the format of the url. For the above url the default route will suffice:
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);
Then the default model binder will automatically bind your id (i.e. 1 in the above url) to the int id in the action.
Like Adam was suggesting, I don't think you should specify the name of the id in the url as it is automatically bound to for you by the default model binder.

Related

web api support parameters while they don't have one

http://localhost:xxxx/api/BindAppointmentResources
works fine for me but when I'm trying to add any invalid object after controller (with this ? "http://localhost:xxxxx/api/BindAppointmentResources?Userid") in URL its gets the same result
I tried action-based routing , attribute routing so far but same result?
PS : I don't have parameters in WEB API
Route Config :
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
}
}
Query string parameters will automatically get bound to your parameters that have the same name in web api.
If no parameter names are found it will route the request to the base url (which is the url before the question mark).
So this url
http://localhost:xxxx/api/BindAppointmentResources?UserID=1
will, if no method with parameter name that match UserID are found, end up being routed to
http://localhost:xxxx/api/BindAppointmentResources
In the Get method you can still get the query string
var queryString = this.Request.GetQueryNameValuePairs();
To prevent binding parameters from query string and only allow bindings from route values, you could remove the default QueryStringValueProviderFactory from the default HttpConfiguration configuration. Read more about it in this article

Passing a parameter on a Web API Get method

This is my api controller method to get a list of items filtered by a user id.
public IEnumerable<MyItemListItemDTO> Get(int userId)
When calling the method from the client why won't /MyItems/Get/11 work and /MyItems/Get?userId=11 does?
Because on the parametrized URL the name of the parameter is id rather than userId. Model binder checks the name of the parameter to do the binding. Look on the routes definition and you'll see that.
What I mean, basically is that on the RouteConfig.cs file you have as the default route the following:
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
Look that the URL is controller/action/id and the name of the last parameter is id. So, in some action, to receive that piece of the URL you must match the name of the parameter.

Hierarchies in MVC3

Im working my way though an ASP.NET MVC tutorial and couldnt find the answer im looking for.
I understand that each controller class in the 'Controller' root folder is mapped to a Url, so:
****Controller Folder****
|- StoreController.cs
Maps to $url/Store
However, If I wish to creater a 'subfolder'
I.e. a Controller class located for $url/Store/Testing I cant seem to see how I go about it.
I tried deriving a class from StoreController.cs, but that didnt work.
URLs do not necessarily correspond to MVC application internal folder structure. You can use MVC routing tables to conceal the internal structure and redirect specific URLs to any controllers/actions you want. For example, you can create a TestingController.cs class in the Controllers folder and use this route in Global.asax:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"Store-Testing", // Route name
"Store/Testing/{action}/{id}", // URL with parameters
new { controller = "Testing", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);
}
In this case, a request to http://[domain]/Store/Testing will be handled by TestingController.
That url would with the default route point to an action called Testing, within the Store controller.
You can however create your own custom routes in your global.asax file.

Incorrect Routing is ASP.NET MVC

I don't know why I have such problems with ASP.NET MVC routing. I wish there was a tool that showed me which routes I had currently setup. Regardless,
In my global.asax.cs file I have the following:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"SignUp", // Route name
"account/{controller}/{action}", // URL with parameters
new { controller = "Home", action = "Register" } // Parameter defaults
);
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);
}
I have the following defined in HomeController.cs
public ActionResult Register()
{
return View();
}
I was expecting to be able to access this page by visiting /account/register in my browser. However, I continue to get a 404. What am I doing wrong?
/Account/Register matches your first route.
The word Register is matched to the {controller}, so it looks for a controller named RegisterController.
replace
routes.MapRoute(
"SignUp", // Route name
"account/{controller}/{action}", // URL with parameters
new { controller = "Home", action = "Register" } // Parameter defaults
);
with
routes.MapRoute(
"SignUp", // Route name
"account/{action}", // URL with parameters
new { controller = "Home" } // Parameter defaults
);
This will mean /account/register will route to the Register action on the Home controller. It will also mean that action links and other links you generate via #Html.ActionLink("Register", "Register", "Home") will generate the URL /account/register
Think of the 'URL with paramters' as a pattern that the URL will be matched against.
The problem with your original route map is that it is looking for a URL like this /account/controllername/actionname. So, when you go /account/register - it is taking register as the controller name, and taking the default action name (in this case register) - and as the 'register' action does not exist in the 'register' controller - you are getting a 404.
UPDATED
I updated my suggested route as per Robert's comments.
It is also worth noting, as Robert states, that this whole thing could be made more simple by making a 'Account' controller, and moving the 'Register ' action there. Then you could delete the 'SignUp' route, and just use default routing. If you thought about it, you'd agree that this would be a better place for a 'Register' action than the 'Home' controller.
Try using this nugget package http://nuget.org/packages/Glimpse.Mvc3
You can find more info about glimpse on http://getglimpse.com/

Did Microsoft change the way to pass string as parameter in ASP.NET MVC 3?

I have this simple question. Previously, when I wanted to call a controller method with only one parameter, I could do it simply calling /ControllerName/Method/Parameter, whatever type this parameter was. Now, I did the same thing with an integer value without problems, but with a string it didn't work. Am I going nuts or Microsoft actually changed this?
The default route that you'll find in Global.aspx.cs is still the following:
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = "" } // Parameter defaults
);
So your "parameter" is the {id} in the example above, presumably a number as IDs tend to be. Get to know your routes, they're fun! Linkage: http://www.asp.net/mvc/tutorials/asp-net-mvc-routing-overview-cs
I'm imagining your actions that work for ints look something like this:
public ActionResult Index(int id)
If you want to accept a string parameter instead of an integer and have it be part of the (default) route, it also would need to be named id in the method signature, like so:
public ActionResult Index(string id)
If you had an action with a signature like this:
public ActionResult Post(string slug)
Then with the default route slug would only have a value if you had a querystring (get) or form (post) value with the key slug. A route that would match the above action and have the slug parameter be populated (assuming it was a method of the BlogController controller) would be:
routes.MapRoute(
"BlogPost",
"post/{slug}",
new { controller = "Blog", action = "Post", slug = "" }
);

Resources