Shaun Xu

The Sheep-Pen of the Shaun


News

logo

Shaun, the author of this blog is a semi-geek, clumsy developer, passionate speaker and incapable architect with about 10 years’ experience in .NET and JavaScript. He hopes to prove that software development is art rather than manufacturing. He's into cloud computing platform and technologies (Windows Azure, Amazon and Aliyun) and right now, Shaun is being attracted by JavaScript (Angular.js and Node.js) and he likes it.

Shaun is working at Worktile Inc. as the chief architect for overall design and develop worktile, a web-based collaboration and task management tool, and lesschat, a real-time communication aggregation tool.

MVP

My Stats

  • Posts - 122
  • Comments - 549
  • Trackbacks - 0

Tag Cloud


Recent Comments


Recent Posts


Archives


Post Categories


Image Galleries


.NET



Although the azure application will be running on the sky we still need to develop it on the ground since we would not be able to fly. In order to make it easy and simple to work with azure on local machine we need to download the Azure SDK firstly. Azure SDK extend Visual Studio 2008 and Visual Studio 2010 RC to enable the creation, configuration, building, debugging, running and packaging of scalable web applications and services on Windows Azure, and it includes all necessary assemblies which we need to build the azure application.

Once we installed the SDK in the New Project dialog of Visual Studio we can find a new category named Cloud Service.

1

Once select the Windows Azure Cloud Service we can select and add the roles we want. As I mentioned in the last post a role = a project so here let's say we want to add an ASP.NET Web Application. Chose the ASP.NET Web Role and rename it to Web_Role.

2

Now we created a new azure application with one web role there. Let's look a bit about the projects and files it created for us.

3

There are 2 projects; CloudService2 is an azure project which only contains the configuration for deploying to roles to windows azure. Web_Role is a project very similar with the traditional web application, just a new file named WebRole.cs. This file contains some necessary procedures such as the application started, configuration changing, etc.

Let's add some test code on the default page and then just press F5 to run it and to see what's happening.

4

After compiled in Visual Studio the website appeared on the browser with the correct content I had modified, which is same as what we did when developing a normal website locally. But please notice the taskbar, there's a small blue Windows logo (ugly) appeared. The context menu contains some items like the image below.

5

The Development Fabric is a simulator running on the local machine. When running the azure application at local machine it will be deployed on the Development Fabric and execute all necessary procedures exactly same as what it will be on the Azure. So we can code and debug it without touching the azure service remotely. And if we click the Show Development Fabric UI item we can see the console-like screen appeared with some logs.

6

Let's go to the default page and add some logs on Page_Load function.

   1: protected void Page_Load(object sender, EventArgs e)
   2: {
   3:     System.Diagnostics.Trace
   4:         .TraceInformation("The Default.aspx page had been opened.");
   5: }

And then pressed F5 so we can see on the Development Fabric UI our log appeared there.

7

Next let's work a little bit on the storages that windows azure provides. As we know windows azure provides 3 storages for us: table storage, blob storage and queue storage. I don't want to dig into too much deeply on all of them, just an example on how to work with them locally rather than on the cloud. (I will explain more detailed about the storages in later posts.) Before starting play with them we need to establish the local storage simulation. The azure SDK provides a simulation for us but we need to make sure the there's an instance of SQL Server 2005 (Express) or higher installed in our computer. We navigate to the installation folder of windows azure SDK, normally should be C:\Program Files\Windows Azure SDK\v1.1 and execute \bin\devstore\DSInit.exe. It will create the tables for the simulation on your local SQL Server instance. (You need to add the login for the SQL Database for your currently user.)

If you have SQL Server installed (rather than Express version) you need to add “/sqlInstance” parameter as the DSInit tool utilize .\SQLEXPRESS by default. If you didn’t provide the instance name of your SQL Server just use “.” (dot) as its name so the full command would be “dsinit /sqlInstance .”.

8

If you back to the database through SSMS we can see the tables created by the simulation. While working with the storages locally our application will use these tables as the windows azure storage services. The Development Fabric exposes them by ADO.NET Data Service protocol, same like what it will be on azure. So we can use them exactly the same as on the cloud.

Now let's do something to test the storage. As I said I don't want to dig into much on all of them so let's just create a very simple web application called 'Whiteboard' that allows anyone write something and save it. We want to save the comments and display them on the default page so we need create a class for the data entity. Just create a new class named CommentEntity and paste the code below.

   1: public class CommentEntity : TableServiceEntity
   2: {
   3:     public string Content { get; set; }
   4:     public string Author { get; set; }
   5:     public DateTime CreateOn { get; set; }
   6:  
   7:     public CommentEntity()
   8:         : base(DateTime.UtcNow.ToString("yyyyMMdd"), 
   9:                string.Format("{0:10}_{1}", DateTime.MaxValue.Ticks - DateTime.Now.Ticks, Guid.NewGuid()))
  10:     {
  11:     }
  12: }

