South Florida Code Camp 2013


If you haven’t heard, one of the biggest Code Camps in the country will start in about 7 hours! Last I heard we broke the record of 1200 registered! So if you haven’t registered, it’s ok, just show up tomorrow at

Nova Southeastern University (NSU) - Main Campus Davie, Florida
Carl DeSantis Building
3301 College Avenue
Fort Lauderdale-Davie, FL 33314

This year I will be doing two sessions:

Building Cross Platform Applications: WP, iOS, Android

Come learn how to write mobile cross platform application using Microsoft's and Xamarin’s (MonoTouch and Mono for Android) tools. We will learn how to architect and write code that can be reused across all platforms using C# and the .NET Framework.

Getting Started with SignalR

SignalR is a groundbreaking open-source project in the .NET community. It offers real-time communication to a variety of platforms, is easy to use and to set up, and scales immensely. Join me as we demo how to use SignalR in different environments using C#!

I hope to see you there in the front row of both of my sessions asking as many questions as you can think of!

Happy Learning!

author:  | posted @ Saturday, February 09, 2013 12:20 AM | Feedback (1)

Getting Started With SignalR – .NET Miami User Group


Today, October 18th, I will be presenting my Getting Started With SignalR talk at the .NET Miami User Group. Please join me to learn about the new revolutionary open source project from Microsoft:

Have you ever wished that you had a persistent connection to a web client instead of using the refresh button or long polling? A new open-source project lets ASP.Net developers easily create real-time communication in web applications. Join us as Microsoft MVP Jonas Stawski gives us a facinating look into SignalR, a project that will allow you to create real-time web apps.

Where:
Planet Linux Café : 1430 Ponce De Leon Blvd, Coral Gables, FL 33134

When:
Thursday, October 18th, 2012

What:
Getting Started With SignalR

author:  | posted @ Thursday, October 18, 2012 9:45 AM | Feedback (0)

Getting Started with SignalR


Join me as I present Getting Started with SignalR at the West Palm Beach .NET user group September 25th, 2012.

SignalR is a groundbreaking open-source project in the .NET community. It offers real-time communication to a variety of platforms, is easy to use and to set up, and scales immensely. Join me as we demo how to use SignalR in different environments!

See you there!

author:  | posted @ Monday, September 24, 2012 12:19 PM | Feedback (0)

Seemingly Integrate SkyDrive or DropBox With Your Windows Libraries


The world of computers has dramatically changed; what once was an utopia, it is now a reality. Bill Gate’s vision of one computer on every home seemed like an impossibility, but now it is very common to see an average person own a computer, tablet, and smart phone. Not to mention the hard core users that have more than one computer. This accessibility of hardware has lead to a huge problem: file synching. With so many computers people don’t know where their files are, but today we have multiple solutions: SkyDrive, DropBox, iCloud, and probably many other hidden gems. SkyDrive and DropBox solve the problem by installing a mini client that synchronizes your files between the Cloud and your other computers. They do so by setting a special folder in your computer which is used as a repository. Any file you drop, create, delete, or modify into this folder is automatically synced. This solution brought another problem: if you are hardcore about your file and folder structure you are out of luck. In other words, if you like to keep your pictures under My Pictures or your Documents under My Documents, these file synchronizers abruptly changed your ways… until now.

Windows 7 introduced the concept of Libraries:

provide users with a single, coherent view of their files even when those files are stored in different locations. Libraries can be configured and organized by a user and a library can contain folders that are found on the user's computer and also folders that have been shared over a network. Libraries present a simpler view of the underlying storage system because, to the user, the files and folders in a library are displayed in single view, no matter where they are physically stored.

In simpler terms, you can now specify what folders should be included within your Documents, Pictures, Music, etc Libraries. Therefore, we can now use SkyDrive (or DropBox) with it’s default settings and add specific folders to your Libraries from the SkyDrive folder. I will illustrate how to do so using SkyDrive, but this can also be done using DropBox.

Bellow is a screen shot of my Explorer Window with my SkyDrive folder selected. Note that the default installation adds the SkyDrive folder to your Favorites menu on the left side. If you can’t find it, you can browse to C:\Users\[name]\SkyDrive, where [name] is your username. i.e. C:\Users\Jonas\SkyDrive.

image

As you can see I have a Documents and Pictures folder within my SkyDrive folder, if you don’t have them you can create them and it will automatically sync to your other computers and the cloud.

