Url route with datetime for web api in asp.net webapi - asp.net-web-api

[using WEB Api 1.0]
Need to configured the action with the following GET url
api/v1/Customer/{Id}/Instances/find?start_date={startDate}&end_date={endDate}
Where id,startDate and endDate 3 parameters are mandatory
The webapiconfig is as below for the method
config.Routes.MapHttpRoute(
name: "CustomerInstances",
routeTemplate: "api/v1/Customer/{id}/Instances/find",
defaults: new { controller = "api", action = "CustomerInstances" });
The ApiController action is as below
[HttpGet]
public IEnumerable<Customer> CustomerInstances(int id,DateTime startDate,DateTime endDate)
{
return customer;
}
Please help me i am stuck as i get the error
Issue 1:
The parameters dictionary contains a null entry for parameter
'startDate' of non-nullable type 'System.DateTime' for method
'CustomeInstances(Int32, System.DateTime,System.DateTime)' in
'apiController'. An optional parameter must be a reference type, a
nullable type, or be declared as an optional parameter.
Issue 2
I even tried to make Datetime as nullable i.e Datetime? startDate=null but i get startDate as null all the time the values are not getting bind not sure why.
This seems to be weird
Thanks in advance

Related

ASP.NET WebAPI routing confusing me with null paramters

