0

How can use ASP.NET Core WebAPI process json request without model binding?

I have more than one hundred APIs that need to be transferred to ASP.NET Core WebAPI, but I cannot design a model for each API because the number is too much.

In addition, I also need to use Swagger, so I cannot use string parsing like IActionResult Post(string json) or IActionResult Post(JObject obj).

Controller Code(with bug):

[ApiController]
[Route("[controller]")]
public class TestController : ControllerBase
{
    public class Person { public int Age { get; set; } }
    [HttpPost]
    public IActionResult Post([FromBody] string name, Person person)
    {
        return Ok(new
        {
            Name = name,
            person.Age
        });
    }
}

Postman:

POST /Test HTTP/1.1
Host: localhost:5000
Content-Type: application/json
Content-Length: 68

{
    "Name": "Test",
    "Person": {
        "Age": 10
    }
}

enter image description here

Current API Interface:

bool InsertPoint(PointInfo point);
bool[] InsertPoints(PointInfo[] points);
bool RemovePoint(string pointName);
bool[] RemovePoints(string[] pointNames);
string[] Search(SearchCondition condition, int count);
...

What i want to do in controller:

[HttpPost]
[SomeJsonBodyAttribute]
public IActionResult InsertPoint(PointInfo point);
[HttpPost]
[SomeJsonBodyAttribute]
public IActionResult InsertPoints(PointInfo[] points);
[HttpPost]
[SomeJsonBodyAttribute]
public IActionResult RemovePoint(string pointName);
[HttpPost]
[SomeJsonBodyAttribute]
public IActionResult RemovePoints(string[] pointNames);
[HttpPost]
[SomeJsonBodyAttribute]
public IActionResult Search(SearchCondition condition, int count);
...

What i want to do in request:

  • RemovePoint
POST /Point/RemovePoint HTTP/1.1
Content-Type: application/json

{
    "pointName": "Test"
}
  • Search
POST /Point/Search HTTP/1.1
Content-Type: application/json

{
    "condition": {
        ...
    },
    "count": 10
}
yejinmo
  • 43
  • 1
  • 6
  • Hi @yejinmo, why not using JObject? – Rena Jul 12 '21 at 09:10
  • This link might help you: https://stackoverflow.com/questions/40853188/frombody-string-parameter-is-giving-null – Arib Yousuf Jul 12 '21 at 10:17
  • You can look into dynamic as parameter. However I would be question the rationale of moving hundred apis without wanting to have dedicated models. How do you process the data in each controller without risk of misalignment, especially if there is a hundred apis? – Aeseir Jul 12 '21 at 10:52
  • You have a bug in your code. What do you want to fix this bug or something else? If you want to use Swagger there is no way to use any dynamic models. You have to decide what is more important. – Serge Jul 12 '21 at 12:51
  • @Rena If I use JObject, I cannot use Swagger to generate documentation. – yejinmo Jul 13 '21 at 03:15
  • Hi @yejinmo, oh really? It actually works fine in my asp.net core version 3.1 project. What is your version of asp.net core? – Rena Jul 13 '21 at 03:17
  • Hi @yejinmo, please check the Output panel in your visual studio if the error caused by JObject. Also share the error message will be helpful. – Rena Jul 13 '21 at 03:20
  • @Rena I am using .Net 5, Swagger is effective, but Swagger cannot automatically recognize the parameter summary if I use JObjcet – yejinmo Jul 13 '21 at 03:36
  • @Aeseir Because there are too many models and time is too tight, and I don’t understand why there can’t be a [FromJson] just like [FromForm] so that there is no need to define a model. – yejinmo Jul 13 '21 at 03:41

1 Answers1

2

Be sure add Newtonsoft support in your project.You could refer to the following answer:

https://stackoverflow.com/a/65101721/11398810

Then you could get data like below:

[HttpPost]
public IActionResult Post([FromBody] JObject obj)
{
    //for list model:
    //obj["Person"][0]["Age"].ToString()
    return Ok(new { Name = obj["Name"].ToString(), Age = obj["Person"]["Age"].ToString() });
}

With json:

{
    "Name": "Test",
    "Person": {
        "Age": 10
    }
}

Result: enter image description here

Rena
  • 30,832
  • 6
  • 37
  • 72
  • This is a compromise solution, but it cannot: 1. Method binding based on parameter list 2. Automatically generate parameter descriptions in Swagger – yejinmo Jul 13 '21 at 07:59
  • It is impossible to automatically meet your new requirement because you do not want to create models for them. JObject is the fastest way to solve your original issue. – Rena Jul 13 '21 at 08:06