All entities stored in the table storage should have 2 public string properties: PartitionKey and RowKey. They are the unique identify columns for all entities. The azure SDK provides a base class for us named TableServiceEntity which we can use. It has the PartitionKey and RowKey properties there and the default constructor. So you can see that the CommentEntity we created was derived from it.

Since the storages are exposed by ADO.NET Data Service we need to create the relevant class to connect and consume it. We add another class named WhiteboardDataContext for the data context and source.

   1: public class WhiteboardDataContext : TableServiceContext
   2: {
   3:     private CloudStorageAccount _account;
   4:  
   5:     public IQueryable<CommentEntity> Comments
   6:     {
   7:         get
   8:         {
   9:             return CreateQuery<CommentEntity>("Comments");
  10:         }
  11:     }
  12:  
  13:     public WhiteboardDataContext(CloudStorageAccount account)
  14:         : base(account.TableEndpoint.AbsoluteUri, account.Credentials)
  15:     {
  16:         _account = account;
  17:  
  18:         var tableStorage = new CloudTableClient(_account.TableEndpoint.AbsoluteUri, _account.Credentials);
  19:         if (!tableStorage.DoesTableExist("Comments"))
  20:         {
  21:             CloudTableClient.CreateTablesFromModel(typeof(WhiteboardDataContext), _account.TableEndpoint.AbsoluteUri, _account.Credentials);
  22:         }
  23:     }
  24:  
  25:     public void AddCommentEntity(CommentEntity comment)
  26:     {
  27:         AddObject("Comments", comment);
  28:         SaveChanges();
  29:     }
  30: }

The WhiteboardDataContext derived from TableServiceContext, which is included in the azure SDK for connect to the table storage. What we did just simply add a property for retrieving the comments and insert a new comment into the storage. In the constructor, we firstly check whether the table for the comments had been initialized or not. If not then we create it from the context type with the credentials passed through the parameter.

Next we go to the frontend file - Default.aspx and add a textbox, a button for adding new comment; and a GridView for displaying all comments in the storage. In the backend code, we create several methods below.

   1: public partial class _Default : System.Web.UI.Page
   2: {
   3:     WhiteboardDataContext _context;
   4:  
   5:     protected void Page_Load(object sender, EventArgs e)
   6:     {
   7:         _context = new WhiteboardDataContext(CloudStorageAccount.FromConfigurationSetting("DataConnectionString"));
   8:  
   9:         if (!IsPostBack)
  10:         {
  11:             BindComments();
  12:         }
  13:     }
  14:  
  15:     protected void btnPostComment_Click(object sender, EventArgs e)
  16:     {
  17:         var comment = new CommentEntity()
  18:         {
  19:             Content = txtNewComment.Text,
  20:             CreateOn = DateTime.Now
  21:         };
  22:         _context.AddCommentEntity(comment);
  23:  
  24:         BindComments();
  25:     }
  26:  
  27:     private void BindComments()
  28:     {
  29:         var comments = _context.Comments.ToList();
  30:         gvComments.DataSource = comments;
  31:         gvComments.DataBind();
  32:     }
  33: }

Firstly we defined a local variant for the data context we had just created and initialize it when page's loading. Then we invoke the BindComments method to retrieve all comments and display on the GridView. In that method we just called the Comments property of the WhiteboardDataContext.
When adding a new comment, we created the comment entity based on what the user typed in the textbox and utilized AddCommentEntity method to insert and saved changes.

Before press F5 we need to do something special for azure development. First is that we need to define some configuration, which tells our application which storage it should use. Double click the Web_Role node under the CloudService2 project, navigate to the Settings panel and create another connect string named DataConnectString. Then in the Value cell open the editor form and just select the first radio button, which indicates using the development storage locally.

The next one is define the configuration setter for the azure application. This is to tell the application how to retrieve the configuration value based on the name. Just modify the OnStart method as the code below.

   1: public override bool OnStart()
   2: {
   3:     DiagnosticMonitor.Start("DiagnosticsConnectionString");
   4:  
   5:     // For information on handling configuration changes
   6:     // see the MSDN topic at http://go.microsoft.com/fwlink/?LinkId=166357.
   7:     RoleEnvironment.Changing += RoleEnvironmentChanging;
   8:  
   9:     Microsoft.WindowsAzure.CloudStorageAccount.SetConfigurationSettingPublisher((configName, configSetter) =>
  10:     {
  11:         configSetter(Microsoft.WindowsAzure.ServiceRuntime.RoleEnvironment.GetConfigurationSettingValue(configName));
  12:     });
  13:  
  14:     return base.OnStart();
  15: }

And now we can run this application a see how it's going. First time there's nothing in the comment table so we got a blank textbox with a button. And we can enter some sentences and add it into the system.

12

Do not laugh at my UI skill I know I'm an amateur. The key point is that the comments saved in the table storage. If you open up the local SQL Server database you can see some records inserted into the TableRow table.

13

Notice that in the azure platform the data was not stored as the structure in local simulation. At local machine the simulations just created a table for the tables' schema and another for the data and expose them through Data Service by the Development Storage.