Next step is to right click on Document under the Libraries section and go to Properties:

image image

Click on the Add button on the Library locations and browse to the SkyDrive\Documents. (Remember that SkyDrive should be under Favorites). Click Include Folder and the Click OK to close the Documents Property window.

image

After you are all done, your Library folder should look like the picture below. If you want to seemingly integrate it without differentiating the folder location, click on the Group By and select none. Doing so will flatten the view, but the problem with that is that any file created on the root will be saved to the default Save Location, which is the local Documents folder that is not synched with SkyDrive. If you want the SkyDrive folder to be the default Save Location you can do so on the Properties Window.

image image image

Of course, you can do the same with the rest of the Libraries: Music, Pictures, Videos.

Happy File Syncing

author:  | posted @ Tuesday, August 21, 2012 10:14 AM | Feedback (0)

Scaling Out/In with the Azure Management API


The Windows Azure Service Management REST API docs are very well written and informative, but they do lack in examples. In this post I will write a guide on how to use the Rest API to programmatically Scale Out/In (increase/decrease the number of instances).

In order to increase the number of instances of a deployment you must call the Change Deployment Configuration operation and post an updated configuration file to Azure. Therefore, the first thing to do is get the current configuration by calling the Get Deployment operation. After we retrieve the deployment we need to change the configuration file so we can scale out or in. The service returns the configuration file encoded as a base 64 so we abstract the decoding, modification, and re encoding using the UpdateInstanceCount method. After the change we call the ChangeDeploymentConfiguration which uploads the new configuration file to Azure.

   1: public void Scale(string serviceName, string deploymentName, string roleName, int count)
   2: {
   3:     X509Certificate2 cert = GetCertificate(); //from somewhere
   4:     Guid subscriptionId = new Guid("use your subscription guid");
   5:  
   6:     Deployment dep = GetDeployment(subscriptionId, serviceName, deploymentName, cert);
   7:  
   8:     if (dep == null)
   9:     {
  10:         //deployment doesn't exist anymore!
  11:         //TODO: do something
  12:         return;
  13:     }
  14:     string encodedConf = UpdateInstanceCount(dep.Configuration, roleName, count);
  15:     if (encodedConf == null)
  16:     {
  17:         //role doesn't exist anymore!
  18:         //TODO: do something
  19:         return;
  20:     }
  21:  
  22:     ChangeDeploymentConfiguration(subscriptionId, serviceName, deploymentName, encodedConf, false, cert);
  23:  
  24:     return View();
  25: }


Below is the GetDeployment function, which retrieves the Deployment information, including the encoded configuration file.

   1: const string getDeploymentUrl = "https://management.core.windows.net/{0}/services/hostedservices/{1}/deployments/{2}";
   2: const string getDeploymentVersion = "2012-03-01";
   3:  
   4: public static Deployment GetDeployment(Guid subscriptionId, string serviceName, string deploymentName, X509Certificate2 cert)
   5: {
   6:     Uri uri = new Uri(String.Format(getDeploymentUrl, subscriptionId, serviceName, deploymentName));
   7:  
   8:     HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(uri);
   9:     request.Method = "GET";
  10:     request.Headers.Add("x-ms-version", getDeploymentVersion);
  11:     request.ClientCertificates.Add(cert);
  12:     request.ContentType = "application/xml";
  13:  
  14:     XDocument responseBody = null;
  15:     HttpStatusCode statusCode;
  16:     HttpWebResponse response;
  17:     try
  18:     {
  19:         response = (HttpWebResponse)request.GetResponse();
  20:     }
  21:     catch (WebException ex)
  22:     {
  23:         // GetResponse throws a WebException for 400 and 500 status codes
  24:         response = (HttpWebResponse)ex.Response;
  25:     }
  26:     statusCode = response.StatusCode;
  27:     if (response.ContentLength > 0)
  28:     {
  29:         using (XmlReader reader = XmlReader.Create(response.GetResponseStream()))
  30:         {
  31:             responseBody = XDocument.Load(reader);
  32:         }
  33:     }
  34:     response.Close();
  35:     if (statusCode.Equals(HttpStatusCode.OK))
  36:     {
  37:         XNamespace wa = "http://schemas.microsoft.com/windowsazure";
  38:         XElement dep = responseBody.Element(wa + "Deployment");
  39:         Deployment deployment = new Deployment
  40:         {
  41:             Name = dep.Element(wa + "Name").Value,
  42:             Slot = (DeploymentSlot)Enum.Parse(typeof(DeploymentSlot), dep.Element(wa + "DeploymentSlot").Value),
  43:             PrivateID = dep.Element(wa + "PrivateID").Value,
  44:             Status = (DeploymentStatus)Enum.Parse(typeof(DeploymentStatus), dep.Element(wa + "Status").Value),
  45:             Label = dep.Element(wa + "Label").Value,
  46:             Url = new Uri(dep.Element(wa + "Url").Value),
  47:             Configuration = dep.Element(wa + "Configuration").Value,
  48:             Roles = (from r in dep.Element(wa + "RoleInstanceList").Elements(wa + "RoleInstance")
  49:                      select new RoleInstance
  50:                      {
  51:                          RoleName = r.Element(wa + "RoleName").Value,
  52:                          InstanceName = r.Element(wa + "InstanceName").Value,
  53:                          Size = (InstanceSize)Enum.Parse(typeof(InstanceSize), r.Element(wa + "InstanceSize").Value),
  54:                          Status = (InstanceStatus)Enum.Parse(typeof(InstanceStatus), r.Element(wa + "InstanceStatus").Value)
  55:  
  56:                      }).ToList()
  57:         };
  58:  
  59:         return deployment;
  60:     }
  61:     else
  62:     {
  63:         //TODO: return some error
  64:     }
  65:     return null;
  66: }

