LeftyX
LeftyX

Reputation: 35587

web.api cannot bind JSON object properly

I am studying angularjs and web.api v2 at the moment.

I am trying to submit a simple javascript object to a web.api 2 controller.
The controller doesn't do much: receives an object and returns it (web.api):

[RoutePrefix("api/v1")]
public class UsersController : ApiController
{
    [HttpPost]
    [Route("users")]
    public IHttpActionResult Save([FromBody] User user)
    {
        return Ok(user);
    }
}

This is the User class (web.api):

public class User
{
    public int Code { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string Address { get; set; }
    public string City { get; set; }
    public string Telephone { get; set; }
    public string Email { get; set; }
}

In my client application I've replicated the object model. My controller returns something like this (angularjs):

vm.user = {
    firstName: '',
    lastName: '',
    address: '',
    city: '',
    telephone: '',
    email: ''
};

and this is my view:

<div class="list card" ng-controller="userregistration as vm">
    <div class="list">
    <label class="item item-input item-stacked-label">
        <span class="input-label">Nome:</span>
        <input type="text" placeholder="" ng-model="vm.user.firstName">
    </label>
    <label class="item item-input item-stacked-label">
        <span class="input-label">Cognome</span>
        <input type="text" placeholder="" ng-model="vm.user.lastName">
    </label>
    <label class="item item-input item-stacked-label">
        <span class="input-label">Indirizzo</span>
        <input type="text" placeholder="" ng-model="vm.user.address">
    </label>
    <label class="item item-input item-stacked-label">
        <span class="input-label">Città</span>
        <input type="text" placeholder="" ng-model="vm.user.city">
    </label>
    <label class="item item-input item-stacked-label">
        <span class="input-label">Telefono:</span>
        <input type="text" placeholder="" ng-model="vm.user.telephone">
    </label>
    <label class="item item-input item-stacked-label">
        <span class="input-label">Email</span>
        <input type="text" placeholder="" ng-model="vm.user.email">
    </label>
    </div>
    <div class="padding">
    <button class="button button-block button-positive" ng-click="vm.registerUser(vm.user);">Crea Utente</button>
    </div>
</div>

and this is the registerUser method in my controller (angularjs):

vm.registerUser = function (user)
{
    dataService.registerUser(user)
    .then(
        function (result) {
        device.showAlert(result.Code, config.name, 'CONGRATULAZIONI');
        },
        function (reason) {
        device.showAlert(reason, config.name, 'ATTENZIONE');
        }
    );
}

My service module (angularjs) receives the user object and POSTs it to my web.api controller:

function saveUser(token, user)
{
var deferred = $q.defer();

$http({
    method: 'POST', url: config.webAPIsBaseUrl + '/api/v1/users',
    // headers: { 'Authorization': 'Bearer ' + token },
    data: { user: user }
})
.success(function (data, status, headers, config) {
    console.log('saveUser() => success.');
    deferred.resolve(data);
    }
)
.error(function (data, status, headers, config) {
    if (data.Message) {
       console.log('saveUser() => error 1.');
       deferred.reject(data.Message);
       }
    else {
        console.log('saveUser() => error 2.');
        deferred.reject("An error occured while registering user!", status);
       }
    }
);
return (deferred.promise);
}

When I send my user object to my API, my controller cannot de-serialize the user properly.

All the fields are empty.

I've investigated a little bit with fiddler and I've seen that the object is wrapped this way:

{"user":{"firstName":"LeftyX","lastName":"","address":"","city":"","telephone":"","email":""}}

I've tried to remove the user wrapper:

{"firstName":"LeftyX","lastName":"","address":"","city":"","telephone":"","email":""}

and now everything works as expected.

QUESTIONs:

Is there a way to bind the javascript object to my controller's model?

Upvotes: 0

Views: 720

Answers (1)

Anthony Chu
Anthony Chu

Reputation: 37520

Instead of passing data: { user: user } to $http(), just pass the user like this...

$http({
    method: 'POST', url: config.webAPIsBaseUrl + '/api/v1/users',
    // headers: { 'Authorization': 'Bearer ' + token },
    data: user
})

Upvotes: 2

Related Questions