3

I have a simple ASP.Net Web API controller in an otherwise unchanged MVC4 Web API project that has a POST method that takes a Values class. When I do a:

POST /api/values with a body of { name: "somename" }

the Values() constructor gets called instead of the Values(string name) one. Normally, this isn't a problem because the Name property would have a public set and Web API would call it after construction. In this case it is private, so I get a default instance of Values.

If I remove the Values(int) ctor then it does call the Values(string) ctor.

Is there a reason ModelBinding isn't choosing the ctor with the name parameter?

Here's the example code:

using System.Web.Http;

namespace WebAPIPlayground.Controllers
{
    public class ValuesController : ApiController
    {
        public void Post(Values value)
        {
            var a = value.ID; // == 0
            var b = value.Name; // == null
        }
    }

    public class Values
    {
        public int ID { get; private set; }
        public string Name { get; private set; }

        private Values() { }
        public Values(int id) { ID = id; }
        public Values(string name) { Name = name; }
    }
}

I have already looked at: Routing and Action Selection and WebAPI Parameter binding under the hood among many other sites, but I do not understand this behavior.

2
  • 1
    I don't know much about this, but the constructor you claim it should be calling does not have the same method signature as your POST body (you haven't provided an int parameter). Commented May 29, 2013 at 22:09
  • @RobertHarvey Thanks for catching that. It shouldn't have been there. That was one of the last things I tried before posting here. Commented May 29, 2013 at 22:59

1 Answer 1

5

You're talking about deserialization here, not model binding. Try adding this attribute to the constructor you want to have used:

[JsonConstructor]
public Values(string name)

That should do it for the Json.NET case, but it won't work in XML. Maybe that's all you care about.

Sign up to request clarification or add additional context in comments.

4 Comments

Good point. I'll try this out (or something like it), and post back details.
Don't forget using Newtonsoft.Json;
This did work. We are only doing json right now. Now that I know it's a deserialization problem I'm sure I could get this to work for xml as well if needed. Thanks!
I am not posting JSON, so this is not working. Is there a different way to do it, or do I need to change how I am posting things?

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.