Question

I'm using MVC 5, Web API 2 with Entity Framework 6 in vs 2012.

I'm able to successfully call the right action in my web api controller but the incoming json is never deserialized, or at least not properly. The modelBinding recognizes that the json in the request matches the argument Type for the Post action but every property is null or default value.

Why is the json not being deserialized? I can't see any issues here.

This not an active url, just something setup on my local

POST http://www.scabs.com/api/scabs

Body:

{
    "scab" : {
        "url" : "http://money.cnn.com/2013/12/18/news/companies/target-credit-card/index.html?iid=Lead",
        "title" : "Target: 40 million credit cards compromised",
        "description" : "The Secret Service is investigating a reported credit card data breach at discount retailer Target.",
        "image" : {
            "height" : 367,
            "width" : 620,
            "url" : "http://i2.cdn.turner.com/money/dam/assets/131128213407-black-friday-target-pa-620xa.jpg"
        },
        "category" : null
    }
}

Request header:

Accept:*/*
Accept-Encoding:gzip,deflate,sdch
Accept-Language:en-US,en;q=0.8
Cache-Control:no-cache
Connection:keep-alive
Content-Length:422
Content-Type:application/json
Cookie:.ASPXAUTH=DA97AB5D720AC3100F9698DEAED044403CC5BA266EA8F3361E72C183DA2FAD5EB76D0D9DC2AB6DE30507FF788B7D6607473F87B6EE0D28C043DA50508407ABA1FC7ADA9B8A61F2A7C95024869064EE5D9C6863C670FEF221F9447A3D1F2E7CA67849A33B45B0776FFF0D76CD5C290500
Host:www.scabs.com
Origin:chrome-extension://fdmmgilgnpjigdojojpjoooidkmcomcm
User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.63 Safari/537.36

Controller:

public class ScabsController : ApiController {

    private ScabStore _store;

    private ScabStore store {
        get { return _store = _store ?? new ScabStore(); }
    }

    // POST api/scabs
    public void Post(Scab scab) {
        store.scabRepository.save(scab);
        store.commit();
    }
}

Scab Type

public class Scab {
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int id { get; set; }

    [DataType(DataType.Url)]
    public string url { get; set; }
    public string title { get; set; }
    public string description { get; set; }
    public string site { get; set; }
    public virtual Category category { get; set; }
    public virtual Image image { get; set; } // Complex Type
    public virtual User postedBy { get; set; }
    public virtual ICollection<Score> scores { get; set; }
    public virtual ICollection<Comment> comments { get; set; }

    public Scab() {
        scores = new List<Score>();
        comments = new List<Comment>();
    }
}

I should also note that the Image property is a ComplexType

Was it helpful?

Solution

Your JSON data does not match your C# model.

So you need to drop the unnecessary "scab" property and your data should look like this:

{
    "url" : "http://money.cnn.com/2013/12/18/news/companies/target-credit-card/index.html?iid=Lead",
    "title" : "Target: 40 million credit cards compromised",
    "description" : "The Secret Service is investigating a reported credit card data breach at discount retailer Target.",
    "image" : {
        "height" : 367,
        "width" : 620,
        "url" : "http://i2.cdn.turner.com/money/dam/assets/131128213407-black-friday-target-pa-620xa.jpg"
    },
    "category" : null
}

Or if you cannot change the client side modify your C# action code to:

public void Post(SaveScabModel scabModel) {
    store.scabRepository.save(scabModel);
    store.commit();
}

Where SaveScabModel just wraps the Scab model to have the "extra" scab also on the c# side:

public class SaveScabModel {
    public Scab Scab { get; set; }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top