Dismiss
Announcing Stack Overflow Documentation

We started with Q&A. Technical documentation is next, and we need your help.

Whether you're a beginner or an experienced developer, you can contribute.

Sign up and start helping → Learn more about Documentation →

I would like to collect some data using AngularJS and post it back to my ASP.NET WebAPI controller.

I have defined my business object like this (which just aims to record overall annual petrol consumption along with consumption every month):

public class PetrolViewModel
{
    public double petrol_annual { get; set; }
    public int petrol_measure { get; set; }

    public List<Month> months { get; set; }

}

public class Month
{
    public double jan { get; set; }
    public double feb { get; set; }
}

In my Angular code I have:

var app = angular.module('petrol', []);

app.controller('PetrolController', function ($scope, $http) {

$scope.petrol = {};

$scope.petrol.months = {};

$scope.sendForm = function() {
    $http({
        method: 'Post',
        url: 'api/values',
        data: $scope.petrol
    }).success(function (data, status, headers, config) {
        console.log(data);
        console.log(status);
        console.log(headers);
    }).error(function (data, status, headers, config) {
        console.log(data);
        console.log(status);
        console.log(headers);
    });
};

});

When I submit the form data and leave the WebApi controller to receive an anonymous object it seems to work and I get my form data:

Debug information when passing in an object type

But, if I change this and try to pass in the ViewModel I defined earlier I get a null object being passed in:

Null object when trying to pass in as ViewModel

I want to take full advantage of the ASP.NET features to automatically map the matching names and deliver me a populated Object that I can then handle in my code. I don't want to have to map the anonymous object to the ViewModel.

So, the programming question is: How do I make sure my AngularJS object can be matched to a ViewModel?

In tutorials I've been watching this seems to "just work" for everyone else so they tend not to cover it in much detail.

Here is the JSON that is being sent up, according to Fiddler:

{"months":{"jan":"10","feb":"10","mar":"10","apr":"10","may":"10","jun":"10","jul":"10","aug":"10","sep":"5","oct":"5","nov":"20","dec":"10"},"petrol_annual":"120","petrol_measure":"1"}
share|improve this question
    
Can you show an example of the JSON you're sending up? – Andrew Whitaker Nov 9 '14 at 21:41
    
Sure. So Fiddler tells me it's sending up this: {"months":{"jan":"10","feb":"10","mar":"10","apr":"10","may"‌​:"10","jun":"10","ju‌​l":"10","aug":"10","‌​sep":"5","oct":"5","‌​nov":"20","dec":"10"‌​},"petrol_annual":"1‌​20","petrol_measure"‌​:"1"} – Mike Rouse Nov 9 '14 at 21:52
up vote 0 down vote accepted

I'm not sure why petrol_annual or petrol_measure aren't model binding correctly, but the List<Month> needs to be Month instead:

public class PetrolViewModel
{
    public double petrol_annual { get; set; }
    public int petrol_measure { get; set; }

    public Month months { get; set; }
}

This is because months in the JSON is an object, not an array. It should match up with the Month class on the server. The Month class should also include entries for all months, but you may have just ommitted those for brevity in your OP.

share|improve this answer
    
For some mysterious reason this fixes it, though I have no idea why. I was assuming that because petrol_annual and petrol_measure were not binding the problem was elsewhere. It didn't occur to me that incorrectly using List<Month> was somehow causing the whole thing to fail. I was getting nothing indicative of this in debugging, but could have been looking in the wrong place. Anyway, I'm very grateful for your answer as I would have been scratching my head over that all night. – Mike Rouse Nov 9 '14 at 22:16

Below works. Perfectly fine. Code:

public class CatergoriesViewModel
{

    public string OrderSelected { get; set; }
    public string CatergoryName { get; set; }
}

var data = { catergoryName: "TestCat", orderSelected: "true" };
    $http.post("Category", data)
 .then(function (response) {
     $scope.test = response.data;
 }, function (error) {
     $scope.test = error;
 });
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.