ASP.Net Web Api not binding model on POST
Asked Answered
H

3

15

I'm trying to POST JSON data to a Web Api method but the JSON data is not binding to the model.

Here's my model:

[DataContract]
public class RegisterDataModel
{
    [DataMember(IsRequired = true)]
    public String SiteKey { get; set; }

    [DataMember(IsRequired = true)]
    public String UserId { get; set; }

    [DataMember(IsRequired = true)]
    public String UserName { get; set; }
}

Here's my Web Api action:

    public class RegisterController : ApiController
    {
    public Guid Post([ModelBinder] RegisterDataModel registerDataModel)
    {
        if (!ModelState.IsValid)
        {
            throw new ModelStateApiException(ModelState);
        }
        var userProfileDataContract = userProfileBusinessLibrary.GetNewOne();
        userProfileDataContract.UserId = registerDataModel.UserId;
        userProfileDataContract.UserName = registerDataModel.UserName;

        var userKey = userProfileBusinessLibrary.Register(registerDataModel.SiteKey, userProfileDataContract);

        return userKey;
    }
    }

Before I added [ModelBinder], registerDataModel was null. After adding [ModelBinder], registerDataModel is a RegisterDataModel instance, but all of the property values are null.

Here's my Request via Fiddler:

http://local.testwebsite.com/api/register

Request Headers:
User-Agent: Fiddler
Host: local.testwebsite.com
Content-Length: 89
Content-Type: application/json; charset=utf-8:

Request Body:
{ 
 "SiteKey":"qwerty",
 "UserId": "12345qwerty", 
 "UserName":"john q"
}    

What am I missing to make my post data bind to the RegisterDataModel properties? Thanks for your help.

Hawn answered 6/10, 2012 at 16:33 Comment(2)
You might just need the [Post] attribute on your controller action.Naumann
Thanks for reply, but adding [HttpPost] did not help. It's my understanding with WebApi that you do not need the http verb attributes because ASP.net MVC uses a convention of matching the verb to the controller action.Hawn
C
12

How are you creating the JSON request? Through Fiddler request builder? Try just the following in the request body.

{ 
 "SiteKey":"qwerty",
 "UserId": "12345qwerty", 
 "UserName":"john q"
}

I'm guessing 'Request Body:' is also part of your request body. Remove that and check.

Cingulum answered 6/10, 2012 at 17:39 Comment(4)
I'm using Fiddler's composer to submit the json data to my web api. Here's a screen shot: screencast.com/t/x2IH6hp01rGQHawn
If I just remove the [ModelBinder], it works perfectly for me. I just copy pasted your code and tested it. One difference I'm seeing here is that your content-Length is 89. Mine is 64 for the exact same payload. That's why I'm guessing you are sending something extra like 'Request Body:'Cingulum
Oh, btw, there is an extra colon or a semi-colon next to utf-8 Content-Type: application/json; charset=utf-8: Remove that and try pleaseCingulum
It was a combination of having [ModelBinder] and the ":" typo. Thanks for your help.Hawn
P
14

Not related to the OP's problem, but the title of the question led me here when I used (public) fields instead of properties in the Model class (i.e. no {get; set;}). It turned out that this also causes the binding to fail.

Maybe helps someone.

Potted answered 6/10, 2012 at 16:33 Comment(3)
I had exactly the same problem and adding a get and set resolved this.Formate
This helped me as well. Glad to see it wasn't deleted, it definitely belongs with this question title even if OP already had properties.Mercaptide
This helped me. Thanks a lot!Horsehair
C
12

How are you creating the JSON request? Through Fiddler request builder? Try just the following in the request body.

{ 
 "SiteKey":"qwerty",
 "UserId": "12345qwerty", 
 "UserName":"john q"
}

I'm guessing 'Request Body:' is also part of your request body. Remove that and check.

Cingulum answered 6/10, 2012 at 17:39 Comment(4)
I'm using Fiddler's composer to submit the json data to my web api. Here's a screen shot: screencast.com/t/x2IH6hp01rGQHawn
If I just remove the [ModelBinder], it works perfectly for me. I just copy pasted your code and tested it. One difference I'm seeing here is that your content-Length is 89. Mine is 64 for the exact same payload. That's why I'm guessing you are sending something extra like 'Request Body:'Cingulum
Oh, btw, there is an extra colon or a semi-colon next to utf-8 Content-Type: application/json; charset=utf-8: Remove that and try pleaseCingulum
It was a combination of having [ModelBinder] and the ":" typo. Thanks for your help.Hawn
C
1

In my case, app's requests are passed through a middleware called "API Manager" for authentication / authorization before forwarding to my .NET Web API. POST parameter isn't binded because, for some reason I'm no idea why, the "Content-Length" is emitted from the Headers.The reason is because, the default JsonMediaTypeFormatter always check requests' Content-Length before doing model binding, and if the Content-Length is not presented it will set the parameter to NULL.

Coppins answered 5/10, 2015 at 6:24 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.