3
votes

Created a new Azure Function in Visual Studio 2017 (HTTPTrigger based) and having difficulty passing parameters with custom route. Below is the code excerpt:

[FunctionName("RunTest")]
public static async Task<HttpResponseMessage> Run(
    [HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = "orchestrators/contoso_function01/{id:int}/{username:alpha}")] HttpRequestMessage req, TraceWriter log)
{
    log.Info("C# HTTP trigger function processed a request.");

    // parse query parameter
    string name = req.GetQueryNameValuePairs()
        .FirstOrDefault(q => string.Compare(q.Key, "id", true) == 0)
        .Value;

    string instanceId = req.GetQueryNameValuePairs()
        .FirstOrDefault(q => string.Compare(q.Key, "username", true) == 0)
        .Value;

    if (name == null)
    {
        // Get request body
        dynamic data = await req.Content.ReadAsAsync<object>();
        name = data?.name;
    }

    return name == null
        ? req.CreateResponse(HttpStatusCode.BadRequest, "Please pass a name on the query string or in the request body")
        : req.CreateResponse(HttpStatusCode.OK, "Hello " + name);
}

I tried to access the Function with the below URLs, but couldn't retrieve the ID or UserName values from the query string using the GetQueryNameValuePairs() API, as it has only 0 items in the collection:

http://localhost:7071/api/orchestrators/contoso_function01/123/abc
http://localhost:7071/api/orchestrators/contoso_function01/?id=123&username=abc
4

4 Answers

7
votes

Not sure if this is the right way to handle such a need to pass parameters for HTTP Requests with Azure Functions, but if I include parameters for each of the query string with matching parameter names (which apparently is mandatory to get the bindings work), it automatically gets assigned with the value passed in the URL to the respective parameter.

[FunctionName("HttpRunSingle")]
public static async Task<HttpResponseMessage> Run(
    [HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = "orchestrators/contoso_function01/{id:int}/{username:alpha}")]
    HttpRequestMessage req,
    int id,
    string username,
    TraceWriter log)
{
    log.Info("C# HTTP trigger function processed a request.");
            
    return (id == 0 || string.IsNullOrEmpty(username))
        ? req.CreateResponse(HttpStatusCode.BadRequest, "Please pass a name on the query string or in the request body")
        : req.CreateResponse(HttpStatusCode.OK, "Hello " + id + " " + username);
}
2
votes

For anyone who wants to use the URL like this:

http://localhost:7201/api/orchestrators/contoso_function01/<123>/<abc>

Where 123 is the integer id and abc is the string username that we want to be the part of URL.

You can do the following:

[FunctionName("RunTest")]
public static async Task<HttpResponseMessage> Run(
    [HttpTrigger(AuthorizationLevel.Function, "get", "post", 
        Route = "orchestrators/contoso_function01/{id}/{username}")]
    HttpRequestMessage req, int id, string username, TraceWriter log)
{
    log.Info($"Id = {id}, Username = {username}");
    // more code goes here...
}

Here we made two changes:

  1. Adding id and username as part of URL.

    Route = "orchestrators/contoso_function01/{id}/{username}"

  2. Declaring two additional variables for id and username

    HttpRequestMessage req, int id, string username, TraceWriter log

This solution was tested on Azure Functions Version 3.

Further Reading: Serverless C# with Azure Functions: HTTP-Triggered Functions.

1
votes

you can do it like:

var query = System.Web.HttpUtility.ParseQueryString(req.RequestUri.Query);
string userid = query.Get("username");
0
votes

I tried all kinds of stuff. This is the only thing that would work for me.

string RawUrl = url;
int index = RawUrl.IndexOf("?");
if (index > 0)
    RawUrl = RawUrl.Substring(index).Remove(0, 1);

var query = System.Web.HttpUtility.ParseQueryString(RawUrl);
userId = query.Get("id");

It works well with a Url like this.

https://www.bing.com?id=12345678955&test=12345

Make sure and add this before using statements to get System.Web.HttpUtility.ParseQueryString to work.

#r "System.Web"