2

Good Day All

I am using ASP.NET Core 3.1. I need to bind controller parameters to body (they are too large to fit in the URL). I do not wish to create a DTO just for a single method (I also have multiple endpoints, which will end up requiring a lot of throwaway DTOs). This isn't possible out of the box, and all current online help seems to be focused to the old .NET Framework Web Api.

In simple terms, given the following controller:

public class GreetController : ControllerBase
{
    public string Index(string firstname, string lastname) 
        => $"Hello {firstname} {lastname}";
}

The following curl command:

curl -X GET --header "Content-Type: application/json" --data \
    "{\"firstname\":\"John\",\"lastname\":\"Doe\"}" https://[Url]/Greet/

should return Hello John Doe, but instead the parameters are null. Adding [FromBody] also does not work. I need this to work for Json and Xml request bodies. I am aware that this can be done with URI parameters. However, I have some parameters which are too large for a URI therefore they must be in the request body.

NB 2: Please do not include a long-winded explanation about why this doesn't comply with REST.

2
  • I think there are two points here. First one is about using Body of a GET method. You can't do that. Second is about using of DTO, you will need a complex object to parse the body content, because the FromBodyAttribute cannot be wrote in more than one method parameter. Commented Nov 4, 2020 at 1:37
  • you can check more about this here: learn.microsoft.com/en-us/aspnet/core/mvc/models/… Commented Nov 4, 2020 at 1:38

3 Answers 3

5

Here are two things you need to know:

1.FromBody could not work with Get request.

2.Don't apply [FromBody] to more than one parameter per action method. Once the request stream is read by an input formatter, it's no longer available to be read again for binding other [FromBody] parameters.

For you do not want to pass the data by query and do not want to create dtos,I suggest that you could using Newtonsoft.Json.Linq.JObject:

public class GreetController : ControllerBase
{
    [HttpPost]
    public string Index([FromBody]JObject model)
    { 
        var firstname = model["firstname"].ToString();
        var lastname = model["lastname"].ToString();
        return $"Hello {firstname} {lastname}"; 
    }
}

Startup.cs:

services.AddControllers()
    .AddNewtonsoftJson();

For how to use Newtonsoft.Json in an ASP.NET Core 3.1 project:

https://learn.microsoft.com/en-us/aspnet/core/migration/22-to-30?view=aspnetcore-3.1&tabs=visual-studio#use-newtonsoftjson-in-an-aspnet-core-30-mvc-project

Result: enter image description here

Another way is to custom model binder,you could follow the answer below:

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

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

1 Comment

I will look into the custom model binder, it seems to do what I am looking for. Thanks!
0

Use nuget package Mvc.ModelBinding.MultiParameter

You can skip all the attributes when having unique names.

Comments

-1

That scenario seems ideal for a QueryString request. Example:

GET: [Url]/Greet/?firstName=Rod&lastName=Ramirez

where:

public class GreetController : ControllerBase
{
    public string Index([FromQuery] string firstname, string lastname) 
        => $"Hello {firstname} {lastname}";
}

Not tested, but this should work 😁

Comments

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.