From the code above you can see we first create the Uri that we will be calling using subscriptionId, serviceName, and deploymentName for a very specific deployment. All those values can be retrieved from previous calls to the Azure Management API and/or the Azure Management Portal. We then go ahead and create a web request using GET, attaching the certificate, and specifying the type as application/xml. If the response is OK then we populate the model object Deployment using LINQ to XML.

Below is the UpdateInstanceCount, which decodes, modifies, and encodes the configuration file.

   1: private static string UpdateInstanceCount(string base64Conf, string roleName, int count)
   2: {
   3:     string conf = GetStringFromBase64String(base64Conf);
   4:  
   5:     XDocument c = XDocument.Parse(conf);
   6:  
   7:     XNamespace wa = "http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceConfiguration";
   8:     XElement serviceConf = c.Element(wa + "ServiceConfiguration");
   9:  
  10:     var role = serviceConf.Elements(wa + "Role").Where(r => r.Attribute("name").Value == roleName).SingleOrDefault();
  11:  
  12:     if (role == null)
  13:         return null;
  14:  
  15:     role.Element(wa + "Instances").SetAttributeValue("count", count);
  16:  
  17:     string encoded = GetBase64StringFromString(serviceConf.ToString());
  18:  
  19:     return encoded;
  20: }
  21:  
  22: private static string GetStringFromBase64String(string base64Str)
  23: {
  24:     byte[] bs = System.Convert.FromBase64String(base64Str);
  25:     string s = System.Text.Encoding.UTF8.GetString(bs);
  26:     return s;
  27: }
  28:  
  29: private static string GetBase64StringFromString(string str)
  30: {
  31:     byte[] toEncodeAsBytes = System.Text.UTF8Encoding.UTF8.GetBytes(str);
  32:     string returnValue = System.Convert.ToBase64String(toEncodeAsBytes);
  33:     return returnValue;
  34: }


We first get a readable string of the base 64 encoded configuration and then create an XDocument so we can query it and change it. After changing the ServiceConfiguration\Role\Instances[count] attribute we base 64 encode the configuration again and return it to the calling method. Below is a sample configuration file:

   1: <ServiceConfiguration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" serviceName="" osFamily="1" osVersion="*" xmlns="http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceConfiguration">
   2:   <Role name="mTender">
   3:     <ConfigurationSettings>
   4:       <Setting name="Microsoft.WindowsAzure.Plugins.Diagnostics.ConnectionString" value="UseDevelopmentStorage=true" />
   5:       <Setting name="StorageAccount" value="something" />
   6:     </ConfigurationSettings>
   7:     <Instances count="1" />
   8:     <Certificates />
   9:   </Role>
  10: </ServiceConfiguration>

