c# - Azure Function 中的自定义绑定(bind)未得到解决

标签 c# azure azure-functions

我正在尝试为 Azure Functions 创建自己的自定义绑定(bind)。 这项工作基于 2 篇有关此功能的 wiki 文章: https://github.com/Azure/azure-webjobs-sdk/wiki/Creating-custom-input-and-output-bindingshttps://github.com/Azure/WebJobsExtensionSamples

对于示例项目,我指的是 Azure Functions/WebJobs binding extension sample project 。 该项目基于.NET Framework 4.6。

我希望自己的自定义绑定(bind)能够与 Azure Functions v2 配合使用,因此我在所有项目中都以 NetStandard2 为目标。

在示例项目中,我看到启动本地模拟器时正在加载绑定(bind)扩展。

[3-1-2019 08:48:02] Loaded binding extension 'SampleExtensions' from 'referenced by: Method='FunctionApp.WriterFunction.Run', Parameter='sampleOutput'.'

但是,在运行我自己的绑定(bind)扩展时,我从未看到此行出现。

我所做的如下。 首先,我创建了一个新属性。

[AttributeUsage(AttributeTargets.Parameter | AttributeTargets.ReturnValue)]
[Binding]
public class MySimpleBindingAttribute : Attribute
{
    /// <summary>
    /// Path to the folder where a file should be written.
    /// </summary>
    [AutoResolve]
    public string Location { get; set; }
}

还有一个相当简单的扩展类

public class MySimpleBindingExtension : IExtensionConfigProvider
{
    public void Initialize(ExtensionConfigContext context)
    {
        var rule = context.AddBindingRule<MySimpleBindingAttribute>();
        rule.BindToInput<MySimpleModel>(BuildItemFromAttribute);
    }

    private MySimpleModel BuildItemFromAttribute(MySimpleBindingAttribute arg)
    {
        string content = default(string);
        if (File.Exists(arg.Location))
        {
            content = File.ReadAllText(arg.Location);
        }

        return new MySimpleModel
        {
            FullFilePath = arg.Location,
            Content = content
        };
    }
}

当然还有模型。

public class MySimpleModel
{
    public string FullFilePath { get; set; }
    public string Content { get; set; }
}

根据我在 wiki 上阅读的内容,我认为这应该足以在我的 Azure Functions 项目中使用它。 该函数如下所示。

[FunctionName("CustomBindingFunction")]
public static IActionResult Run(
    [HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = "{name}")]
    HttpRequest req,
    string name,
    [MySimpleBinding(Location = "%filepath%\\{name}")]
    MySimpleModel simpleModel)
{
    return (ActionResult) new OkObjectResult(simpleModel.Content);
}

在模拟器中运行此程序时,我看到以下错误和警告消息。

[3-1-2019 08:51:37] Error indexing method 'CustomBindingFunction.Run'

[3-1-2019 08:51:37] Microsoft.Azure.WebJobs.Host: Error indexing method 'CustomBindingFunction.Run'. Microsoft.Azure.WebJobs.Host: Cannot bind parameter 'simpleModel' to type MySimpleModel. Make sure the parameter Type is supported by the binding. If you're using binding extensions (e.g. Azure Storage, ServiceBus, Timers, etc.) make sure you've called the registration method for the extension(s) in your startup code (e.g. builder.AddAzureStorage(), builder.AddServiceBus(), builder.AddTimers(), etc.).

[3-1-2019 08:51:37] Function 'CustomBindingFunction.Run' failed indexing and will be disabled.

[3-1-2019 08:51:37] No job functions found. Try making your job classes and methods public. If you're using binding extensions (e.g. Azure Storage, ServiceBus, Timers, etc.) make sure you've called the registration method for the extension(s) in your startup code (e.g. builder.AddAzureStorage(), builder.AddServiceBus(), builder.AddTimers(), etc.).

现在,此消息在 WebJob 场景中有意义,但对于 Azure Function,您无法在启动代码中进行设置。 调用该函数会抛出以下消息。

[3-1-2019 08:53:13] An unhandled host error has occurred.

[3-1-2019 08:53:13] Microsoft.Azure.WebJobs.Host: 'CustomBindingFunction' can't be invoked from Azure WebJobs SDK. Is it missing Azure WebJobs SDK attributes?.

我读过一些关于添加 extensions.json file and use the AzureWebJobs_ExtensionsPath (for v1) 的内容,但那些似乎没有做任何事情(或者我做错了什么)。

关于如何进行的任何想法?

为了完整起见,以下是我当前对 NuGet 包的引用。

<PackageReference Include="Microsoft.Azure.WebJobs" Version="3.0.3" />
<PackageReference Include="Microsoft.NET.Sdk.Functions" Version="1.0.24" />
<PackageReference Include="Newtonsoft.Json" Version="11.0.2" />

最佳答案

在其他示例的帮助和指导下,我能够弄清楚目前需要添加哪些内容才能使自定义绑定(bind)正常工作。

我的猜测是,在即将发布的运行时版本中,这会随着时间的推移而改变,但谁知道......

首先,添加一个小扩展方法,在该方法中将扩展添加到 IWebJobsBuilder

public static class MySimpleBindingExtension
{
    public static IWebJobsBuilder AddMySimpleBinding(this IWebJobsBuilder builder)
    {
        if (builder == null)
        {
            throw new ArgumentNullException(nameof(builder));
        }

        builder.AddExtension<MySimpleBinding>();
        return builder;
    }
}

接下来是 IWebJobsStartup 实现。这将在启动时由运行时通过反射获取。

public class MySimpleBindingStartup : IWebJobsStartup
{
    public void Configure(IWebJobsBuilder builder)
    {
        builder.AddMySimpleBinding();
    }
}

您不能忘记的一件事是将以下内容添加到此类中:

[assembly: WebJobsStartup(typeof(MySimpleBindingStartup))]

您很快就会注意到这一点,因为如果您忘记了,绑定(bind)将不会被拾取。

希望这对遇到我遇到的同样问题的每个人都有帮助。 如果您想查看完整的代码,我在 GitHub 存储库中提供了一个示例项目:https://github.com/Jandev/CustomBindings

关于c# - Azure Function 中的自定义绑定(bind)未得到解决,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54019076/

相关文章:

c# - 如何找到字符串格式错误的 XML(在 C# 中)的位置?

azure - 如何跟踪 Azure 中的应用程序登录?

azure - 有没有办法以编程方式更改 Azure 函数触发器类型。

azure - 使用运行时 4、.NET 6 在进程外运行 Azure 函数时遇到问题

linux - 无法在 Azure 上的 Ubuntu 16.04 上连接 Percona Docker 镜像

azure-devops - 重新部署Azure Functions ARM模板会删除我发布的函数

azure - 将App Service与NAT网关集成以获取静态出站IP

c# - 自引用导航属性和 json 序列化

c# - 无法将 'int' 隐式转换为 'bool'

c# - 在 WCF Rest 中捕获 WebFaultException 的详细信息