mannok
mannok

Reputation: 1851

Posting to .NET Core Web API Controller without model binding

Server Side

public void Post(int clientID, string name, string gender)  // Currently, it is bound from querystring by default
{
    Console.WriteLine(clientID);
    Console.WriteLine(name);
    Console.WriteLine(gender);
}

Client Side

  return jQuery.ajax({
    'type': 'POST',
    'url': url,
    'contentType': 'application/json; charset=utf-8',
    'data': '{ "clientID": 123, "name": "foo", "gender": "M" }',
    'dataType': 'json'
  });

.NET Core Web API encourage developer to take a model for model binding. However, for me, I think it is quite annoying in some cases. i.e. I need to create a model for every POST request.

I know I can use a JsonElement with [FromBody] to contain the incoming paramerters, but after trying to manipulate with JsonElement, seems that it is not that convenient to use. (compare to JObject/JArray)

May I know if there a convenient way to get my parameters without model binder? Or can I contain the parameters with Newtonsoft's JObject? Any help would be appreciate. Thanks in advance.

Upvotes: 4

Views: 3396

Answers (2)

Jeremy Thompson
Jeremy Thompson

Reputation: 65534

Why POST?

Do it with a GET and put the parameters on the query string which will map to parameters in the WebMethod:

$.getJSON(url, { clientID: 1, name: "Jeremy", gender: "Male"} ) function(data) {

}

Otherwise if it has to be a POST use a Model, it's not so bad. Pro Tip use a JSON to C# conversion service to make classes for you, ie copy this JSON { clientID: 1, name: "Jeremy", gender: "Male"} into https://json2csharp.com/

Ref: https://www.youtube.com/watch?v=HW7QmYWMnqE

Upvotes: 1

Noldor
Noldor

Reputation: 1182

First of all, apart from your actual question, you should never act lazy for creating new classes for a good code design. Even for a few simple parameters for a method, do always create models. I sometimes even don't care if it takes only one parameter, unless it's like an id parameter for a Get(int id) method or sorts.. Do not act lazy for it, because one of the qualities of a well coded application comes from being more open to future changes with making less code modifications for them. Today it might seem like this method only needs 3 parameters to you, and why bother creating a whole new class just for that, right? But things always change, it never stays the same. I have/had team-mates doing the same thing over years, believe me, those methods always ended up adding new and new parameters over time and looked pretty ugly and unreadable in the end. And if you decide to change these parameters to a model later, it will bring too much work, because you will have to change inside the method too.

Back to your question;

Yes unfortunately the easiest solution is using [FromBody]JObject as parameter. But since you have to use it like a class, and even worse, like a dictionary, why not making your own class instead?

Another solution could be, posting empty data in the body, but passing those arguments in the query string.

Another one is writing your own model binder (IModelBinder) and use it with an attribute on your methods like these guys did with JsonParametersModelBinder It's too much work at the beginning maybe, but it's reusable if you're planning to use parameters mostly.

Upvotes: 0

Related Questions