The last step is calling the ChangeDeploymentConfiguration which looks like this:

   1: const string changeDeploymentConfigurationUrl = "https://management.core.windows.net/{0}/services/hostedservices/{1}/deployments/{2}/?comp=config";
   2: const string changeDeploymentConfigurationVersion = "2012-03-01";
   3:  
   4: public static void ChangeDeploymentConfiguration(Guid subscriptionId, string serviceName, string deploymentName, string base64Configuration, bool treatWarningsAsError, X509Certificate2 cert)
   5: {
   6:     Uri uri = new Uri(String.Format(changeDeploymentConfigurationUrl, subscriptionId, serviceName, deploymentName));
   7:  
   8:     HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(uri);
   9:     request.Method = "POST";
  10:     request.Headers.Add("x-ms-version", changeDeploymentConfigurationVersion);
  11:     request.ClientCertificates.Add(cert);
  12:     request.ContentType = "application/xml";
  13:  
  14:     string xmlRequestFormat = @"<?xml version=""1.0"" encoding=""utf-8""?>
  15:                                 <ChangeConfiguration xmlns=""http://schemas.microsoft.com/windowsazure"">
  16:                                    <Configuration>{0}</Configuration>
  17:                                    <TreatWarningsAsError>{1}</TreatWarningsAsError>
  18:                                    <Mode>Auto</Mode>
  19:                                    <ExtendedProperties />
  20:                                 </ChangeConfiguration>";
  21:  
  22:     string xmlRequest = String.Format(xmlRequestFormat, base64Configuration, treatWarningsAsError.ToString().ToLower());
  23:  
  24:     byte[] bs = System.Text.Encoding.UTF8.GetBytes(xmlRequest);
  25:     request.ContentLength = bs.Length;
  26:  
  27:     Stream dataStream = request.GetRequestStream();
  28:     dataStream.Write(bs, 0, bs.Length);
  29:     dataStream.Close();
  30:  
  31:     XDocument responseBody = null;
  32:     HttpStatusCode statusCode;
  33:     HttpWebResponse response;
  34:     try
  35:     {
  36:         response = (HttpWebResponse)request.GetResponse();
  37:     }
  38:     catch (WebException ex)
  39:     {
  40:         // GetResponse throws a WebException for 400 and 500 status codes
  41:         response = (HttpWebResponse)ex.Response;
  42:     }
  43:     statusCode = response.StatusCode;
  44:     if (response.ContentLength > 0)
  45:     {
  46:         using (XmlReader reader = XmlReader.Create(response.GetResponseStream()))
  47:         {
  48:             responseBody = XDocument.Load(reader);
  49:         }
  50:     }
  51:     response.Close();
  52:     if (statusCode.Equals(HttpStatusCode.Accepted))
  53:     {
  54:         XNamespace wa = "http://schemas.microsoft.com/windowsazure";
  55:         //XElement hs = responseBody.Element(wa + "HostedService");
  56:  
  57:  
  58:         return;
  59:     }
  60:     else
  61:     {
  62:         //TODO: error! what do we return?
  63:     }
  64:     return;
  65: }

This code is very similar to the GetDeployment function, but with some major differences. Instead of a GET we have to perform a POST and post what we want to change. The API documentation specifies we need to post an XML that looks like the one from line 14-20. The Configuration node should hold the encoded configuration file we changed earlier. Something very important to note is line 22 where we change the treatWarningAsError boolean into a lower case string. XML is case sensitive and the service is expecting false or true, not False or True. If you fail to lower case it then you will receive an error from the service. We then post the information and check for the Status Code Accepted. Something else to note is that if you upload a configuration file without any modifications you will get a WebException with a Status Code of 400 (Bad Request) with a response body that looks like this:

   1: <Error xmlns="http://schemas.microsoft.com/windowsazure" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
   2:   <Code>BadRequest</Code>
   3:   <Message>No change in settings specified</Message>
   4: </Error>

Please note that this is only sample code and is missing a lot of checks like the one below. It’s only purpose is to demo what steps are needed to scale out or in programmatically in Azure. Feel free to use this code and modified as needed.

Happy programming (and scaling)!

author:  | posted @ Friday, August 10, 2012 12:17 PM | Feedback (1)

Deleting the Windows.old directory after upgrading to Windows 8 Release Preview


