Windows Azure Table Storage Webrole.cs vs. global.asax.cs - azure

I have read that the easiest way for setting up a connection and creating a table is putting the following line of codes in the webrole.cs onStart() method.
but for some reason I have got errors and when I put the same code in global.asax.cs Application_start() method. it works fine?
what is the difference
here is the code I am talking about : I am using tablestorage bytheway
...
CloudStorageAccount.SetConfigurationSettingPublisher((configName, configSettingPublisher) =>
{
var connectionString = RoleEnvironment.GetConfigurationSettingValue(configName);
configSettingPublisher(connectionString);
}
);
var account =
CloudStorageAccount.FromConfigurationSetting(
Constants.KEY_STORAGE);
//create table
var client = account.CreateCloudTableClient();
client.CreateTableIfNotExist(Constants.EMAILMERGE_TABLE);
/////////////////////////////////
and the Error I am getting is-----------------------------
SetConfigurationSettingPublisher needs to be called before FromConfigurationSetting can be used
Tnx for the tips!!
cheeers

For a worker role, we only need to put the code in OnStart. But for a web role, we need to put the code in two places. If you want to access storage in OnStart, please put the code in OnStart. If you want to access storage in your web application, please put the code in Global.asax’s Application_Start. If you need both, please put the code in both places.
Best Regards,
Ming Xu.

Related

setting must be in the form "name=value" in vs 2017

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).

Use SQL Server view in NEW Azure App Service

I am new to Azure App Service.
I've created a view in Azure database to get data across several tables. Now I want to use the data from this view in my Cordova App using the Azure Mobile Service (MobileService.GetTable...). I found several articles in the web that describe how to do that in Classic Azure Portal. But I need a solution for the NEW Azure App Service with Node.js Backend.
What is the syntax to return data from a view as an Azure table?
var table = module.exports = require('azure-mobile-apps').table();
table.read(function (context) {
// *** Need code to return data from sql view ***
//return context.execute();
});
And it would be great to use a parameter to filter data in the view before returning.
Thanks,
Uwe
You are pretty much right there. You need to just create a table controller to access the view. Ensure you have the system columns defined (version, updatedAt, createdAt, deleted and id). Also, ensure the right thing happens when you update the view (e.g. with an INSERT, UPDATE, DELETE) as that will tell you what needs to be done with the controller (for example, if you can't insert/update/delete, then make it read-only).
Reference blog post for you: https://shellmonger.com/2016/04/15/30-days-of-zumo-v2-azure-mobile-apps-day-8-table-controller-basics/
Things can be so easy sometimes ;-)
All I need to do is to write the following lines to my table controller:
var table = require('azure-mobile-apps').table();
table.databaseTableName = 'ViewName';
module.exports = table;
Thanks for your help!
Had a similar issue but fixed it now, am using a .Net backend thou.
1. Log into azure portal and select the database you want to create the view in Then select the query Editor in the left pane.
2. Use the sql to create the query.
3.Create a table in the asp.net backend that matches your fields in your view.
4.Go to your asp.net backend and create a custom Api and write the following codes:
public class HelloCustomController : ApiController
{
MobileServiceContext context;
public HelloCustomController()
{
context = new MobileServiceContext();
}
[HttpGet]
public async Task<List<vwUser>> Get()
{
try
{
var users = context.Database.SqlQuery<vwUser>("Select * from
dbo.vwUser);
return await users.ToListAsync();
}
catch(Exception ex)
{
return new List<vwUser>()
{
new vwUser
{
UserName=ex.Message
}
};
}
}
4.You edit my codes to select from your view.
5. Create a similar class in your mobile app that matches what u created in your backend.
5. You can then access your view by calling it in your mobile app with the following codes:
var users= await client.InvokeApiAsync<vwUser>("HelloCustom",HttpMethod.Get,null);
Thanks Guys. This is my fisrt answer to this beautiful community that carried me from day 1 of programming till now that am a bit conversant.

Azure WebJobs Connection Strings configuration ( AzureWebJobsDashboard?? )

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();
}
}
}

Azure Diagnostics - runtime def vs. wadcfg

