![](/img/trans.png)
[英]azure function queueTrigger error - Microsoft Azure WebJobs SDK '[Hidden Credential]' connection string is missing or empty
[英]Azure WebJobs SDK 3, trying to add a BlobTrigger and related connection string
旧的处理方式看起来像这样:
var jobConfig = new JobHostConfiguration(cfg.DocumentDatabase.BlobStorageServer)
{
NameResolver = new Support.BlobNameResolver(_env)
};
jobConfig.Queues.MaxPollingInterval = TimeSpan.FromSeconds(_pollSeconds);
_wjHost = new JobHost(jobConfig);
我正在尝试将其转换为3.0中的新方法,这就是我所走的路:
_wjHost = new HostBuilder().ConfigureWebJobs(b =>
{
b.AddAzureStorage(x =>
{
x.MaxPollingInterval = TimeSpan.FromSeconds(_pollSeconds);
});
}).ConfigureServices(s =>
{
s.AddSingleton<INameResolver, Support.BlobNameResolver>(_ => new Support.BlobNameResolver(_env));
s.Configure<QueuesOptions>(o =>
{
o.MaxPollingInterval = TimeSpan.FromSeconds(_pollSeconds);
});
}).Build();
首先,我不知道哪个MaxPollingInterval
是适合使用的那个...所以我同时设置了两者。 我认为我不应该在AddBlobStorage
使用AddBlobStorage
其次,更重要的是,我在哪里指定Blob存储连接字符串? 在上述情况下,它是存储在cfg.DocumentDatabase.BlobStorageServer
的设置
谢谢
WebJob Github上提供了官方样本
在您的函数中,您可以传递在appsettings.json
使用的连接字符串键名。
例如:
public void ProcessBlob([BlobTrigger("blobPath", Connection = "AzureWebJobsBlobConnection")] string blob)
在appsettings.json
按以下方式配置“ AzureWebJobsBlobConnection”: { "Logging": { ... }, "AzureWebJobsBlobConnection": "...", }
并且不要忘记在program.cs
添加配置:
var builder = new HostBuilder()
.ConfigureAppConfiguration((builderContext, cb) =>
{
IHostingEnvironment env = builderContext.HostingEnvironment;
cb.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true);
})
.ConfigureWebJobs(b =>
{
b.AddAzureStorage(o =>
{
o.MaxDequeueCount = 1;
})
.AddServiceBus(c =>
{
c.MessageHandlerOptions.MaxConcurrentCalls = 1;
});
})
.ConfigureLogging((webHostBuilder, loggingBuilder) =>
{
loggingBuilder.AddConsole();
loggingBuilder.AddDebug();
})
.ConfigureServices((hb, sc) =>
{
string connectionString = hb.Configuration.GetConnectionString("DefaultConnection");
sc.AddScoped<Functions, Functions>();
...
});
builder.RunConsoleAsync().GetAwaiter().GetResult();
因此,在盯着webjob SDK的源代码后,我发现了一个难题。 好吧,我认为这是一个矛盾。 它可以工作,现在我可以使用新的3.0 SDK。
我将其发布在这里,主要是因为我担心没有其他方法可以使用自己的配置文件来执行此操作。
如果这是错误的,请让我知道,我将删除此答案。
所以我的代码现在看起来像这样:
_wjHost = new HostBuilder().ConfigureWebJobs(b =>
{
b.AddAzureStorage(x =>
{
x.MaxPollingInterval = TimeSpan.FromSeconds(_pollSeconds);
});
}).ConfigureServices(s =>
{
s.AddSingleton(new StorageAccountProvider(new BlobStorageConfiguration(cfg.DocumentDatabase.BlobStorageServer)));
s.AddSingleton<INameResolver, Support.BlobNameResolver>(_ => new Support.BlobNameResolver(_env));
s.Configure<QueuesOptions>(o =>
{
o.MaxPollingInterval = TimeSpan.FromSeconds(_pollSeconds);
});
}).Build();
我添加的行是s.AddSingleton(new StorageAccountProvider(new BlobStorageConfiguration(cfg.DocumentDatabase.BlobStorageServer)));
webjobs SDK专门在寻找一个名为Storage
的密钥。 因此,我必须实现IConfiguration
并按如下方式进行合并:
private sealed class BlobStorageConfiguration : IConfiguration
{
private readonly string _bsConnString;
public BlobStorageConfiguration(string connString)
{
_bsConnString = connString;
}
public string this[string key]
{
get => key == "Storage" ? _bsConnString : null;
set { }
}
public IEnumerable<IConfigurationSection> GetChildren() => null;
public IChangeToken GetReloadToken() => null;
public IConfigurationSection GetSection(string key) => null;
}
现在触发器触发得很好。 不漂亮。 但是,有关新的IHost方法,有零文档。
在WebSDK 3中,作业是通过appsettings.json
文件配置的,与对ASP.NET Core的配置方法相同。
您可以在Github官方repo上看到一个示例,但我还将在下面添加一个更完整的示例。
在appsettings.development.json
,通过ConnectionStrings["AzureWebJobsStorage"]
属性将其配置为使用本地存储:
{
"ConnectionStrings": {
"AzureWebJobsDashboard": "UseDevelopmentStorage=true",
"AzureWebJobsStorage": "UseDevelopmentStorage=true"
}
}
在appsettings.json
,将其配置为prod:
{
"ConnectionStrings": {
"AzureWebJobsDashboard": "DefaultEndpointsProtocol=https;AccountName=name;AccountKey=key",
"AzureWebJobsStorage": "DefaultEndpointsProtocol=https;AccountName=name;AccountKey=key"
}
}
我完整的Program.cs
如下所示(带有注释):
public class Program
{
public static async Task Main(string[] args)
{
var builder = new HostBuilder();
// allows us to read the configuration file from current directory
// (remember to copy those files to the OutputDirectory in VS)
builder.UseContentRoot(Directory.GetCurrentDirectory());
// configure things like batch size, service bus, etc..
builder.ConfigureWebJobs(b =>
{
b
.AddAzureStorageCoreServices()
.AddAzureStorage(options =>
{
options.BatchSize = 1;
options.MaxDequeueCount = 1;
})
;
});
// this step allows the env variable to be read BEFORE the rest of the configuration
// => this is useful to configure the hosting environment in debug, by setting the
// ENVIRONMENT variable in VS
builder.ConfigureHostConfiguration(config =>
{
config.AddEnvironmentVariables();
});
// reads the configuration from json file
builder.ConfigureAppConfiguration((context, config) =>
{
var env = context.HostingEnvironment;
// Adding command line as a configuration source
config
.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true);
config.AddEnvironmentVariables();
if (args != null)
config.AddCommandLine(args);
});
// configure logging (you can use the config here, via context.Configuration)
builder.ConfigureLogging((context, loggingBuilder) =>
{
loggingBuilder.AddConfiguration(context.Configuration.GetSection("Logging"));
loggingBuilder.AddConsole();
// If this key exists in any config, use it to enable App Insights
var appInsightsKey = context.Configuration["APPINSIGHTS_INSTRUMENTATIONKEY"];
if (!string.IsNullOrEmpty(appInsightsKey))
{
loggingBuilder.AddApplicationInsights(o => o.InstrumentationKey = appInsightsKey);
}
});
// inject dependencies via DI
builder.ConfigureServices((context, services) =>
{
services.AddSingleton<INameResolver>(new QueueNameResolver("test"));
services.AddDbContextPool<DbContext>(options =>
options.UseSqlServer(context.Configuration.GetConnectionString("DbContext"))
);
});
// finalize host config
builder.UseConsoleLifetime();
var host = builder.Build();
using (host)
{
await host.RunAsync();
}
}
}
以防万一有人在使用QueueTrigger时遇到与我解析队列名称时遇到的相同情况:
您必须使用“ Microsoft.Extensions.DependencyInjection”包才能使以下代码正常工作。
static void Main(string[] args)
{
var environment = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT");
Console.WriteLine($"Current Environment : {(string.IsNullOrEmpty(environment) ? "Development" : environment)}");
var config = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
.AddJsonFile($"appsettings.{environment}.json", optional: true, reloadOnChange: true)
.AddEnvironmentVariables()
.Build();
var builder = new HostBuilder();
builder.UseEnvironment("Development");
builder.ConfigureLogging((context, b) =>
{
b.AddConsole();
});
builder.ConfigureWebJobs(b =>
{
b.AddAzureStorageCoreServices();
b.AddAzureStorage();
// b.AddTimers();
b.AddServiceBus(c =>
{
c.ConnectionString = "[Your Connection String]";
});
}).ConfigureServices((context, services)=>
{
services.AddSingleton<INameResolver>(new QueueNameResolver(config));
});
var host = builder.Build();
using (host)
{
host.Run();
}
}
public class QueueNameResolver : INameResolver
{
private readonly IConfiguration _configuration;
public QueueNameResolver(IConfiguration configuration)
{
_configuration = configuration;
}
public string Resolve(string name)
{
return _configuration[$"AppSettings:{name}"];
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.