Please find the slides from my Microsoft Azure tutoral at the SI-SE http://si-se.ch/2013/ conference here. This was a hands-on session for beginners and non-.NET people.
Everybody had its solution running in the cloud…
… and not on-premise
Please find the slides from my Microsoft Azure tutoral at the SI-SE http://si-se.ch/2013/ conference here. This was a hands-on session for beginners and non-.NET people.
Everybody had its solution running in the cloud…
… and not on-premise
On Thursday, 24.1.2013 I give an Azure Tutorial targeted at (non-Microsoft technology stack) developers and architects at SI-SE.ch http://si-se.ch/2013/tutorials
Come and see me introducing to the Azure platform services – and develop and deploy your first Azure cloud application yourself!
I came accross an issue today where I wanted to deploy a .NET 4.5 (osVersion=”3”) cloud service using a self-signed SSL certificate to protect the web service traffic:
11:55:44 AM - Preparing deployment for <solution> - 11/23/2012 11:55:30 AM with Subscription ID ‘<subscription>' using Service Management URL 'https://management.core.windows.net/'...
11:55:44 - Connecting...
11:55:46 - Warning: Error: Certificate: ‘SSLCertificate’ with Thumbprint: <thumbprint> for Role: <solution>Service has not been uploaded to the cloud service: <solution>.
11:55:46 - The deployment cannot be completed because it requires certificates or OS images which are not present in the cloud.
11:55:46 - Deployment failed with a fatal error
I investigated around my projects certificate settings, thumbprint or certificate store location – in vain. Then I solved the problem:
NOTE
Looks like this being by design: conforming to some best security practices where developers should not have access to the production certificates – so deployment stops here. Took me some time so see it – but is perfectly true.
As published today in the Azure Team Blog, pricing is reduced for SQL Azure (by about 50%). 5 GB are now 26$ instead of 50$.
Furthermore SQL Azure is getting more attractive for small data apps with the new 100MB option:
Database Size | Price Per Database Per Month |
0 to 100 MB | Flat $4.995 |
Greater than 100 MB to 1 GB | Flat $9.99 |
-> 4 CHF/Mt for high availability, reliability and self-management.
See https://www.windowsazure.com/en-us/pricing/details/ for details.
I got a SQL server (express) database backup (.bak file) from a customer to do a test against. In the past, I just restored from my own, previously existing databases, so I never came across the issue of restoring one from a complete different machine. Using SSMS I got the following error messages
The backup set holds a backup of a database other than the existing database – or
File 'Db' cannot be restored to 'C:\Program Files\Microsoft SQL Server\MSSQL10_50.CUSTOMER\MSSQL\DATA\Db.mdf'. Use WITH MOVE to identify a valid location for the file.
The path does not exist on my machine. After browsing the web I found out the following:
RESTORE DATABASE [Db]
FROM DISK = 'c:\theDbBackup.bak'
WITH REPLACE
This year the ESE conference 2012 will take place in Zurich April 24. and 25. – hosted by Zühlke Engineering AG.
That’s where software experts from around the world meet their peers and prominent speakers. The conference targets software architects, project managers, IT manager, process experts and all kinds of techies. Interactive discussion and talks are a major part of the two days.
There are three trendy tracks: Agile, Cloud and Mobile. See this for more details.
Got some issues recently with the Azure SDK samples (e.g. RelayedConnectionSample with NetTcp, MulticastSample, etc.). SecurityExceptions were thrown, etc.
Until I noticed that the samples still reference the Microsoft.ServiceBus.dll in
So you need to
<extensions>
<bindingExtensions>
<add name="netEventRelayBinding" type="Microsoft.ServiceBus.Configuration.NetEventRelayBindingCollectionElement, Microsoft.ServiceBus, Version=1.6.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
</bindingExtensions>
</extensions>
</system.serviceModel>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Microsoft.ServiceBus"
publicKeyToken="31bf3856ad364e35"
culture="neutral" />
<bindingRedirect oldVersion="1.0.0.0"
newVersion="1.6.0.0"/>
</dependentAssembly>
</assemblyBinding>
</runtime>
and it works again.
However, some of the samples did not with 1.6 but only with 1.5. Maybe I messed up with the latest SDK installation.
Using Windows “Azure Connect” - a service from the Windows Azure platform – one can establish a protected network connection between enterprise computers and the cloud roles (E2C). This virtual IPsec network allows for:
Setting up Connect is a 3 step process. There is a tutorial showing all the details.
1. Get an activation token from the Azure portal and configure your Azure roles to use it.
Copy the token into your role’s properties / virtual network settings
Now you publish your Azure roles to the staging or production environment in the cloud. Wait until the service is ready and check that it appears in the portals “Virtual network” –> “Groups and Roles” and “Activated Endpoints”.
2. Enable local machines to connect to roles in the cloud. Install the Connect Agent on local machines. Copy the link URL to a browser, download the configured executable and run it. A system tray icon like the following should appear
3. Pair the local machines and Azure roles in a “Group” (network policy). In the portal click Create Group
The system tray icon should change to connected now.
Please note that ping will not work until you enable it in your role using a startup task script. From my limited home network I experienced some significant (first-hit) network delays
Pinging RD00155D3A622D [2a01:111:f102:121:858:cf20:a9dd:5639] with 32 bytes of data:
Reply from 2a01:111:f102:121:858:cf20:a9dd:5639: time=299ms
Reply from 2a01:111:f102:121:858:cf20:a9dd:5639: time=258ms
Reply from 2a01:111:f102:121:858:cf20:a9dd:5639: time=359ms
Reply from 2a01:111:f102:121:858:cf20:a9dd:5639: time=368ms
Ping statistics for 2a01:111:f102:121:858:cf20:a9dd:5639:
Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
Minimum = 258ms, Maximum = 368ms, Average = 321ms
Azure Data Sync let’s you synchronize enterprise (on-premise) SQL Server (2005 and above) databases with SQL Azure databases – or several SQL Azure databases. There is a local agent and a cloud sync group service necessary for it to work.
This is the first preview from Nov 14 2011; let’s have a try.
In the management portal navigation tree go to Data Sync, select a subscription, a data center region,
You now have two options:
Let’s synchronize on-prem and a cloud SQL Azure database. The wizard leads you through the configuration of a sync group
Download and install the so called Sync Agent for the local server.
Then start the Data Sync Agent Preview from the start menu.
Now generate an agent key from the management portal and copy it into the local agent wizard.
Then register a SQL Server
to get
Back in the portal we add the agent to the Sync Group
Now we are half way through. Now let’s add an SQL Azure database:
Just creating a new SQL Azure database for this demo – and selecting it in Step 3 above.
In the following step (4) we configure the scheduling, and the conflict resolution (client or hub wins)
Select the on-premise SQL database
Click deploy now
Done!
Now, let’s see that it worked correctly. In the local Northwind database there are 2 people from Switzerland, add a row filter for Country = ‘Switzerland’. Then go the SSMS, connect the SQL Azure DB. There is a new dbo.Customers table now. Please also note the added tables for the change tracking. There are also some triggers and stored procedures added to your database. This may impact your runtime performance.
There are the 2 rows as expected:
That’s it again in the portal
This was actually super simple to setup. There are some best practices out there.
Negative point: there does not seem to exist an API or .NET library for scripted configuration and operation.
Last time I showed you how to create, build, package, upload and use a simple DNN module, developed in C# using Visual Studio
2010. Let’s get started by thinking (and writing down ) some requirements.
Non-functional
R-NFR1 DotNetNuke 05.06
R-NFR2 ASP.NET 4
R-NFR3 local testability without DNN installation
Use Cases
As a client I want to:
R-U1 – Create an online account on the site
R-U2 – Log in and out
R-U3 – Choose a treatment
R-U4 – Choose a time/date
R-U5 – Book a massage
R-U6 – Got sent an email confirmation
R-U6.1 with an outlook appointment attached to it
R-U7 – get shown my booked treatments in detail
As an administrator I want to:
R-A1 – Define treatments (duration, title, description)
R-A2 – Define time windows (opening or working hours)
R-A3 – Show (todays, etc.) bookings
R-A4 – Got sent an email with a client booking information
R-A5 – Manage accounts (list, add, edit, delete)
To separate DotNetNuke module stuff from booking web functionality I added a new ASP.NET web project to the solution
remove the generated pages, sub folders and strip down the web.config file to a minimum.
Now add a web user control to the BookingViews project
Writing an outlook style schedule/calendar control in ASP.NET seems like a huge effort. Let’s get a commercial control library suite including a schedule control. As DNN already contains Telerik controls the evaluation was short. They have an excellent reputation when talking to colleagues.
First let’s show the data access layer where the massage bookings and treatment offerings are persisted. Using the Entity Framework 4.0 model first approach, I create the following model:
The BookingEntry and Treatment entities were added in the model edmx in VS design view. However, the User entity was imported from the existing DotNetNuke database (table first). Adding some relations and I can take advantage of the DNN register/login/user functionality in my bookings.
Learning and configuring the module view took more effort. This is the resulting aspx:
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="BookingForm.aspx.cs" Inherits="BookingViews.BookingForm" %>
<%@ Register Assembly="Telerik.Web.UI" Namespace="Telerik.Web.UI" TagPrefix="telerik" %><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head runat="server"><title></title></head><body><form id="form1" runat="server">
<asp:ScriptManager ID="ScriptManager1" runat="server">
</asp:ScriptManager>
<div style="height: 527px; width: 827px">
<telerik:RadScheduler ID="RadScheduler1" runat="server" Culture="de-CH" DayEndTime="19:00:00"
DayStartTime="07:00:00" FirstDayOfWeek="Monday" Height="558px" SelectedView="WeekView"
ShowViewTabs="False" Skin="Forest" Width="800px" WorkDayEndTime="19:00:00" WorkDayStartTime="07:00:00"
SelectedDate="2011-11-01" DataEndField="End" DataKeyField="Id"
DataStartField="Start" DataSubjectField="Subject"
onappointmentcommand="RadScheduler1_AppointmentCommand"
ontimeslotcreated="RadScheduler1_TimeSlotCreated"
DataSourceID="BookingEntryDataSource" DataDescriptionField="Remarks"
EnableDescriptionField="True">
<ResourceTypes>
<telerik:ResourceType DataSourceID="TreatmentDataSource"
ForeignKeyField="TreatmentId" KeyField="Id" Name="TreatmentResource"
TextField="Name" />
</ResourceTypes>
<WeekView DayEndTime="19:00:00" DayStartTime="07:00:00" HeaderDateFormat="dd.MM.yyyy"
WorkDayEndTime="19:00:00" WorkDayStartTime="07:00:00" />
<AppointmentTemplate>
<span style ="font-weight: bold; font-size: small">
<%# Eval("Subject") %>
</span>
<br />
<asp:ImageButton ID="ImageButton1" runat="server" ImageUrl="~/Resources/Calendar.png" OnClick="ExportOutlook" CommandName="ExportOutlook" />
</AppointmentTemplate>
</telerik:RadScheduler>
</div>
<telerik:RadAjaxManager runat="server">
<AjaxSettings>
<telerik:AjaxSetting AjaxControlID="RadScheduler1">
<UpdatedControls>
<telerik:AjaxUpdatedControl ControlID="RadScheduler1" />
</UpdatedControls>
</telerik:AjaxSetting>
</AjaxSettings>
</telerik:RadAjaxManager>
<asp:ObjectDataSource ID="BookingEntryDataSource" runat="server"
DataObjectTypeName="My.DotNetNuke.Modules.BookingModule.BookingEntry"
DeleteMethod="Delete" InsertMethod="Add" SelectMethod="GetAll"
TypeName="My.DotNetNuke.Modules.BookingModule.Data.BookingEntryDataRepository"
UpdateMethod="Update"></asp:ObjectDataSource>
<asp:ObjectDataSource ID="TreatmentDataSource" runat="server"
DataObjectTypeName="My.DotNetNuke.Modules.BookingModule.Treatment"
DeleteMethod="Delete" InsertMethod="Add" SelectMethod="GetAll"
TypeName="My.DotNetNuke.Modules.BookingModule.Data.TreatmentDataRepository"
UpdateMethod="Update"></asp:ObjectDataSource>
</form>
</body>
</html>
The control’s data sources are of type ObjectDataSource. BookingEntryDataSource and TreatmentDataSource both implement the IRepository<T> interface. This hides the EF stuff behind a façade and allowed better testability than the EntityDataSource:
/// <summary>
/// Interface to decouple entities from data access.
/// </summary>
public interface IRepository<T> where T: class
{
void Add(T entity);
void Delete(T entity);
ICollection<T> GetAll();
T GetById(T entryWithKeyOnly);
void Update(T entity);
}
Note that I added the telerik rad scheduler, configured a week view, added some appointment resources and DataSources to be bound in the scheduler control.
And this is the final result:
Double clicking shows or edits the details of the appointment
I hope this 3-part series of my (hobby project) development “minutes” gave you some insight around DotNetNuke module development in Visual Studio using C#.