With the release of Windows 8 Release Preview comes the necessity to upgrade. If you are running Windows 8 Developer/Consumer Preview it is as easy as running the Setup and upgrading. The setup was pretty fast and very easy to follow, they even cut the steps down from previous version of Windows. After the upgrade you will notice that your free space on your hard drive has diminished by quite a lot. That is probably due to the fact that your old Windows directory has been moved by the setup to C:\Windows.old. You might feel inclined to delete by simply deleting the folder, but you will get Access Denied errors all over the place. I’ve read online a bunch of solutions to get around these type of errors, but they are all too cumbersome.

The easiest and probably supported way is to do so from the Disk Clean up prompt. To do so go to your Computer, right click on C and select properties. From there click on Disk Cleanup.

image

Click on Clean up system files. This will change the options in the “Files to delete:” section and will include “Older version of Windows”. Select that option as well as any other option you wish and press OK. This will get rid of the Windows.old directory without any errors.

Happy testing!

author:  | posted @ Friday, June 01, 2012 1:02 PM | Feedback (17)

AspNetHost deprecated in SignalR 0.5


Now that SignalR 0.5 is out you can scale out using Windows Azure Web Roles and the Service Bus. So if you want to do so you can follow the steps laid out by Clemens Vasters. The problem I had is that I couldn’t find AspNetHost anywhere. After an hour and a half found out that AspNetHost was deprecated in 0.5 in favor of GlobalHost. So

   1: AspNetHost.DependencyResolver.UseWindowsAzureServiceBus(“{namespace}“,”{account}”, “{key}”, "{appname}", 2);

becomes

   1: GlobalHost.DependencyResolver.UseWindowsAzureServiceBus(“{namespace}“,”{account}”, “{key}”, "{appname}", 2);

 

Happy Signaling across multiple nodes!

author:  | posted @ Wednesday, May 09, 2012 1:04 PM | Feedback (0)

Using Windows 8 Tablet as a Hotspot


If you were lucky like me and were at the Microsoft BUILD conference last September then you probably have a Samsung Series 7 Tablet repurposed for the Windows 8 preview. The good thing about that tablet is that it also came with a free 1 year of AT&T 3G. I have since replaced the developer preview with the consumer preview and wasn’t able to find an easy way to share my 3G connection as a hotspot. I remember that used to be very easy in the developer preview, but for some reason it is not in the consumer preview. A little searching online and found this tutorial on how to create a hotspot, but had to do it in different order:

  1. Since there is no keyboard on the tablet, just bring the Charms Barand search for cmd
  2. Swipe down on the only found item and click on Run as administrator
  3. Type:
    • NETSH WLAN SET HOSTEDNETWORK MODE = ALLOW ssid=”NETWORKNAME” key=”YourWpa2Key”
    • NETSH WLAN START HOSTEDNETWORK
  4. Bring the Charms Bar again and search for ncpa.cpl and click on the only result it finds.
  5. You should have the list of network adapters, including the one we just created. Right click (touch and hold) on the 3G one (mine is called Mobile broadband) and click properties
  6. Go to sharing tab and check the “Allow other network users to connect through this computer’s Internet connection”
  7. Select the just created network connection under the “Home networking connection:”. Mine is called Wi-Fi 2.
  8. Hit OK.

Enjoy your free hotspot. I’m on my way to Starbucks to give this a try!

Happy hotspotting!

author:  | posted @ Thursday, May 03, 2012 7:56 PM | Feedback (0)

Join me at the 2012 Orlando Code Camp


Today I will be presenting “An inside look into a successful Windows Phone app” at the Orlando Code Camp. We will take a look at the source code of the famous Champions League Tracker application for Windows Phone 7. We will look into the architecture and implementation of the app: MVVM, WCF Rest, SQL CE, Live Tiles, and Background Tasks.

See you there!

author:  | posted @ Saturday, March 31, 2012 10:32 AM | Feedback (0)

Join me at the Weston Learning Group


Today I will be presenting my famous Programming Web for Beginners at the Weston Learning Group. Programming Web is a combination of Programming Web 101 and 201, two sessions I usually give at Code Camps and user groups across the south east. This session is intended for developers who want to learn the basics of programming for the web. We will start with theory, show some classic ASP and then move on to ASP.NET. If you are just starting programming, learning how to program, or are an experience Windows developer that wants to learn about web programming then you should not miss this session. We will also do some hands on coding with the demos from the presentation, so bring your laptop.

See you there!

author:  | posted @ Wednesday, February 15, 2012 9:50 AM | Feedback (1)