I can't figure out why I need to create an empty method signature to allow a Get rest call with 3 null parameters to work. I have the following Code:
public class SessionPresenterController : ApiController
{
public HttpResponseMessage Get()
{
return Get(null, null, null);
}
public HttpResponseMessage Get(int? codeCampYearId, int? sessionId, int? attendeesId)
{
and in my WebApiConfig I have
config.Routes.MapHttpRoute
("API Default Rest", "rest/{controller}/{id}",
new { id = RouteParameter.Optional });
config.Routes.MapHttpRoute
("API Default RPC", "rpc/{controller}/{action}/{id}",
new { id = RouteParameter.Optional });
If I call /rest/SessionPresenter without any parameters and I Don't have the Get() defined, the Get with the three null parameters is not found.
Why not?
Try specifying defaults for your parameters:
public HttpResponseMessage Get(
int? codeCampYearId = null,
int? sessionId = null,
int? attendeesId = null)
{
//...
}
Jacobs' snippet will solve your issue. Let's answert the question why not? why get is not found..
There is a complete documentation of the Routing and Action Selection. Let's use some extratc and reveal what happens:
Action Selection
Create a list of all actions on the controller that match the HTTP request method.
If the route dictionary has an "action" entry, remove actions whose name does not match this value.
Try to match action parameters to the URI, as follows:
For each action, get a list of the parameters that are a simple type, where the binding gets the parameter from the URI. Exclude optional parameters.
From this list, try to find a match for each parameter name, either in the route dictionary or in the URI query string. Matches are case insensitive and do not depend on the parameter order.
Select an action where every parameter in the list has a match in the URI.
If more that one action meets these criteria, pick the one with the most parameter matches.
Other words, if there will be only Get with three parameters (omited Get()), to decided which action should be selected:
Selected was Get(int? codeCampYearId, int? sessionId, int? attendeesId)
still the Get(int? codeCampYearId, int? sessionId, int? attendeesId) is selected
URL is /rest/SessionPresenter
no optional parameters excluded. All have to be found
URL does not have a match for all three parameters
So to solve it, we have to either pass all params (empty, null):
/rest/SessionPresenter?codeCampYearId&attendeesId&sessionid
Or change the signature to have parameters optinal (Jacobs' answer), and skipped during the action selection

MVC 3 exception: The parameters dictionary contains a null entry for parameter 'id' of non-nullable type 'System.Int32' for method 'System.Web.Mvc

My application seems to run fine, but I keep getting these exceptions in log4net logs:
The parameters dictionary contains a null entry for parameter 'id' of non-nullable type 'System.Int32' for method 'System.Web.Mvc.ActionResult Agency(Int32)' in 'COPSGMIS.Controllers.QuestionController'. An optional parameter must be a reference type, a nullable type, or be declared as an optional parameter.
Not sure whats going wrong?
My controller:
public ActionResult Agency(int id)
{
QuestionDAL qd = new QuestionDAL();
var agency = qd.GetAgencyDetails(id);
agency.Reviews = qd.GetAgencyReviews(id);
return View(agency);
}
My routes:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);
}
This error is thrown if you attempt to call this controller action and you do not specify the id either in the path portion or as query string parameter. Since your controller action takes an id as parameter you should make sure that you always specify this parameter.
Make sure that when you are requesting this action you have specified a valid id in the url:
http://example.com/somecontroller/agency/123
If you are generating an anchor, make sure there's an id:
#Html.ActionLink("click me", "agency", new { id = "123" })
If you are sending an AJAX request, also make sure that the id is present in the url.
If on the other hand the parameter is optional, you could make it a nullable integer:
public ActionResult Agency(int? id)
but in this case you will have to handle the case where the parameter value is not specified.

WebApi parameters

I am very new to WebApi and don't understand parameters mapping.
I had a controller with HttpGet method with 2 parameters. In WebApiConfig mapping defined like
config.Routes.MapHttpRoute(
name: "MyActionApi",
routeTemplate: "api/{controller}/{action}/{p},{q}");
which seemed to work fine.
By analogy I've added another controller (DetailsController) that has 3 parameter HttpGet method.
I've added
config.Routes.MapHttpRoute(
name: "MyActionApi2",
routeTemplate: "api/{controller}/{action}/{p},{q},{r}");
But navigating to
http://mysite/api/Details/CrossReport/12,14,Peter
gives 404 error and says
No action was found on the controller 'Details' that matches the request.
But navigating like this
http://mysite/api/Details/FilterByDate/12,14?q=10
gives correct results.
Why is that? I'd like to have it comma separated as in the first case. And why it works in first case but not the second one?
Working controller's method:
public IEnumerable<Order> FilterByDate(DateTime dateStart, DateTime dateEnd).
Not working:
public IEnumerable<Detail> FilterByDate(DateTime dateStart, DateTime dateEnd, int maxCount)
Both have HttpGet attribute.
You need to define a matching action. Try adding an action with the following signature on your DetailsController class:
[HttpGet]
public IEnumerable<Detail> CrossReport(string p, string q, string r)
As you see, the action name and parameter names must match what you have on your route.
One thought, have you made sure that MyActionApi2 ahead of MyActionApi in you routing config? If I am not mistaken, It looks for the first possible match... and so MyActionApi would match (even if there are 3 parameters)
There are two types of parameters in WebApi: parameters in routes and parameters in body/url.
Parameter in route
In this example the id param is in the route.
http://mysite/api/Details/CrossReport/{id}
The route params are separate by "/" and there are part of the route.
http://mysite/api/Details/CrossReport/{id}/{name}/{detailId}
In your web api controller you must be:
public IEnumerable<Order> FilterByDate(int id, string name, int detailId)
Parameter in body/url
The parameters in url are separate by & and all this params are after a ? in route. For example.
http://mysite/api/Details/CrossReport?id=3&name="john"&detailId=5
And in your web api controller is the same:
public IEnumerable<Order> FilterByDate(int id, string name, int detailId)
If the object is compound by others properties:
public class MyObject
{
public int Id { get; set; }
public string Name { get; set; }
}
You can only have one in the body of the message and you have to send in the body on the message and your web api controller receipt them:
public IEnumerable<Order> FilterByDate(MyObject obj)

Web API nested routing not working as expected

I am having difficulty with a nested Web API routing set-up.
Given a routing config of:
config.Routes.MapHttpRoute(
name: "UsersGroups",
routeTemplate: "api/users/{userID}/groups/{groupID}",
defaults: new { controller = "UsersGroups", groupID = UrlParameter.Optional }
);
and controller actions like thus:
public AuthGroup Get(long userID, int groupID)
{
//Get specific group here
}
public IEnumerable<AuthGroup> Get(long userID)
{
//get all groups for user here
}
Calling this route /api/users/1528/groups gives this error:
The parameters dictionary contains a null entry for parameter groupID of non-nullable type System.Int32 for method AuthGroup Get(Int64, Int32) in UsersGroupsController. An optional parameter must be a reference type, a nullable type, or be declared as an optional parameter.
I was expecting it to grab the action with the single long parameter, but obviously for some reason it's ignoring this and going straight for the one with most arguments.
Based on what's available at MS on how Web API interprets routes: http://www.asp.net/web-api/overview/web-api-routing-and-actions/routing-and-action-selection I think what I have should be correct, but obviously it is not working as it seems like it should.
You should use RouteParameter.Optional (from Web API), not UrlParameter.Optional (from ASP.NET MVC).
Everything will behave as you want then.
More info:
UrlParameter.Optional - http://msdn.microsoft.com/en-us/library/system.web.mvc.urlparameter.optional(v=vs.108).aspx
RouteParameter.Optional - http://msdn.microsoft.com/en-us/library/system.web.http.routeparameter.optional(v=vs.108).aspx

MVC Ajax Int32 error

Hi when I try to do an Ajax post to my controller I keep getting this message:
The parameters dictionary contains a
null entry for parameter 'id' of
non-nullable type 'System.Int32' for
method 'System.Web.Mvc.JsonResult
GetContactsByDepartment(Int32)' in
'Intranet.Controllers.MyController'.
An optional parameter must be a
reference type, a nullable type, or be
declared as an optional parameter.
The method head looks like this: public JsonResult GetContactsByDepartment(int id)
What am I missing? I have ensured that the id is being passed through my Jquery ajax call.
Try to rename id to for example DepartmentID.
Probably an issue with your registered routes.

Resources