Introduction
The HttpRequestData
type is an abstract class with some basic items relating to Http based requests such as access to the Body, headers, cookies, url and identities but out of the box there is no option to access the query string parameters directly. The actual type of the instance passed in at run time is a GrpcHttpRequestData
and trust me when I say you don’t want to go down that rabbit hole to implement that yourself. When it gets generated it gets passed a RpcHttp
instance which has access to a Query MapField
but isn’t exposed on the consumer itself.
So how do we access the QueryString parameters? And how do we do it nicely? Let’s explore!
Option 1
As part of the request we have access to the full url. This will include everything we need including the query string parameters we want access to. This is where we are going to start.
As developers who have worked with ASP.NET/ASP.NET Core over the years there have been various ways of parsing the querystring including System.Web.HttpUtility.ParseQueryString
which is not what we want.
But the newer ASP.NET Core world does give us a way of parsing it nicely.
To do this we need to install the WebUtilities nuget package - Microsoft.AspNetCore.WebUtilities - https://www.nuget.org/packages/Microsoft.AspNetCore.WebUtilities/.
Once that is installed we can use the QueryHelpers
class to parse the query part of the Url to return a dictionary we can look into.
Dictionary<string, StringValues> parsedQueryString = QueryHelpers.ParseNullableQuery(req.Url.Query);
And it being used in an Azure Function looks.
[Function("Function1")]
public static HttpResponseData Run([HttpTrigger(AuthorizationLevel.Anonymous, "get")] HttpRequestData req,
FunctionContext executionContext)
{
Dictionary<string, StringValues> parsedQueryString = QueryHelpers.ParseNullableQuery(req.Url.Query);
return req.CreateResponse(HttpStatusCode.OK);
}
This is relatively straight forward but still doesn’t quite feel right. But in ASP.NET Core the model binding gives us controller action bindings I hear you cry and this is true and so does Azure Functions.
Option 2
As with ASP.NET Core controller actions where you can specify action parameters and the model binding will look in the query string to see if it can identify the values so does Azure Functions.
Note: the bindings for Azure Functions are not as feature rich as ASP.NET Core yet so if you are looking for the data in the body of the request you currently have to parse that yourself etc.
Like ASP.NET Core controllers Query String binding does work so you don’t have to do anything manually like option 1 above. If you require a name
and age
parameters then you specify them as parameter values and they will be bound. As far as I am aware only basic types are supported at this time and I think this is due to the limited binding functionality.
[Function("Function1")]
public static HttpResponseData Run([HttpTrigger(AuthorizationLevel.Anonymous, "get")] HttpRequestData req,
string name,
int age,
FunctionContext executionContext)
{
return req.CreateResponse(HttpStatusCode.OK);
}
Conclusion
As we’re seeing Azure Functions functionality expand I have no doubt the model binding will improve and I expect to see binding attributes like [FromBody]
in the future to allow the framework to do the heavy lifting and allow developers to concentrate on the functionality. This isn’t there yet but I believe it will come.
Working with a combination of query string parameter binding and routing value binding is really powerful and I look forward to seeing this area of Azure Functions expand in the future.
What are you thoughts on Azure Functions isolated mode? What items have you been tripped up on and want to improve? Let me know on Twitter @WestDiscGolf.