It's how we develop and debug (although I didn't show the debug screenshots but trust me we can insert a breakpoint and debug same as what we are doing now everyday) an azure application at local machine without touching the cloud at all. But we do need to upload it onto azure once we think it's good enough to be go-live. In the next post I would like to deploy this application on to azure, real azure.

 

Hope this helps.

Shaun

 

All documents and related graphics, codes are provided "AS IS" without warranty of any kind.
Copyright © Shaun Ziyan Xu. This work is licensed under the Creative Commons License.


Comments

Gravatar # re: Azure - Part 2 - Develop and Debug Azure Application
Posted by Feroz on 2/26/2010 2:47 PM
Nice work on the top of it..
Gravatar # re: Azure - Part 2 - Develop and Debug Azure Application
Posted by RaviKumar on 4/28/2010 8:56 PM
Hi, i have followed the steps provided by you. but i am getting build error :Erro The name 'CreateQuery' does not exist in the current context

Thanks
Ravi
Gravatar # re: Azure - Part 2 - Develop and Debug Azure Application
Posted by Shaun on 4/29/2010 8:00 AM
@Ravi

I guess this is because you didn't add System.Data.Services.Client which is the client library for ADO.NET Data Service provides the CreateQuery, Insert, etc methods. The Microsoft.WindowsAzure.StorageClient just provides the base classes for storage classes but not those base methods.
Gravatar # re: Azure - Part 2 - Develop and Debug Azure Application
Posted by RaviKumar on 4/29/2010 1:34 PM
Hi Shaun
This time i am getting the error in default.aspx.cs at gvComments in BindComments method and in the file
<ItemGroup>
<RoleReferences Include="@(WebRoleReferences); @(WorkerRoleReferences)" />
</ItemGroup>
and

<Error
Condition=" !Exists('%(_ResolvedProjectReferencePaths.Identity)')"
Text="The referenced assembly %(_ResolvedProjectReferencePaths.Identity) was not found. Please make sure to build the role project that produces this assembly before building this Cloud Service Project."
ContinueOnError="false"/>


Why dont you send me the source code @ rkbhuvanagiri@hotmail.com

Thanks
RAVI
Gravatar # re: Azure - Part 2 - Develop and Debug Azure Application
Posted by Shaun on 4/29/2010 1:41 PM
I'm not at the office now but will pass the code to you once I can.
Gravatar # re: Azure - Part 2 - Develop and Debug Azure Application
Posted by Shaun on 4/30/2010 11:21 AM
@Ravi
Had passed the source code over to you. Hope it helps.
Gravatar # re: Azure - Part 2 - Develop and Debug Azure Application
Posted by Tejas Kardile on 1/31/2011 5:55 PM
while running above application on default page getting below error:

SetConfigurationSettingPublisher needs to be called before FromConfigurationSetting can be used

please explain why i am facing this error

Thanks
Tejas
Gravatar # re: Azure - Part 2 - Develop and Debug Azure Application
Posted by Shaun on 2/1/2011 9:03 AM

@Tejas Kardile
I guess you are using Windows Azure SDK 1.3. In 1.3 the web role runs under another process besides the windows azure web core which invokes the SetConfigurationSettingPublisher method. Please copy Microsoft.WindowsAzure.CloudStorageAccount.SetConfigurationSettingPublisher((configName, configSetter) =>
{
configSetter(Microsoft.WindowsAzure.ServiceRuntime.RoleEnvironment.GetConfigurationSettingValue(configName));
});
into your web role, the Application_Start method and have another try.
Gravatar # re: Azure - Part 2 - Develop and Debug Azure Application
Posted by Alaa on 2/3/2011 7:55 PM
hi Shaun;
i faced an error that it doesn't accept(TableClient)
in the context although i added (System.Data.Services.Client )
Gravatar # re: Azure - Part 2 - Develop and Debug Azure Application
Posted by satinder singh on 2/26/2011 9:10 PM
Thanks Shaun Xu,

Nice post...
People who is using azure sdk v1.3 use following
on default page.Also no need to change on onstart event.

_context = new WhiteboardDataContext(CloudStorageAccount.Parse(RoleEnvironment.GetConfigurationSettingValue("DataConnectionString")));
Gravatar # re: Azure - Part 2 - Develop and Debug Azure Application
Posted by jagpreet singh on 2/26/2011 10:06 PM
Great post...
I have done this with little change as mentioned above because i am using sdk 1.3. Keep it up...


Thanks
Satinder singh hundal
Gravatar # re: Azure - Part 2 - Develop and Debug Azure Application
Posted by satinder singh on 3/1/2011 3:32 PM

I did in vs 2010 using c#.But when i try to do this in using vb then i am getting the following error.
windows azure project 1.csx does not exists.
Plz help me. My email id is satinderhundal1983@gmail.com
Thanks


Post A Comment
Title:
Name:
Email:
Comment:
Verification: