Gary O. Stenstrom
Gary O. Stenstrom

Reputation: 2294

ViewModel passed into WebApi method is null

Not sure why I am having problems with this. I have done it before but looking at previous projects has yielded no help. I am sure that I am missing a configuration or something.

I have an ApiController in a WebForms 4.5 project that I am using to retrieve and update data from a datastore (SQL Server CE 4.0).

I have defined the following POST method to handle the adding of property records to a product ...

    [HttpPost]
    public void AddPropertyToProduct([FromBody]ProductPropertyViewModel prodProp)
    {
        Mapper.CreateMap<ProductPropertyViewModel, ProductProperty>();
        ProductProperty property = Mapper.Map<ProductProperty>(prodProp);

        ProductRepository.Instance.AddProperty(property.ProductId, property);
        ProductRepository.Instance.SaveChanges();
    }

The ProductPropertyViewModel argument is a ViewModel that I use instead of the Data Model...

public class ProductPropertyViewModel
{
    public Int64 Id { get; set; }

    public Int64 ProductId { get; set; }

    public String PropertyName { get; set; }

    public String PropertyValue { get; set; }

    public String Comments { get; set; }

    public DateTime DateAdded { get; set; }

    public DateTime DateUpdated { get; set; }

}

The client-side script that calls the service sends in a JSON string that matches the ViewModel property for property...

var addPropertyToProduct = function (propertyViewModel, productId, isAsync, fnSuccess, fnError) {

    var methodUrl = "/api/ProductPropertyAPI/AddPropertyToProduct/"
    var ret = null;
    //
    // Make sure that the ProductId is specified as part of the ViewModel
    propertyViewModel.ProductId = productId;
    //
    // make sure that the propertyViewModel is reduced to JSON for being passed to the server.
    // Example : {"Id": 0, "ProductId":5,"PropertyName":"Engine Size","PropertyValue":"300cc","Comments":"Some comment","DateAdded":"07/25/2013","DateUpdated":"07/25/2013"}
    var jsonData = ko.toJSON(propertyViewModel);
    $.ajax({
        type: "POST",
        data: jsonData,
        async: isAsync,
        contentType: 'application/json;charset=utf-8',
        url: methodUrl,
        success: function (data) {
            //#region console log
            var logMsg = "AJAX.ProductPropertyAPI.AddPropertyToProduct ( "+ JSON.stringify(jsonData) +" ): RESPONSE : " + JSON.stringify(data);
            console.log(logMsg);
            //#endregion
            if (typeof fnSuccess === 'function') {
                fnSuccess(data);
            }
            else {
                defaultSuccess(data);
            }
        },
        error: function (data) {

            if (typeof fnError === 'function') {
                fnError(data);
            }
            else {
                defaultError(data);
            }
        }
    });
}

The problem that I am having is that when the request is POSTED to the AddPropertyToProduct method of the service, the prodProp argument is NULL instead of an instance of the ViewModel. It was my understanding that the WebAPI would know to map the JSON data to the ProductPropertyViewModel object.

I am sure that I have overlooked something here but cannot figure out what it is. Can anyone see what I am missing?

Thanks, G

UPDATE: Added Fiddler data

This is the Request that I am sending via Fiddler.

POST http://localhost:55556/api/ProductPropertyAPI/AddPropertyToProduct HTTP/1.1
User-Agent: Fiddler
Host: localhost:55556
ContentType: 'application/json;charset=utf-8'
Content-Length: 155

{"Id": 0, "ProductId":5,"PropertyName":"Engine Size","PropertyValue":"300cc","Comments":"Some comment","DateAdded":"07/25/2013","DateUpdated":"07/25/2013"}

UPDATED : Added $.Ajax Request Header from IE Developer Tools

Key Value
Request POST http://localhost:55556/api/ProductPropertyAPI/AddPropertyToProduct/ HTTP/1.1
Accept  */*
Content-Type    application/json;charset=utf-8
X-Requested-With    XMLHttpRequest
Referer http://localhost:55556/Admin/ProductManager.aspx
Accept-Language en-US
Accept-Encoding gzip, deflate
User-Agent  Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; WOW64; Trident/6.0)
Host    localhost:55556
Content-Length  129
DNT 1
Proxy-Connection    Keep-Alive
Pragma  no-cache
Cookie  __atuvc=38%7C8; __AntiXsrfToken=63a0ede574be4aa9a19e153474320450; ASPSESSIONIDACBTCRRS=FDDPEJIBPDFEODAHOEMBOOFK; ASPSESSIONIDCABTDTRT=AANBPPFCEFOBMAEFMMPMMFLF; ASPSESSIONIDAAARDSRS=LODHOFGCLJILEEEHICHGLNLA; ASPSESSIONIDCCDTCSQT=NHOJPJGCOECNJBIDGGKIALFG; ASP.NET_SessionId=xh4xctv0mvq2zb454hkb1f3z

Upvotes: 1

Views: 1754

Answers (1)

mnsr
mnsr

Reputation: 12437

I just copy pasted your code in to new project, and it failed.

"Message":"An error has occurred.",
"ExceptionMessage":"Object reference not set to an instance of an object.",
"ExceptionType":"System.NullReferenceException"

I'm assuming you're getting this same error. But after i removed:

contentType: 'application/json;charset=utf-8',

It worked.

My full ajax request:

// I used static jsonData because you're getting the correct values in 
// your fiddler so this is definitely not causing any issues
var jsonData = { "Id": 0, "ProductId": 5, "PropertyName": "Engine Size", "PropertyValue": "300cc", "Comments": "Some comment", "DateAdded": "07/25/2013", "DateUpdated": "07/25/2013" };
var methodUrl = "/api/test/AddPropertyToProduct/";
$.ajax({
    type: "POST",
    data: jsonData,
    //async: isAsync,
    //contentType: 'application/json;charset=utf-8',
    url: methodUrl,
    success: function (data) {
        console.log('Success: ', data);
    },
    error: function (data) {
        console.log('Error: ', data);
    }
});

The action method I used:

[HttpPost]
public string AddPropertyToProduct(ProductPropertyViewModel prodProp)
{
    return prodProp.PropertyName;
}

Upvotes: 0

Related Questions