4

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.

1
  • use query string only. Commented Jun 29, 2020 at 3:11

2 Answers 2

1

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

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

2 Comments

QueryString has length limitation, it may be too long in some case. e.g. base64 img
Fair enough, then back to POST which has a body that is intended to be a serialized object in .net core. The benefit of serialization is that it does support backward compatibility to a degree. Whereas if you have a route path or varying number of parameters anytime you add a new one it will go out of sync, and you can't accommodate new ones without breaking the old version. The single model binding argument with automatic JSON deserialization eases the burden and is designed specifically for this. Plus it's nicer.
0

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.

2 Comments

I've tried JObject. However, it prompt me error. .NET Core Web API don't know how to convert JsonElement to JObject
then use JsonElement instead?

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.