I'm trying to work with Azure Webjobs, I understand the way its works but I don't understand why I need to use two connection strings, one is for the queue for holding the messages but
why there is another one called "AzureWebJobsDashboard" ?
What its purpose?
And where I get this connection string from ?
At the moment I have one Web App and one Webjob at the same solution, I'm experiment only locally ( without publishing anything ), the one thing I got up in the cloud is the Storage account that holds the queue.
I even try to put the same connection string in both places ( AzureWebJobsDashboard,AzureWebJobsStorage) but its throw exception :
"Cannot bind parameter 'log' when using this trigger."
Thank you.
There are two connection strings because the WebJobs SDK writes some logs in the storage account. It gives you the possibility of having one storage account just for data (AzureWebJobsStorage) and the another one for logs (AzureWebJobsDashboard). They can be the same. Also, you need two of them because you can have multiple job hosts using different data accounts but sending logs to the same dashboard.
The error you are getting is not related to the connection strings but to one of the functions in your code. One of them has a log parameter that is not of the right type. Can you share the code?
Okay, anyone coming here looking for an actual answer of "where do I get the ConnectionString from"... here you go.
On the new Azure portal, you should have a Storage Account resource; mine starts with "portalvhds" followed by a bunch of alphanumerics. Click that so see a resource Dashboard on the right, followed immediately by a Settings window. Look for the Keys submenu under General -- click that. The whole connection string is there (actually there are two, Primary and Secondary; I don't currently understand the difference, but let's go with Primary, shall we?).
Copy and paste that in your App.config file on the connectionString attribute of the AzureWebJobsDashboard and AzureWebJobsStorage items. This presumes for your environment you only have one Storage Account, and so you want that same storage to be used for data and logs.
I tried this, and at least the WebJob ran without throwing an error.
#RayHAz - Expanding upon your above answer (thanks)...
I tried this https://learn.microsoft.com/en-us/azure/app-service/webjobs-sdk-get-started
but in .Net Core 2.1, was getting exceptions about how it couldn't find the connection string.
Long story short, I ended up with the following, which worked for me:
appsettings.json, in a .Net Core 2.1 Console app:
{
"ConnectionStrings": {
"AzureWebJobsStorage": "---your Azure storage connection string here---",
"AzureWebJobsDashboard":"---the same connectionstring---"
}
}
... and my Program.cs file...
using System;
using System.IO;
using Microsoft.Azure.WebJobs;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
namespace YourWebJobConsoleAppProjectNamespaceHere
{
public class Program
{
public static IConfiguration Configuration;
static void Main(string[] args)
{
var builder = new ConfigurationBuilder()
.SetBasePath(Path.Combine(AppContext.BaseDirectory))
.AddJsonFile("appsettings.json", true);
Configuration = builder.Build();
var azureWebJobsStorageConnectionString = Configuration.GetConnectionString("AzureWebJobsStorage");
var azureWebJobsDashboardConnectionString = Configuration.GetConnectionString("AzureWebJobsDashboard");
var config = new JobHostConfiguration
{
DashboardConnectionString = azureWebJobsDashboardConnectionString,
StorageConnectionString = azureWebJobsStorageConnectionString
};
var loggerFactory = new LoggerFactory();
config.LoggerFactory = loggerFactory.AddConsole();
var host = new JobHost(config);
host.RunAndBlock();
}
}
}
Related
I've been working with functions with Azure, I've built a very simple Http Function locally by following the example linked here, the only difference is I've defined a User table instead of a Todo table
Everything works as expected locally, I'm able to post and get.
However, when deploying the function and trying to make a POST request I see the following within the logs:
Executed 'User' (Failed, Id=5df9dffe-eedf-4b11-aa10-54fda00992b0, Duration=1ms)System.ArgumentNullException : Value cannot be null. (Parameter 'connectionString')
I've checked the SQL Server to ensure it's accessible by other Azure Services just encase that was causing a problem, but I can confirm it's set to allow.
I have found this question, I've gone through the steps and checked against mine and I can confirm my Function App configuration does have the AzureWebJobsStorage connection string.
I'm not 100% sure why this would be happening due to my lack of knowledge of functions at the moment, have anyone else experience this? if so how did you resolve it?
Update
After further testing, it seems the error is coming from my Startup class,
class Startup : FunctionsStartup
{
public override void Configure(IFunctionsHostBuilder builder)
{
string connectionString = Environment.GetEnvironmentVariable("SqlConnectionString");
builder.Services.AddDbContext<ApplicationDbContext>(
options => SqlServerDbContextOptionsExtensions.UseSqlServer(options, connectionString));
}
}
Upon deployment, connectionString variable is null.... not sure why though.
Yes, you can not get it because you didn't set it in the configuration settings.
If you want to use the Connection Strings section.
Add the "ConnectionStrings":{} section to your local.settings.json file then add your connection string
{
...
"ConnectionStrings": {
"MyConnectionString": ""
}
}
Then you need to set the connection string in the Settings section of the Function App in the Azure Portal.
The scroll down to the Connection Section
And add a new connection string. Make sure it has the same name as you connection in the local.settings.json file.
Your question isn't 100% clear if this is happening locally (as you refer to local.settings.json) or when deploying. If this occurs when deploying, changing your local.settings.json file will not help, unfortunately.
You will need to add the Application Setting within the Azure Portal (located under Settings -> Configuration -> Application Settings -> New application setting).
You will need to save the application setting, and then restart the Azure Function instance for the changes to reflect.
Check out https://learn.microsoft.com/en-us/azure/azure-functions/functions-how-to-use-azure-function-app-settings?tabs=portal
I am a newbie to Azure functions. I am having problem with the below code where CosmosDB binding is not working. If I remove CosmosDB, it works find; I am able to get messages thru eventGridEvent. But as soon as I add CosmosDB, this piece of code fails. I had tried different Collectors (IAsyncCollectory, IReadOnlyCollection, IReadOnlyList, IEnumerable, etc.) some of them compiles fine but when deployed to Azure portal it does nothing (msg: function not found).
I need to retrieve data from CosmosDb and save it to a Queue by using the message coming thru eventGridEvent. I can hardcoded but that is not allowed for my project. Any help will be appreciated team!
[FunctionName("TopicGridTrigger")]
public static void Run([EventGridTrigger()] EventGridEvent eventGridEvent,
[Queue("myqueuetest")] out string queueMessage,
[CosmosDB("MyCarStore", "cars", ConnectionStringSetting = "CosmosDBConnectionString")] IAsyncCollector<MyCar> Items,
ILogger log
)
{
//SOME CODE HERE
}
I have been learning the bot framework from microsoft and have been following a tutorial on pluralsight. I have made the changes to my Global.asax.cs and for some reason I keep on getting the error setting must be in the form name=value. I have no idea what to do and how to get rid of these errors. Any help would be highly appreciated.
Global.asax.cs
public class WebApiApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
// This code chunk below will allow us to use table bot data store instead of
// in memory data store
Conversation.UpdateContainer(
builder =>
{
builder.RegisterModule(new AzureModule(Assembly.GetExecutingAssembly()));
// here we grab the storage container string from our web config and connecting
var store = new TableBotDataStore(ConfigurationManager.ConnectionStrings["StorageConnectionString"].ConnectionString);
builder.Register(c => store).
Keyed<IBotDataStore<BotData>>(AzureModule.Key_DataStore).
AsSelf().
SingleInstance();
});
GlobalConfiguration.Configure(WebApiConfig.Register);
TableBotDataStore is for Azure Table Storage, and it seems you are using some sql connectionstring. You would usually have that connection string in the AppSettings section, not the ConnectionStrings section (yes, the names are a bit misguiding here).
In Visual Studio 2017 with the latest update, for azure functions template, I want something where I can initialize like program.cs in webjobs template.
I am trying to create a new subscription with new namespace Manager when application initializes so that I can listen to one service bus topic.
Is there a way to do that? If yes then how?
If you intend to create a subscription that this Function will be triggered on, there is no need to do that manually. Function App will create the subscription based on your binding at deployment time.
For other scenarios (e.g. timer-triggered function), you can do the initialization in a static constructor:
public static class MyFunction1
{
static MyFunction1()
{
var namespaceManager = NamespaceManager.CreateFromConnectionString(connString);
if (!namespaceManager.SubscriptionExists("topic1", "subscription1"))
{
namespaceManager.CreateSubscription("topic1", "subscription1");
}
}
[FunctionName("MyFunction1")]
public static void Run(
// ...
}
Static constructor will run at the time of the first function call.
for azure functions template, I want something where I can initialize like program.cs in webjobs template.
As far as I know, Azure functions do not have good support for this right now. You can find a similar question:
Question:
I have a C# function and want to know if there is any Initialization point. I have dependency injection containers that need initialization
and want to know where to do that.
Mathew's reply
We don't have a good story for this right now. Please see open issue
here in our repo where this is discussed.
We are hosting 3party sites in our webrole and to limit them access to the storage container I need to set the connection string from code instead of the connection string in serviceconfiguration?
Is this possible?
Based on answer i ran into a problem.
DiagnosticMonitorConfiguration dmConfig = DiagnosticMonitor.GetDefaultInitialConfiguration();
DiagnosticMonitor.StartWithConnectionString(conn, dmConfig);
This resets the configuration to defaults and overrides the stuff that was deployed with the cloud service. I assume when using the StartWithConnectionString, you cant use the support they added in visual studio for setting these things.
Yes, I think you can. Do take a look at DiagnosticMonitor.StartWithConnectionString method. You would do something like this in your WebRole's OnStart() method:
DiagnosticMonitorConfiguration dmConfig = DiagnosticMonitor.GetDefaultInitialConfiguration();
DiagnosticMonitor.StartWithConnectionString("DefaultEndpointsProtocol=https;AccountName=accountname;AccountKey=accountkey", dmConfig);
return base.OnStart();
However I would not recommend hard coding the connection string in the code itself. Instead take it from some database.