diff --git a/common.props b/common.props
index 7500396..2e4d5c0 100644
--- a/common.props
+++ b/common.props
@@ -4,7 +4,7 @@
4
4
- 0
+ 1
diff --git a/src/Microsoft.NET.Sdk.Functions.Generator/AttributeExtensions.cs b/src/Microsoft.NET.Sdk.Functions.Generator/AttributeExtensions.cs
index c937da1..64425df 100644
--- a/src/Microsoft.NET.Sdk.Functions.Generator/AttributeExtensions.cs
+++ b/src/Microsoft.NET.Sdk.Functions.Generator/AttributeExtensions.cs
@@ -43,13 +43,20 @@ private static string ToAttributeFriendlyName(string name)
};
///
- ///
+ /// Checks if a custom attribute is a WebJobs attribute.
///
- ///
- ///
+ /// The custom attribute to check.
+ /// True if the attribute is a WebJobs attribute; otherwise, False.
public static bool IsWebJobsAttribute(this CustomAttribute attribute)
{
- return attribute.AttributeType.Resolve().CustomAttributes.Any(a => a.AttributeType.FullName == "Microsoft.Azure.WebJobs.Description.BindingAttribute")
+ var attributeTypeDefinition = attribute.AttributeType?.Resolve();
+
+ if (attributeTypeDefinition == null)
+ {
+ return false;
+ }
+
+ return attributeTypeDefinition.CustomAttributes.Any(a => a.AttributeType.FullName == "Microsoft.Azure.WebJobs.Description.BindingAttribute")
|| _supportedAttributes.Contains(attribute.AttributeType.FullName);
}
diff --git a/test/Microsoft.NET.Sdk.Functions.EndToEnd.Tests/FunctionsV4SdkTests.cs b/test/Microsoft.NET.Sdk.Functions.EndToEnd.Tests/FunctionsV4SdkTests.cs
index a4e9a2f..43e3d73 100644
--- a/test/Microsoft.NET.Sdk.Functions.EndToEnd.Tests/FunctionsV4SdkTests.cs
+++ b/test/Microsoft.NET.Sdk.Functions.EndToEnd.Tests/FunctionsV4SdkTests.cs
@@ -11,11 +11,11 @@ public class FunctionsV4SdkTests
private string _testsDirectory;
private TestInitialize _testInitializer;
private ITestOutputHelper _testOutputHelper;
- private const string _testVersion = "v4";
+ private const string TestVersion = "v4";
public FunctionsV4SdkTests(ITestOutputHelper testOutputHelper)
{
- _testInitializer = new TestInitialize(testOutputHelper, _testVersion);
+ _testInitializer = new TestInitialize(testOutputHelper, TestVersion);
_testOutputHelper = testOutputHelper;
_functionsSdkPackageSource = _testInitializer.FunctionsSdkPackageSource;
_testsDirectory = _testInitializer.TestDirectory;
@@ -68,7 +68,7 @@ public void BuildAndPublish_CopiesRuntimesToAdditionalBinFolder()
Assert.True(Directory.Exists(additionalBinDir));
var files = Directory.EnumerateFiles(additionalBinDir, "*.dll", SearchOption.AllDirectories);
Assert.True(files.Count() > 1);
- // Test addional runtimes
+ // Test additional runtimes
files = Directory.EnumerateFiles(Path.Combine(additionalBinDir, "runtimes"), "*.dll", SearchOption.AllDirectories);
Assert.True(files.Count() > 1);
@@ -99,7 +99,7 @@ public void BuildAndPublish_GeneratesFunctions()
string dotnetArgs = $"build {projectFileToTest}.csproj --configuration {TestInitialize.Configuration}";
int? exitCode = new ProcessWrapper().RunProcess(TestInitialize.DotNetExecutable, dotnetArgs, projectFileDirectory, out int? _, createDirectoryIfNotExists: false, testOutputHelper: _testOutputHelper);
Assert.True(exitCode.HasValue && exitCode.Value == 0);
- // Test addional bin
+ // Test additional bin
string binDir = Path.Combine(projectFileDirectory, "bin", TestInitialize.Configuration, TestInitialize.NetCoreFramework);
string additionalBinDir = Path.Combine(binDir, "bin");
Assert.True(Directory.Exists(additionalBinDir));
@@ -108,6 +108,8 @@ public void BuildAndPublish_GeneratesFunctions()
// Test functions generator output
string httpTriggerFunctionpath = Path.Combine(binDir, "HttpFunction", "function.json");
Assert.True(File.Exists(httpTriggerFunctionpath));
+ string httpTrigger2Functionpath = Path.Combine(binDir, "HttpFunction2", "function.json");
+ Assert.True(File.Exists(httpTrigger2Functionpath));
// Publish
dotnetArgs = $"publish {projectFileToTest}.csproj --configuration {TestInitialize.Configuration}";
@@ -122,6 +124,8 @@ public void BuildAndPublish_GeneratesFunctions()
// Test functions generator output
httpTriggerFunctionpath = Path.Combine(publishDir, "HttpFunction", "function.json");
Assert.True(File.Exists(httpTriggerFunctionpath));
+ httpTrigger2Functionpath = Path.Combine(publishDir, "HttpFunction2", "function.json");
+ Assert.True(File.Exists(httpTrigger2Functionpath));
}
private void UpdatePackageReference(string projectFileToTest, string projectFileDirectory)
diff --git a/test/Microsoft.NET.Sdk.Functions.EndToEnd.Tests/Resources/v4/FunctionAppWithHttpTrigger/HttpFunction.cs b/test/Microsoft.NET.Sdk.Functions.EndToEnd.Tests/Resources/v4/FunctionAppWithHttpTrigger/HttpFunction.cs
index ae2ea34..6eb56d6 100644
--- a/test/Microsoft.NET.Sdk.Functions.EndToEnd.Tests/Resources/v4/FunctionAppWithHttpTrigger/HttpFunction.cs
+++ b/test/Microsoft.NET.Sdk.Functions.EndToEnd.Tests/Resources/v4/FunctionAppWithHttpTrigger/HttpFunction.cs
@@ -31,5 +31,13 @@ public static async Task Run(
return new OkObjectResult(responseMessage);
}
+
+ // A function which uses nullable type for parameter.
+ [FunctionName("HttpFunction2")]
+ public static async Task Run2(
+ [HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = "hello/{id}")] HttpRequest req, ILogger log, string? id)
+ {
+ return new OkObjectResult($"Hello {id}");
+ }
}
}