I've got a web app running with a web job running on Azure. I've linked my solution to Bitbucket in order to use continuous deployment and that part is working fine.
The problem I'm having is that whenever I deployment (and rebuild) occurs, neither my web app or web job can access my Azure storage table as the value returned from CloudConfigurationManager.GetSetting("StorageConnectionString")
returns a blank value.
I've just checked via FTP and both my web app and webjob has the relevant entry in their respective config file i.e. StorageConnectionString
<appSettings>
...
<add key="StorageConnectionString"
value="DefaultEndpointsProtocol=https;
AccountName=MyASPMVCSite;AccountKey=ABCD==" />
</appSettings>
I call the following code to read the StorageConnectionString value from my appSettings
var cloudStorageAccount =
CloudStorageAccount.Parse(
CloudConfigurationManager.GetSetting("StorageConnectionString"));
but when I try to output this value to either my home page or my webjob log, it "displays" as an empty value.
When I publish my project via a Web Deploy
directly from VS 2013 to Azure, everything works as expected. My StorageConnectionString
value is displayed on both my home page and web job log.
Any ideas why?
Thanks.
UPDATE
If you have time to spare and want to try to reproduce it, here is the code.
As the project is so small, but I don't believe the problem lies with the code. I think it lies with the deployment.
I created a basic ASP.NET MVC web application and then added a webjob project as a second project to the solution. It is a very basic test sample that I'm following from MS Virtual Academy. All it does is insert a random number into a storage table whenever the web job is called.
I've added the following code the ASP.NET MVC web app:
Changed the index.cshtml and added the following at the bottom the file:
<h1>Table Endpoint:</h1> @Html.Raw(ViewBag.TableEndpoint) <br /> <h1>Azure Results:</h1> @Html.Raw(ViewBag.Result)
Changed the HomeController.cs to:
public ActionResult Index() { Time = string.Format("{0:MM/dd/yyyy hh:mm:ss tt}", DateTime.UtcNow); long ticks = DateTime.MaxValue.Ticks; DateTime utcNow = DateTime.UtcNow; string orderingTime = string.Format("{0:D19}", ticks - utcNow.Ticks); ViewBag.Message = "Modify this template to jump-start your ASP.NET MVC application."; var cloudStorageAccount = CloudStorageAccount. Parse(CloudConfigurationManager. GetSetting("StorageConnectionString")); Console.WriteLine(cloudStorageAccount. TableEndpoint.ToString()); var tableReference = cloudStorageAccount. CreateCloudTableClient(). GetTableReference("Activity"); var activities = ( from g in tableReference.CreateQuery<Activity>() where (g.PartitionKey == "Demo") && string.Compare(g.RowKey, orderingTime, StringComparison.Ordinal) > 0 select g); string result = string.Empty; if (activities != null) { foreach (var activity in activities) { result += string.Format("<p>{0} => {1}</p>", activity.Date.ToLongDateString(), activity.Number.ToString()); } } ViewBag.TableEndpoint = cloudStorageAccount.TableEndpoint.ToString(); ViewBag.Result = result; return View(); }
I've added a class to the Models folder i.e. Activity.cs
public class Activity : TableEntity { public DateTime Date { get; set; } public int Number { get; set; } }
In the web job project, the following was changed:
The Program.cs was changed to:
static void Main() { //var host = new JobHost(); //// The following code will invoke //a function called ManualTrigger and //// pass in data (value in this case) to the function //host.Call(typeof(Functions). //GetMethod("ManualTrigger"), new { value = 20 }); var cloudStorageAccount = CloudStorageAccount.Parse( CloudConfigurationManager. GetSetting("StorageConnectionString")); Console.WriteLine( cloudStorageAccount.TableEndpoint.ToString()); var tableReference = cloudStorageAccount. CreateCloudTableClient(). GetTableReference("Activity"); tableReference.CreateIfNotExists(); Random random = new Random(); var activity = new Activity() { Number = random.Next(100) }; var tableOperation = TableOperation.Insert(activity); try { tableReference.Execute(tableOperation); } catch (Exception) { throw; } //#if DEBUG Console.WriteLine("{0} number generated.", activity.Number.ToString()); Console.ReadLine(); //#endif }
I've also added a new class i.e. Activity.cs
public class Activity : TableEntity { public DateTime Date { get; set; } public int Number { get; set; }
public Activity() { var ticks = DateTime.MaxValue.Ticks; var utcNow = DateTime.UtcNow; this.PartitionKey = "Demo"; this.RowKey = string.Format("{0:D19}", ticks - utcNow.Ticks); this.Date = DateTime.Now; }
}
That's it. Every time you run the web job it will generate a random number and insert it into an Activity table. When running the web app, it will simply list all the numbers that were added to the table at the bottom of the home page (i.e. index).
All you need to do if you want to try to reproduce it is to add this to BitBucket (or other git repository - not sure if it is specific to BitBucket or not), make sure to link your project for continuous deployment, make a change, commit and upload your changes. This is the part that fails for me.
If you then use WebDeploy in VS, it then works.
Don't forget, you have to add the StorageConnectionString
in the appSettings section in both project and set it to the relevant Azure Storage.
Thanks.