Azure / azure-functions-vs-build-sdk

MSBuild task for Azure Functions
MIT License
96 stars 62 forks source link

'Metadata generation failed' when function parameter has BindingAttribute with array parameter #585

Open HolisticDeveloper opened 1 year ago

HolisticDeveloper commented 1 year ago

I am trying to update some Azure Function projects from .NET Core 3.1 to .NET 6. We have defined a custom BindingAttribute to handle authorization. When updating the Functions SDK from 3.0.13 to 3.1.0 or later, we can no longer build the projects. Instead, we get the following errors in the Error List:

This problem seems to be introduced by #547.

Full stack trace:

System.ArgumentException: Object of type 'Mono.Cecil.CustomAttributeArgument[]' cannot be converted to type 'System.Int32[]'.
   at System.RuntimeType.TryChangeType(Object value, Binder binder, CultureInfo culture, Boolean needsSpecialCast)
   at System.RuntimeType.CheckValue(Object value, Binder binder, CultureInfo culture, BindingFlags invokeAttr)
   at System.Reflection.MethodBase.CheckArguments(Object[] parameters, Binder binder, BindingFlags invokeAttr, CultureInfo culture, Signature sig)
   at System.Reflection.RuntimeMethodInfo.InvokeArgumentsCheck(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
   at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
   at System.Reflection.RuntimePropertyInfo.SetValue(Object obj, Object value, BindingFlags invokeAttr, Binder binder, Object[] index, CultureInfo culture)
   at System.Reflection.RuntimePropertyInfo.SetValue(Object obj, Object value, Object[] index)
   at MakeFunctionJson.TypeUtility.ToReflection(CustomAttribute customAttribute)
   at MakeFunctionJson.TypeUtility.GetResolvedAttribute(ParameterDefinition parameter, CustomAttribute customAttribute)
   at MakeFunctionJson.ParameterInfoExtensions.<>c__DisplayClass1_0.<ToFunctionJsonBindings>b__1(CustomAttribute a)
   at System.Linq.Utilities.<>c__DisplayClass2_0`3.<CombineSelectors>b__0(TSource x)
   at System.Linq.Utilities.<>c__DisplayClass2_0`3.<CombineSelectors>b__0(TSource x)
   at System.Linq.Enumerable.WhereSelectEnumerableIterator`2.ToList()
   at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
   at MakeFunctionJson.ParameterInfoExtensions.ToFunctionJsonBindings(ParameterDefinition parameterInfo)
   at MakeFunctionJson.MethodInfoExtensions.<>c.<ToFunctionJson>b__6_0(ParameterDefinition p)
   at System.Linq.Enumerable.SelectIListIterator`2.MoveNext()
   at System.Linq.Enumerable.SelectManySingleSelectorIterator`2.MoveNext()
   at System.Collections.Generic.LargeArrayBuilder`1.AddRange(IEnumerable`1 items)
   at System.Collections.Generic.SparseArrayBuilder`1.AddRange(IEnumerable`1 items)
   at System.Collections.Generic.SparseArrayBuilder`1.ReserveOrAdd(IEnumerable`1 items)
   at System.Linq.Enumerable.Concat2Iterator`1.ToArray()
   at System.Linq.Enumerable.ToArray[TSource](IEnumerable`1 source)
   at MakeFunctionJson.MethodInfoExtensions.ToFunctionJson(MethodDefinition method, String assemblyPath)
   at MakeFunctionJson.FunctionJsonConverter.GenerateFunctions(IEnumerable`1 types)+MoveNext()
   at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
   at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
   at MakeFunctionJson.FunctionJsonConverter.TryGenerateFunctionJsons()
   at MakeFunctionJson.FunctionJsonConverter.TryRun()
Error generating functions metadata

Repro Steps:

  1. Using VS 2022 17.3.2, create a new Azure Functions project using .NET Core 3.1 as the Functions worker.
  2. Replace the code in Function1.cs with the following block:
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.AspNetCore.Http;
using Microsoft.Azure.WebJobs.Description;
using System;
using System.Threading.Tasks;

namespace FunctionApp1
{
    public static class Function1
    {
        [FunctionName("Function1")]
        public static async Task<IActionResult> Run(
            [HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)] HttpRequest req,
            [SampleAttribute(ArrayParameter = new int[] { 100 })] string input)
        {
            return new OkResult();
        }
    }

    [AttributeUsage(AttributeTargets.Parameter | AttributeTargets.ReturnValue)]
    [Binding]
    public sealed class SampleAttributeAttribute : Attribute
    {
        public int[] ArrayParameter { get; set; }
    }
}