1

I'm trying to get a param for my WebAPI from a query param using [FromQuery] using ASP.NET Core 2.1. For the the life of me I cannot figure out what I'm doing wrong.

The particular action looks like this:

[Route("api/[controller]/[action]")]
public class AuthController : Controller
{
    [HttpGet]
    [Authorize(Roles = "admin")]
    public async Task<IActionResult> GenerateCode([FromQuery]string email)
    {
        if (String.IsNullOrEmpty(email))
            return new BadRequestObjectResult(new ApiBadRequestResponse(new string[] { "Email is empty." }));

        var result = await _mediator.Send(new CreateAccessCode.Command
        {
            Email = email
        });

        if (result.Succeeded)
            return new OkObjectResult(new ApiOkResponse(result.Data));

        return new BadRequestObjectResult(new ApiBadRequestResponse(result.Errors));
    }
}

email is always null and I've put a breakpoint in the function so I know its getting called.

The request I'm sending is this:

{{url}}/api/auth/generatecode?email=test

If I create a new project from scratch, [FromQuery] seems to work, I have no idea what I'm doing differently. The action is getting called, but is always return BadResponse due to the first line...

My startup.cs function looks like this:

services.AddMvc()
            .SetCompatibilityVersion(CompatibilityVersion.Version_2_1)
            .AddMvcOptions(options =>
            {
                options.Filters.Add(new ActionValidationFilter());
            })
            .AddFluentValidation()
            .AddJsonOptions(options =>
            {
                options.SerializerSettings.ContractResolver =
                new CamelCasePropertyNamesContractResolver();
            })
            .AddSessionStateTempDataProvider();

I'm completely lost. This is the first action I have in my WebAPI that is looking for a query param. All other actions are using FromBody and work fine.

8
  • What do you use to submit the data to Web API ? React, Angular, Jquery ? Please mention clearly so I can help you Commented Jul 16, 2018 at 4:08
  • Remove [HttpPost] attribute from your method. Commented Jul 16, 2018 at 6:32
  • You dont need to use FormQuery and please remove [HttpPost] Commented Jul 16, 2018 at 8:13
  • For now, just using postman to send the request. Removing the HttpPost or switching HttpGet doesn’t change the behavior. Commented Jul 16, 2018 at 9:03
  • Have you tried it without using [FromQuery]? Commented Jul 16, 2018 at 9:24

2 Answers 2

4

Option 1)
Try changing your [HttpGet] attribute to

[HttpGet("GenerateCode/{email}]

You will need to remove /[action] from your controller's Route attribute if doing this, so it'd just be

[Route("api/[controller]")]

Option 2)
Alternatively, in Startup.cs change app.UseMvc(); to

app.UseMvc(routes =>
{
    routes.MapRoute(
        name: "default",
        template: "api/{controller=Home}/{action=Index}/{id?}");
});

And remove [Route("api/[controller]/[action]")] from the controller attributes and make sure you don't have the [ApiController] attribute either

This solution will change your entire project's routing, so you'll have to do the same for all your other API controllers

Option 3)
A third solution would be to change [Route("api/[controller]/[action]")] to

[Route("api/[controller]/[action]/{id?}")]

I have tested all 3 solutions and they all with with the URL {{url}}/api/ControllerName/ActionName?email=test

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

3 Comments

I tried each of these solutions and unfortunately, they don't work for me with the URL provided. Option 2 doesn't seem to be an option because my project is purely a WebAPI without a "HomeController". Option 3 also wouldn't seem to work in my case only because there are other actions within the controller (which I left out for brevity) and that would apply to all of them. Option 1 just doesn't seem to work. Its still unclear to me why [FromQuery] doesn't work, especially when I create a new project and it works just fine in that one.
@bryken Option 2 is just a template, you don't need an actual Home controller for it to work. Reminder: if you use option 1 you'll still need to edit the route attribute to remove /[action] off the end. Why can't you use option 3? The final {id?} is optional (i.e. {{url}}/api/ControllerName/ActionName would still work fine with option 3)
I did end up getting this to work. However, I still didn't understand why [FromQuery] wasn't working. I ended up reverting all the changes I made and restarting again, in this case I was able to get the [FromQuery] to work. I wish I knew what happened the first time to provide more insight in case anyone else runs into a similar problem. Thanks for the help.
2

A little late answer but may be helpful for others

Option 4

You can explicitly name the querystring parameter name within the [FromQuery] attribute

[HttpGet]
[Authorize(Roles = "admin")]
public async Task<IActionResult> GenerateCode([FromQuery(Name="email")] string email)
{

}

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.