2

I have this query object:

public class GetRecipeQuery: IRequest<RecipeResponse>
{
    [BindRequired]
    [FromRoute]
    public int Id {get; set;}
}

And controller:

[ApiController]
[Route("[controller]")]
public class RecipeController
{
    private AppDbContext _context;
    private readonly IMediator _mediator;   

    public RecipeController(AppDbContext context, IMediator mediator)
    {
        _context = context;
        _mediator = mediator;
    }
    
    [HttpGet("{Id}")]
    // http://localhost:5555/Recipe/555
    public RecipeResponse Get([FromRoute]GetRecipeQuery query)
    {
        if (query.Id == 0)
        {
            throw new ArgumentException("No Id!", nameof(query.Id));
        }
        var result = _mediator.Send(query).Result;
        return result;
    } 
}

So I see this as a result:

Status: 400
"The value '{Id}' is not valid for Id."

Need help: How to bind Id from route to GetRecipeQuery.Id ? Otherwise i need to construct query objects manually in every controller method.

JHBonarius
  • 10,824
  • 3
  • 22
  • 41
navff
  • 43
  • 1
  • 7

2 Answers2

2

It seems like you confuse a bit route parameters and query parameters. If you want to use URL parameters your endpoint in controller should be a value type:

[FromRoute]int id

Then URL you are calling would approximately look like this:

http://localhost:8080/foo/10

If you want to use query parameters this is how your controller endpoint argument would look like:

[FromQuery]Foo query

With Foo looking like this:

public class Foo
{
    public int Id {get; set;}
}

And the address you need to call:

http://localhost:8080/foo?id=10
OlegI
  • 5,472
  • 4
  • 23
  • 31
  • 1
    Thanks. Yes, we can use [FromQuery] and that is simple. But I wanted to bind from route. And, it turns out, there is a solution – navff Mar 15 '21 at 02:18
1

@tontonsevilla, answered my question. Thanks.

[HttpGet("{Id:int}")] returns 404 error, but [HttpGet("{id:int}")] works fine! Need lowercase and type for Id parameter.

Full solution.

1). Add query class

public class GetRecipeQuery : IRequest<RecipeResponse>
{
    [FromRoute]
    public int Id { get; set; }
}

2). Use this query class in Controller and add [HttpGet("{id:int}")]:

 [HttpGet("{id:int}")]
 public RecipeResponse Get(GetRecipeQuery query)
 {
    // your code
 }

I need it because I started using Mediatr

navff
  • 43
  • 1
  • 7