I'm trying to understand the various ways to configure the Diagnostics in Windows Azure.
So far I've set a diagnostics.wadcfg that is properly used by Azure as I retrieve its content in the xml blob stored by Diagnostics in the wad-control-container (and the tables are updated at the correct refresh rate).
Now I would like to override some fields from the cscfg, in order to boost the log transfer period for all instances, for example (without having to update each wad-control-container file, which will be erased in case of instance recycle btw).
So in my WebRole.Run(), I get a parameter from RoleEnvironment.GetConfigurationSettingValue() and try to apply it to the current config ; but my problem is that the values I read from DiagnosticMonitor.GetDefaultInitialConfiguration() do not correspond to the content of my diagnostics.wadcfg, and setting new values in there doesn't seem to have any effect.
Can anyone explain the relationship between what's taken from diagnostics.wadcfg and the values you can set at run-time?
Thanks
GetDefaultInitialConfiguration() will not return you your current settings, becasue as its name states it takes a default configuration. You have to use the GetCurrentConfiguration method if you need to take the configuration that is in place.
However, if you need to just boost the transfer, you could use for example the Cerebrata's Azure Diagnostics Manager to quickly kick off on-demand transfer of your roles.
You could also use the Windows Azure Diagnostics Management cmdlets for powershell. Check out this article.
Hope this helps!
In order to utilize values in wadcfg file the following code code could be used to access current DiagnosticsMonitorConfiguration:
var cloudStorageAccount = CloudStorageAccount.Parse(
RoleEnvironment.GetConfigurationSettingValue(WADStorageConnectionString));
var roleInstanceDiagnosticManager = cloudStorageAccount.CreateRoleInstanceDiagnosticManager(
RoleEnvironment.DeploymentId,
RoleEnvironment.CurrentRoleInstance.Role.Name,
RoleEnvironment.CurrentRoleInstance.Id);
var dmc = roleInstanceDiagnosticManager.GetCurrentConfiguration();
// Set different logging settings
dmc.Logs....
dmc.PerformanceCounters....
// don't forget to update
roleInstanceDiagnosticManager.SetCurrentConfiguration(dmc);
The code by Boris Lipshitz doesn't work now (Breaking Changes in Windows Azure Diagnostics (SDK 2.0)): "the DeploymentDiagnosticManager constructor now accepts a connection string to the storage account instead of a CloudStorageAccount object".
Updated code for SDK 2.0+:
var roleInstanceDiagnosticManager = new RoleInstanceDiagnosticManager(
// Add StorageConnectionString to your role settings for this to work
CloudConfigurationManager.GetSetting("StorageConnectionString"),
RoleEnvironment.DeploymentId,
RoleEnvironment.CurrentRoleInstance.Role.Name,
RoleEnvironment.CurrentRoleInstance.Id);
var dmc = roleInstanceDiagnosticManager.GetCurrentConfiguration();
// Set different logging settings
dmc.Logs....
dmc.PerformanceCounters....
// don't forget to update
roleInstanceDiagnosticManager.SetCurrentConfiguration(dmc)

Windows Azure - Web Role cannot access Local Development Queue Storage

I have a class library that is shared between multiple Role projects in my solution. Two of these projects are a Web Role and a Worker Role.
They each have the same Configuration Setting:
<Setting name="QueueConnectionString" value="UseDevelopmentStorage=true" />
each of them is making a call to this function:
public static void AddMessage(string Message)
{
var account = CloudStorageAccount.DevelopmentStorageAccount;
ServicePoint queueServicePoint = ServicePointManager.FindServicePoint(account.QueueEndpoint);
queueServicePoint.UseNagleAlgorithm = false;
var client = account.CreateCloudQueueClient();
var queue = client.GetQueueReference(DefaultRoleInstanceQueueName);
queue.CreateIfNotExist();
queue.AddMessage(new CloudQueueMessage(Message));
}
When this executes in the Worker Role, it works without any issues; I've confirmed proper reads and writes of Queue messages. When it executes in the Web Roles, the call to queue.CreateifNotExist() crashes with the error "Response is not available in this context". I've tried searching for information on what could be causing this but so far my search efforts have been fruitless. Please let me know if there's any additional information I can include.
ok, so after a lot more work, I determined that it was because i was calling it from within the Global.asax Application_Start.
I moved this to my WebRole.cs OnStart() function and it works properly.

Resources