1

I'm trying to pass a JSON array to an ApiController but the string values aren't deserializing (they are set to null values). The strange thing is that I still get the correct number of elements.

A have an ApiController:

[RoutePrefix("api/language")]
public class LanguagePairApiController : ApiController

With a post method:

// POST: api/language/create
[HttpPost]
[Route("create")]
public string Create([FromBody]LanguagePair[] languagePairs)

I'm sending JSON to it:

[
    {"Key":"Test","Value":"Test","Version":"1.0"},
    {"Key":"Areyousure","Value":"Are you sure?","Version":"1.0"},
    {"Key":"File","Value":"File","Version":"1.0"}
]

And this is the class I'm trying to map it to:

public class LanguagePair
{
    public string Key { get; set; }
    public string Value { get; set; }
    public string Version { get; set; }
}

But the string values are coming through as null:

enter image description here

What am I missing?
EDIT: I've figured out one answer to this and posted it below. But I'm still looking for a better answer...

2
  • I do not know much about asp.net, but isn't there some mechanism turned on that automatically camel cases object properties? Try to send [{"key":"win"}] to it. Commented Jun 21, 2016 at 22:44
  • what is your actual jQuery you're using Commented Jun 21, 2016 at 22:47

2 Answers 2

2

I figured it out. I needed to decorate the class with DataContract and DataMember attributes:

{
    [DataContract]
    public class LanguagePair
    {
        [DataMember]
        public string Key { get; set; }
        [DataMember]
        public string Value { get; set; }
        [DataMember]
        public string Version { get; set; }
    }
}
Sign up to request clarification or add additional context in comments.

1 Comment

If you'd like to adjust names for JSON properties (e.g. send {"myKey":"Areyousure","question event with space":"Are you sure?","v":"1.0"} ) you can use correspondingly: [DataMember(Name = "myKey")], [DataMember(Name = "question event with space")], [DataMember(Name = "v")] for the LanguagePair properties in C#
1

Read Parameter Binding in ASP.NET Web API

You need to remove [FromBody] attribute from your action...

// POST: api/language/create
[HttpPost]
[Route("create")]
public string Create(LanguagePair[] languagePairs) { ... }

and you can keep your class lean as you originally had it:

public class LanguagePair
{
    public string Key { get; set; }
    public string Value { get; set; }
    public string Version { get; set; }
}

Using [FromBody]

To force Web API to read a simple type from the request body, add the [FromBody] attribute to the parameter:

public HttpResponseMessage Post([FromBody] string name) { ... }

In this example, Web API will use a media-type formatter to read the value of name from the request body. Here is an example client request.

POST http://localhost:5076/api/values HTTP/1.1
User-Agent: Fiddler
Host: localhost:5076
Content-Type: application/json
Content-Length: 7

"Alice"

When a parameter has [FromBody], Web API uses the Content-Type header to select a formatter. In this example, the content type is "application/json" and the request body is a raw JSON string (not a JSON object).

1 Comment

I just tried this and I get the same result (an array of 3 objects with all the values == null). But the [FromBody] is doing nothing - if I remove that and keep the [DataContract] it works correctly.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.