Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ASP.NET Core: [FromQuery] usage and URL format

I am trying to use [FromQuery] in my web api and I am not sure how to use it.

Here's the GetAllBooks() method in the controller:

 [HttpGet]
 [Route("api/v1/ShelfID/{shelfID}/BookCollection")]
 public async Task<IActionResult> GetAllBooks(string shelfID, [FromQuery] Book bookinfo)
            {
               //do something
            }

Here's the Book model class:

 public class Book
    {
        public string ID{ get; set; }
        public string Name{ get; set; }
        public string Author { get; set; }
        public string PublishDate { get; set; }
    }

I am confused about whether it is the correct way to use [FromQuery]. I thought the URL is

https://localhost:xxxxx/api/v1/ShelfID/{shelfID}/BookCollection/IActionResult?ID="123"&Name="HarryPotter"

But the break point is not hitting my controller method, so I was thinking maybe the URL is not correct. Any suggestions? Thanks!

like image 356
superninja Avatar asked Apr 09 '18 20:04

superninja


People also ask

What is FromQuery in .NET Core?

[FromQuery] - Gets values from the query string. [FromRoute] - Gets values from route data. [FromForm] - Gets values from posted form fields. [FromBody] - Gets values from the request body.

What is difference between controller and ControllerBase?

ControllerBase class Web API controllers should typically derive from ControllerBase rather from Controller. Controller derives from ControllerBase and adds support for views, so it's for handling web pages, not web API requests. If the same controller must support views and web APIs, derive from Controller .


Video Answer


1 Answers

The name of the method and return type are completely ignored when you define your route explicitly via attributes like that. IActionResult shouldn't be there.

The correct URL would be: https://localhost:xxxxx/api/v1/ShelfID/{shelfID}/BookCollection?ID="123"&Name="HarryPotter"

Furthermore, query string binding only works out of the box for primitive types (string, int, etc). To bind a class to a query string you'd need a custom modelbinder, which is quite involved.

It would be better to just explicitly declare the properties you want to pass in:

public async Task<IActionResult> GetAllBooks(string shelfID,
                                             [FromQuery] string ID, 
                                             [FromQuery] string Name)
like image 170
Fred Kleuver Avatar answered Oct 09 '22 04:10

Fred Kleuver