Why isn't FromQuery working in my ASP.Net Core 1.1 controller action
Asked Answered
D

2

5

I am working on an ASP.Net Core 1.1 web API. I have a ServiceTypeCode controller as shown below;

[Produces("application/json")]
[Route("api/[controller]")]
public class ServiceTypeCodeController : Controller
{ 
    ...
    ...
    ...


    [HttpGet]
    public IActionResult Get([FromQuery] string a_query)
    {
        try
        {
            if (string.IsNullOrEmpty(a_query))
            {
                OperationResult<List<ServiceTypeCode>, string> result = m_bl.GetAllServiceTypeCodes();
                if (result.Success && result.Result.Count > 0)
                {
                    return Ok(JsonConvert.SerializeObject(result.Result));
                }
            } else
            {
                // Deserialize query into dictionary of strings and StringValues 
                var query = QueryHelpers.ParseQuery(a_query.ToLower());

                if (query.TryGetValue("mailclasscode", out var mailClassCode))
                {
                    if (!string.IsNullOrEmpty(mailClassCode))
                    {
                        OperationResult<List<ServiceTypeCode>, string> result = m_bl.GetAllServiceTypeCodes(mailClassCode);
                        if (result.Success && result.Result.Count > 0)
                        {
                            return Ok(JsonConvert.SerializeObject(result.Result));
                        }
                    }
                }
                if (query.TryGetValue("stc", out var stc))
                {
                    if (!string.IsNullOrEmpty(stc))
                    {
                        OperationResult<ServiceTypeCode, string> result = m_bl.GetServiceTypeCode(stc);
                        if (result.Success)
                        {
                            return Ok(JsonConvert.SerializeObject(result.Result));
                        }
                    }
                }
            }
            return NotFound();
        }
        catch (Exception ex)
        {
            string msg = "An exception occurred while trying to get a list of ServiceTypeCodes from the database.";
            m_logger.LogError(1, ex, msg);
            ApiError error = BuildError("Server Error - Exception", "500", "Get", ex, msg);
            return Ok(JsonConvert.SerializeObject(error));
        }

    }

If I use the url ...

http://localhost:5000/api/servicetypecodes

in PostMan with the GET verb, I get the list of service type codes, as expected. However, If I try to add anything as a query string, such as ...

http://localhost:5000/api/servicetypecodes?mailclasscode=fc

and set a breakpoint in my code at the

if (string.IsNullOrEmpty(a_query))

location, the value of a_query is null instead of the expected "mailclasscode=fc"

What am I missing here?

Thanks in advance for any help.

Donetta answered 7/7, 2017 at 16:51 Comment(3)
The name of the string variable it is expecting must be the same as the one you are sending: a_query -> mailclasscodeWestland
Terrance - OK, so then if I want to have the user use localhost:5000/api/servicetypecodes?mailclasscode=fc or localhost:5000/api/servicetypecodes?stc=123, depending on if they are filtering by mailclasscode or stc, then I would need to have public IActionResult Get([FromQuery] string mailclasscode, [FromQuery string stc) is that correct?Donetta
That worked. Thanks Terrance. If you want to post an answer, I would be happy to mark it as correct so that you get credit.Donetta
W
11

The .Net Core Controller Method's variable names must be the same as what you are sending.

http://localhost:5000/api/servicetypecodes?mailclasscode=fc

If using that url to pass data the controller method will have to look like this:

[HttpGet]
public IActionResult Get([FromQuery] string mailclasscode)
{...}

Or vice versa.

Good luck - happy coding.

Westland answered 9/7, 2017 at 7:32 Comment(6)
This still doesn't work for some reason if the controller has the [ApiController] attributeDorison
I believe you can specify ([FromQuery("varname")]). If that doesn't work something else many be wrong.Westland
That actually worked! Holy cow, how did you find that? PS I'm using ASP.NET Core 2.1Dorison
Documentation from Microsoft on .net-core is pretty good. Also [FromQuery] as is should also work. May be worth looking into for you. Good luck friend.Westland
Turns out there's a bug in 2.1 that breaks FromQuery in ApiController and the workaround is to override Name. github.com/aspnet/Mvc/issues/7712Dorison
Well there you have, atleast .net-core's delivery is pretty quick. I remember there was a bug on identity core that got fixed in like a week, good find nonetheless. Upvoted comment.Westland
U
1

You can have the query string name differ from the variable name in the method. You have to let .NetCore know how by defining it in code like so (using your variable names):

[HttpGet]
public IActionResult Get([FromQuery(Name = "mailclasscode")] string a_query)
{
   ...
}

or more generically:

[HttpGet]
public IActionResult Get([FromQuery(Name = "myQueryStringParamName")] string myCodeParamName)
{
   ...
}
Upthrow answered 6/2, 2018 at 22:27 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.