OData Action parameter null

Topics: ASP.NET Web API
Mar 25, 2013 at 12:20 PM
Edited Mar 25, 2013 at 12:29 PM
For some reason, the parameter of my OData actions come in as null when called, however, the request body does contain the data send by the client.
I'm probably missing something but I can't seem to figure it out.

I declared my action in global.asax as:
action = model.Entity<Player>().Collection.Action("Register");
action.Parameter<RegistrationData>("registrationData");
action.ReturnsFromEntitySet<Player>("Players");
RegistrationData is a class used only to transfer data required to register and is declared as:
public class RegistrationData
{
    public string DisplayName { get; set; }
    public DateTime DateOfBirth { get; set; }
    public string Email { get; set; }
    //etc
}
([DataContract] and [DataMember] are implied on objects in the model but I also tried explicitly setting them; still null)

The function is declared as the following inside the PlayersController class:
public Player Register(RegistrationData registrationData) { ... }
(object parameters imply [FromBody] but I also tried to explicitly set it; still null)

The function does get triggered. For now I created a workaround (reading the body then parse that using JSON to RegistrationData) but I really just want get it to work as it's supposed to. Not with some workaround.

Also, on a sidenote, are there plans to add OData functions in addition to actions?
Mar 25, 2013 at 1:28 PM
You need [FromBody] on your method parameter.
Mar 25, 2013 at 2:19 PM
Edited Mar 25, 2013 at 2:19 PM
Omar007 wrote:
(object parameters imply [FromBody] but I also tried to explicitly set it; still null)
I already tried that but it was still null.
Mar 25, 2013 at 4:17 PM
Could you check your ModelState if there are any de-serialization errors? Also, did you set the content type header? I spent a lot of time debugging and then realize that I forgot to set the content type header.
Mar 25, 2013 at 6:01 PM
I have the following Content-Type header:
Content-Type: application/json; charset=utf-8
(FYI, I'm using the same value for my Accept header)

The ModelState is invalid. Forgot to include the error. This is the response:
    {
       "odata.error":
       {
           "code": "",
           "message":
           {
               "lang": "en-US",
               "value": "The request is invalid."
           },
           "innererror":
           {
               "message": "registrationData : 'ODataComplexTypeDeserializer' does not support Read. ",
               "type": "",
               "stacktrace": ""
           }
       }
    }
Mar 25, 2013 at 6:07 PM
Your controller action is incorrect. It should be,
[HttpPost]
public Player Register(ODataActionParameters parameters)
{
    RegistrationData registrationData = parameters["registrationData"];
    ...
}
We don't support binding to individual parameters right now. You have to parameter bind to ODataActionParameters and get the parameters individually inside your action.
Mar 26, 2013 at 10:09 AM
Edited Mar 26, 2013 at 10:14 AM
Sadly the ODataActionParameters parameter comes in as null as well.
The ModelState error did change to the following:
"The parameter 'DisplayName' in the request payload is not a valid parameter for the function import 'Register'."
I'm sending the following object:
{
    "DisplayName":"MyAwesomeName",
    "DateOfBirth":"2013-03-26T09:05:44.7199515Z",
    "Email":"e@mail.com",
    //etc
}
Mar 27, 2013 at 7:46 PM
Omar007 wrote:
Sadly the ODataActionParameters parameter comes in as null as well.
The ModelState error did change to the following:
"The parameter 'DisplayName' in the request payload is not a valid parameter for the function import 'Register'."
I'm sending the following object:
{
    "DisplayName":"MyAwesomeName",
    "DateOfBirth":"2013-03-26T09:05:44.7199515Z",
    "Email":"e@mail.com",
    //etc
}
Your request body is incorrect. you have declared that the action takes a single complex parameter with name 'registrationData' and type 'RegistrationData'. So the request body should be more like,
{
    "registrationData" : {
        "DisplayName":"MyAwesomeName",
        "DateOfBirth":"2013-03-26T09:05:44.7199515Z",
        "Email":"e@mail.com",
        //etc
    }
}
Mar 28, 2013 at 9:52 AM
Edited Mar 28, 2013 at 9:53 AM
Indeed it is!
Thanks. it works fine now :)