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.

EiEiGuy
  • 1,447
  • 5
  • 18
  • 32
  • 1
    The name of the string variable it is expecting must be the same as the one you are sending: a_query -> mailclasscode – Terrance00 Jul 07 '17 at 19:09
  • Terrance - OK, so then if I want to have the user use http://localhost:5000/api/servicetypecodes?mailclasscode=fc or http://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? – EiEiGuy Jul 08 '17 at 02:02
  • 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. – EiEiGuy Jul 08 '17 at 02:22

2 Answers2

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.

Terrance00
  • 1,658
  • 1
  • 20
  • 29
  • This still doesn't work for some reason if the controller has the `[ApiController]` attribute – Steven Liekens Jul 30 '18 at 16:23
  • I believe you can specify `([FromQuery("varname")])`. If that doesn't work something else many be wrong. – Terrance00 Jul 30 '18 at 20:02
  • That actually worked! Holy cow, how did you find that? PS I'm using ASP.NET Core 2.1 – Steven Liekens Jul 31 '18 at 07:56
  • 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. – Terrance00 Jul 31 '18 at 08:41
  • 1
    Turns out there's a bug in 2.1 that breaks FromQuery in ApiController and the workaround is to override `Name`. https://github.com/aspnet/Mvc/issues/7712 – Steven Liekens Jul 31 '18 at 08:45
  • 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. – Terrance00 Jul 31 '18 at 09:08
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)
{
   ...
}
ono2012
  • 4,967
  • 2
  • 33
  • 42