Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What types can you pass as a parameter to an admin-only C# Azure Function app?

What types are allowed as parameters for Azure Function apps written in C# that are only callable through the admin endpoint?

I've read lots of documentation and source code and I still don't know the answer. I'm looking for definitive references and clear explanations as to what that means and why, plus examples of how to implement functions with other parameter types.

I'm wondering if the Azure team expect you to accept a string of JSON and parse it yourself into proper types, but the documentation I've found doesn't say.

Additional context

The specific function I am working on is to be called only via the admin interface so does not have any Http etc bindings.

[NoAutomaticTrigger]
[FunctionName(nameof(SomeFunctionName))]
public async Task SomeFunctionName(ParameterTypeHere someParameterName)
{
...

What can I put instead of ParameterTypeHere?

The specific use I have (this time) is that I want to pass something like List<Guid> or Guid[], I don't mind if I have to wrap it in a class or something but nothing I tried worked so I've ended up splitting a string on comma and parsing out the guids which seems like a poor solution.

Currently I've got a string parameter and am calling it with:

$ curl -v http://localhost:7071/admin/functions/SomeFunctionName \
  -d '{"input": "699F3073-9BFD-4DA7-9E61-4E6564D032EC,197DA362-C281-4E0F-BB92-8759F7A5B4B4"}' \
  -H "Content-Type:application/json"

Research so far

Things I've already looked at that leave me still unsure what I can use beyond string for more complex inputs:

  • Azure Functions: Generic type as input parameter
    • https://github.com/Azure/Azure-Functions/issues/735
  • Azure Functions error - Cannot bind parameter to type String
  • Cannot bind parameter, cause the parameter type is not supported by the binding (HttpTrigger of Azure Functions)
  • Can not bind ILogger in azure function v1
  • https://learn.microsoft.com/en-us/azure/azure-functions/functions-manually-run-non-http
  • https://github.com/Azure/azure-functions-host/blob/dev/src/WebJobs.Script/Binding/Manual/ManualTriggerAttributeBindingProvider.cs#L39
    • https://github.com/Azure/azure-functions-host/blob/9b2fa0f3ea69c41ce819f046213eab4f40a5db5f/src/WebJobs.Script/Binding/StreamValueBinder.cs#L24-L30
    • https://github.com/Azure/azure-functions-host/blob/9b2fa0f3ea69c41ce819f046213eab4f40a5db5f/src/WebJobs.Script/Utility.cs#L245
  • ServiceBusTrigger with enqueueTimeUtc argument fails when triggered via HTTP endpoint

The parameter name is ignored, and you have to pass it in with the name "input" regardless of the actual parameter name. Just another thing to trip over.

Even more context

If you're wondering why you'd ever want an admin-only function, this was for a one-off job to be run by someone else who has access to the admin endpoints. It appeared to be the simplest thing that could work. An HttpTrigger would have been fine, it just appeared to violate YAGNI.

like image 856
Tim Abell Avatar asked Sep 16 '25 12:09

Tim Abell


1 Answers

Some weeks ago, I tested how to convert an API using functions with special attention to DI (not shown in below example) and validation. This may not be a direct answer to your question, but it shows that plain model classes may be used.

public class MyRequestModel
{
    [Display(Name = "Message")]
    [Required, MinLength(3)]
    public string Message { get; set; }
}

public static class MyHttpExample
{
    [FunctionName(nameof(MyHttpExample))]
    public static IActionResult Run(
        [HttpTrigger(AuthorizationLevel.Function, "get", Route = "test/{message}")] MyRequestModel req, ILogger log)
    {
        log.LogInformation("C# HTTP trigger function processed a request.");

        var validationResults = new List<ValidationResult>();
        if (!Validator.TryValidateObject(req, new ValidationContext(req, null, null), validationResults, true))
        {
            return new BadRequestObjectResult(validationResults);
        }

        var responseMessage = $"Hello, {req.Message}. This HTTP triggered function executed successfully.";
        return new OkObjectResult(responseMessage);
    }
}

More information on Azure Functions binding expression patterns https://learn.microsoft.com/en-us/azure/azure-functions/functions-bindings-expressions-patterns

When reading the above doc, keep in mind that function.json is generated from annotations when using C#, but doc shows what's available. Generated function.json for the above example:

{
  "generatedBy": "Microsoft.NET.Sdk.Functions-3.0.11",
  "configurationSource": "attributes",
  "bindings": [
    {
      "type": "httpTrigger",
      "route": "test",
      "methods": [
        "get"
      ],
      "authLevel": "function",
      "name": "req"
    }
  ],
  "disabled": false,
  "scriptFile": "../bin/MyFunctions.dll",
  "entryPoint": "MyFunctions.MyHttpExample.Run"
}

See also https://stackoverflow.com/a/54489040/14072498

like image 130
Roar S. Avatar answered Sep 19 '25 03:09

Roar S.