1

I have the following code:

[HttpPost]
[Route("createRepo")]
public HttpResponseMessage createRepo(GitHub githubInfo)
{
    return new HttpResponseMessage(HttpStatusCode.OK)
    {
    Content = new StringContent(githubInfo.RepoName, System.Text.Encoding.UTF8, "application/json")
    };
}

Very simply above, I have a POST route that requires a Github object as input, and just returns its repoName as provided in the object.

Here is the Github model class:

public class GitHub {
    public string RepoName { get; set; }
    public string Organization { get; set; }

    public GitHub(string RepoName, string Organization) {
        this.RepoName = RepoName;
        this.Organization = Organization;
    }
}

Now, doing a POST request with form body returns an error:

enter image description here

It means that githubInfo is null, and so you cannot access its property called RepoName.

However, if I add in the following line to my model GitHub class:

public GitHub() { }

Making the entire model:

public class GitHub {
    public string RepoName { get; set; }
    public string Organization { get; set; }

    public GitHub(string RepoName, string Organization) {
        this.RepoName = RepoName;
        this.Organization = Organization;
    }

    public GitHub() { }
}

Then I have a different story:

enter image description here

It actually recognizes the input, and is able to print out the property name. Why? What is the significance of adding this empty constructor?

K Split X
  • 3,405
  • 7
  • 24
  • 49
  • 1
    [Is it possible to have a non-public parameterless constructor that can be used for model binding?](https://stackoverflow.com/questions/44261895/is-it-possible-to-have-a-non-public-parameterless-constructor-that-can-be-used-f) may also be worth a read. – mjwills Jun 28 '18 at 13:41

2 Answers2

1

The default MVC model binder doesn't know anything about your classes so has no knowledge of the constructor. Therefore it requires a parameterless constructor to be able to instantiate the model and populate the properties.

DavidG
  • 113,891
  • 12
  • 217
  • 223
0

Because by default, to instantiate objects, the framework use the simple parameterless constructors, and populate properties using the setters.

(which makes sense IMHO, it works as intended, and avoid lots of reflection to try to guess which constructor would be appropriate, for no obvious gain)

Note that you might not have noticed it sometimes, if you don't have any constructor explicitly defined, becasue a parameterless public constructor would be created by default.

However, as soo as you specify another constructor, then no default parameterless constructor is created.

Pac0
  • 21,465
  • 8
  • 65
  • 74