Sync Framework v4 is now Open Source, and ready to Connect any Device to SQL Server and SQL Azure

Sync

Microsoft has brought the power to synchronize data with either SQL Server on-premise or SQL Azure in the cloud to the world of mobility.

The profound effects of the Consumerization of IT (CoIT) is blurring the lines between consumers and the enterprise.  The fact that virtually every type of mobile device is now a candidate to make employees productive means that cross-platform, enabling technologies are a must. If you’ve ever synched the music on your iPhone with iTunes, the calendar on your Android device with Gmail, or the Outlook email on your Windows Phone with Exchange, then you understand the importance of sync.  In my experience architecting and building enterprise mobile apps for the world’s largest organizations over the last decade, data sync has always been a critical ingredient.

The new Sync Framework Toolkit found on MSDN builds on the existing Sync Framework 2.1’s ability to create disconnected applications, making it easier to expose data for synchronization to apps running on any client platform.  Where Sync Framework 2.1 required clients to be based on Windows, this free toolkit allows other Microsoft platforms to be used for offline clients such as Silverlight, Windows Phone 7, Windows Mobile, Windows Embedded Handheld, and new Windows Slates.   Additionally, non-Microsoft platforms such as iPhones, iPads, Android phones and tablets, Blackberries and browsers supporting HTML5 are all first-class sync citizens.  The secret is that we no longer require the installation of the Sync Framework runtime on client devices.  When coupled with use of an open protocol like OData for data transport, no platform or programming language is prevented from synchronizing data with our on-premise and cloud databases.  When the data arrives on your device, you can serialize it as JSON, or insert it into SQL Server Compact or SQLite depending on your platform preferences.

The Sync Framework Toolkit provides all the features enabled by theSync Framework 4.0 October 2010 CTP.  We are releasing the toolkit as source code samples on MSDN with the source code utilizing Sync Framework 2.1.  Source code provides the flexibility to customize or extend the capabilities we have provided to suit your specific requirements. The client-side source code in the package is released under the Apache 2.0 license and the server-side source code under the MS-LPL license.  The Sync Framework 2.1 is fully supported by Microsoft and the mobile-enabling source code is yours to use, build upon, and support for the apps you create.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Now some of you might be wondering why you would use a sync technology to move data rather than SOAP or REST web services.  The reason has to do with performance and bandwidth efficiency.  Using SOA, one would retrieve all the data needed to the device in order to see what has changed in SQL Server.  The same goes for uploading data.  Using the Sync Framework Toolkit, only the changes, or deltas, are transmitted over the air.  The boosts performance and reduces bandwidth usage which saves time and money in a world of congested mobile data networks with capped mobile data plans.  You also get a feature called batching, which breaks up the data sent over wireless networks into manageable pieces.  This not only prevents you from blowing out your limited bandwidth, but it also keeps you from using too much RAM memory both on the server and your memory-constrained mobile device.  When combined with conflict resolution and advanced filtering, I’m sold!

I think you’ll find the Sync Framework Toolkit to be an immensely valuable component of your MEAP solutions for the enterprise as well as the ones you build for consumers.

Keep Synching,

-Rob

Sharing my knowledge and helping others never stops, so connect with me on my blog at http://robtiffany.com , follow me on Twitter at https://twitter.com/RobTiffany and on LinkedIn at https://www.linkedin.com/in/robtiffany

Sign Up for my Newsletter and get a FREE Chapter of “Mobile Strategies for Business!”

[mc4wp_form id=”5975″]

Consumerization of IT Collides with MEAP: Windows Phone > Cloud

In my Consumerization of IT Collides with MEAP article last week, I described how to connect a Windows Phone device to Microsoft’s On-Premise infrastructure.

In this week’s scenario, I’ll use the picture below to illustrate how Windows Phone utilizes many of Gartner’s Mobile Enterprise Application Platform Critical Capabilities to connect to Microsoft’s Cloud services in Azure:

image

As you can see from the picture above:

  1. For the Management Tools Critical Capability, there is no Cloud-based device management solution for Windows Phone.  Targeted and beta software distribution is supported through the Windows Phone Marketplace via Windows Live ID’s and deep links.
  2. For both the Client and Server Integrated Development Environment (IDE) and Multichannel Tool Critical Capability, Windows Phone uses Visual Studio.  The free Windows Phone SDK plugs into Visual Studio and provides developers with everything they need to build mobile applications. It even includes a Windows Phone emulator so developers don’t have to own a phone to develop apps.  On the Cloud side of things, the Windows Azure SDK plugs into Visual Studio and provides developers with everything they need to build Cloud applications. It includes a Cloud emulator to simulate all aspects of Windows Azure on their development computer.
  3. For the cross-platform Application Client Runtime Critical Capability, Windows Phone uses the Silverlight flavor of .NET for thick clients. For thin clients, it uses Internet Explorer 9 to provide HTML5 + CSS3 + ECMAScript5 capabilities. Offline storage is important to keep potentially disconnected mobile clients working and this is facilitated by SQL Server Compact + Isolated Storage for thick clients and Web Storage for thin clients.
  4. For the Security Critical Capability, Windows Phone provides security for 3rd party application data-at-rest via AES 256, data-in-transit via SSL, & Authorization/Authentication via the Windows Azure AppFabric Access Control Service (ACS).
  5. For the Enterprise Application Integration Tools Critical Capability, Windows Phone can reach out to servers directly via Web Services or indirectly through the Cloud via the Windows Azure AppFabric Service Bus to connect to other enterprise packages.
  6. The Multichannel Server Critical Capability to support any open protocol is handled automatically by Windows Azure. Cross-Platform wire protocols riding on top of HTTP are exposed by Windows Communication Foundation (WCF) and include SOAP, REST and Atompub. Cross-Platform data serialization is also provided by WCF including XML, JSON, and OData.  These Multichannel capabilities support thick clients making web service calls as well as thin web clients making Ajax calls. Distributed caching to dramatically boost the performance of any client is provided by Windows Azure AppFabric Caching.
  7. As you might imagine, the Hosting Critical Capability is handled by Windows Azure. Beyond providing the most complete solution of any Cloud provider, Windows Azure Connect provides an IPSec-protected connection with your On-Premises network and SQL Azure Data Sync can be used to move data between SQL Server and SQL Azure. This gives you the Hybrid Cloud solution you might be looking for.
  8. For the Packaged Mobile Apps or Components Critical Capability, Windows Phone runs cross-platform mobile apps include Office/Lync/IE/Outlook/Bing.

As you can see, Windows Phone meets many of Gartner’s Critical Capabilities, but is missing cloud-based device management and isn’t as strong as Windows 7 in areas of full-device security.

Next week, I’ll cover how Windows Embedded Handheld (Windows Mobile 6.5.3) connects to an On-Premises Microsoft infrastructure.

Best Regards,

Rob

Sharing my knowledge and helping others never stops, so connect with me on my blog at http://robtiffany.com , follow me on Twitter at https://twitter.com/RobTiffany and on LinkedIn at https://www.linkedin.com/in/robtiffany

Sign Up for my Newsletter and get a FREE Chapter of “Mobile Strategies for Business!”

[mc4wp_form id=”5975″]

Consumerization of IT Collides with MEAP: Windows Phone > On Premise

In my Consumerization of IT Collides with MEAP article last week, I described how to connect a Windows 7 device to Microsoft’s Cloud servers in Azure.

In this week’s scenario, I’ll use the picture below to illustrate how Windows Phone utilizes many of Gartner’s Critical Capabilities to connect to Microsoft’s On-Premise infrastructure:

As you can see from the picture above:

  1. For the Management Tools Critical Capability, Windows Phone uses Microsoft Exchange for On-Premise policy enforcement but has no private software distribution equivalent to System Center Configuration Manager 2007.  Targeted and beta software distribution is supported through the Windows Phone Marketplace via Windows Live ID’s and deep links.
  2. For both the Client and Server Integrated Development Environment (IDE) and Multichannel Tool Critical Capability, Windows Phone uses Visual Studio. The free Windows Phone SDK plugs into Visual Studio and provides developers with everything they need to build mobile applications.  It even includes a Windows Phone emulator so developers don’t have to own a phone to develop apps.
  3. For the cross-platform Application Client Runtime Critical Capability, Windows Phone uses the Silverlight flavor of .NET for thick clients. For thin clients, it uses Internet Explorer 9 to provide HTML5 + CSS3 + ECMAScript5 capabilities. Offline storage is important to keep potentially disconnected mobile clients working and this is facilitated by SQL Server Compact + Isolated Storage for thick clients and Web Storage for thin clients.
  4. For the Security Critical Capability, Windows Phone provides security for 3rd party application data-at-rest via AES 256, data-in-transit via SSL, & Authorization/Authentication via Active Directory.  Full device encryption or encryption of PIM/Email data is not supported.
  5. For the Enterprise Application Integration Tools Critical Capability, Windows Phone can reach out to servers directly via Web Services or indirectly via SQL Server or BizTalk using SSIS/Adapters to connect to other enterprise packages.
  6. The Multichannel Server Critical Capability to support any open protocol directly, via Reverse Proxy, or VPN is facilitated by ISA/TMG/UAG/IIS.  Crosss-Platform wire protocols riding on top of HTTP are exposed by Windows Communication Foundation (WCF) and include SOAP, REST and Atompub. Cross-Platform data serialization is also provided by WCF including XML, JSON, and OData.  These Multichannel capabilities support thick clients making web service calls as well as thin web clients making Ajax calls.  Distributed caching to dramatically boost the performance of any client is provided by Windows Server AppFabric Caching.
  7. While the Hosting Critical Capability may not be as relevant in an on-premises scenario, Windows Azure Connect provides an IPSec-protected connection to the Cloud and SQL Azure Data Sync can be used to move data between SQL Server and SQL Azure.
  8. For the Packaged Mobile Apps or Components Critical Capability, Windows Phone runs cross-platform mobile apps include Office/Lync/IE/Outlook/Bing.

As you can see, Windows Phone meets many of Gartner’s Critical Capabilities, but isn’t as strong as Windows 7 in areas of full-device security and device management.

Next week, I’ll cover how Windows Phone connects to the Cloud.

Rob

Sharing my knowledge and helping others never stops, so connect with me on my blog at http://robtiffany.com , follow me on Twitter at https://twitter.com/RobTiffany and on LinkedIn at https://www.linkedin.com/in/robtiffany

Sign Up for my Newsletter and get a FREE Chapter of “Mobile Strategies for Business!”

[mc4wp_form id=”5975″]

Windows Phone 7 Line of Business App Dev :: Uploading Data back to Azure

Submarine

Looking back over the last 6 months of this series of articles, you’ve created wireless-efficient WCF REST + JSON Web Services in Azure to download data from SQL Azure tables to Windows Phone.

You’ve maintained in-memory collections of objects in your own local NoSQL object cache.  You’ve used LINQ to query those collections and bind results to various Silverlight UI elements.  You’ve even serialized those collections to Isolated Storage using memory-efficient JSON.  So what’s left to do?
Oh yeah, I guess you might want to know how to upload an object full to data back to a WCF Web Service in Azure.  In order to keep this article simple and to-the-point, I’m going to work with a basic Submarine object and show you how to fill it with data and upload it from a Windows Phone or Slate to a WCF REST + JSON Web Service.  Let’s take a look at this object:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.Serialization;
namespace Models
{
[DataContract()]
public class Submarine
{
[DataMember()]
public int Id { get; set; }
[DataMember()]
public string Name { get; set; }
}
}
It includes just an integer data type called Id, and a string called Name.  As in previous articles before, its decorated with a [DataContract()] and two [DataMember()]s to allow .NET serialization to do its thing.  So the next thing we need to do is create and populate this Submarine object with data, serialize it as JSON, and send it on its way using WebClient.
Below is the method and its callback that accomplishes this:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using Microsoft.Phone.Controls;
using System.IO;
using System.Runtime.Serialization.Json;
using System.Text;
private void AddSubmarine()
{
Uri uri = new Uri(“
http://127.0.0.1:81/SubService.svc/AddSubmarine”);
Models.Submarine submarine = new Models.Submarine() { Id = 3, Name = “Seawolf” };
DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(Models.Submarine));
MemoryStream mem = new MemoryStream();
ser.WriteObject(mem, submarine);
string data = Encoding.UTF8.GetString(mem.ToArray(), 0, (int)mem.Length);
WebClient webClient = new WebClient();
webClient.UploadStringCompleted += new UploadStringCompletedEventHandler(webClient _UploadStringCompleted);
webClient.Headers[“Content-type”] = “application/json”;
webClient.Encoding = Encoding.UTF8;
webClient.UploadStringAsync(uri, “POST”, data);
}
void webClient_UploadStringCompleted(object sender, UploadStringCompletedEventArgs e)
{
var x = e.Result;
}
As you can see above, I point the URI at a WCF Service called SubService.svc/AddSubmarine.  How RESTful.  Next, I create an instance of the Submarine object, give it an Id of 3 and the Name Seawolf.  I then use the same DataContractJsonSerializer I’ve been using in all the other articles to serialize the Submarine object to a JSON representation.  Using the MemoryStream, I write the JSON to a stream and then artfully turn it into a string.  Last but not least, I instantiate a new WebClient object, create an event handler for a callback, and upload the stringified Submarine object to the WCF Service.
So where did I upload the Submarine object to?
It takes two to Mango, so let’s take a look.  For starters, it goes without saying that every WCF Service starts with an Interface.  This one is called ISubService.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Text;
namespace DataSync
{
[ServiceContract]
public interface ISubService
{
[OperationContract]
[WebInvoke(UriTemplate = “/AddSubmarine”, BodyStyle = WebMessageBodyStyle.Bare, RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json, Method = “POST”)]
bool AddSubmarine(Models.Submarine sub);
}
}
Unlike previous articles where I had you download data with WebGet, this time I’m using WebInvoke to denote that a PUT, POST, or DELETE HTTP Verb is being used with our REST service.  The UriTemplate gives you the RESTful /AddSubmarine, and I added the Method = “POST” for good measure.  Keep in mind that you’ll need the exact same Submarine class on the server that you had on your Windows Phone to make all this work.
Let’s see what we get when we Implement this Interface:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Text;
using Microsoft.WindowsAzure;
using Microsoft.WindowsAzure.Diagnostics;
using Microsoft.WindowsAzure.ServiceRuntime;
using Microsoft.WindowsAzure.StorageClient;
using System.Configuration;
using System.Xml.Serialization;
using System.IO;
namespace DataSync
{
public class SubService : ISubService
{
public SubService()
{

 

}

 

public bool AddSubmarine(Models.Submarine submarine)
{
try
{
if (submarine != null)
{
//Do something with your Deserialized .NET Submarine Object
//… = submarine.Id
//… = submarine.Name
return true;
}
else
{
return false;
}
}
catch
{
return false;
}
}
}
}
Here we end up with SubService.svc with the simple AddSubmarine method where you pass in a Submarine object as a parameter.  What you do with this object, I’ll leave to you.  Some might be tempted to INSERT it into SQL Azure.  I’d prefer that you drop it into an Azure Queue and have a Worker Role do the INSERTing later so you can stay loosely-coupled.  Just in case you need a refresher on a REST-based Web.config file, here’s one below:
<?xml version=”1.0″?>
<configuration>
<!–  To collect diagnostic traces, uncomment the section below.
To persist the traces to storage, update the DiagnosticsConnectionString setting with your storage credentials.
To avoid performance degradation, remember to disable tracing on production deployments.
<system.diagnostics>
<sharedListeners>
<add name=”AzureLocalStorage” type=”DataSync.AzureLocalStorageTraceListener, DataSync”/>
</sharedListeners>
<sources>
<source name=”System.ServiceModel” switchValue=”Verbose, ActivityTracing”>
<listeners>
<add name=”AzureLocalStorage”/>
</listeners>
</source>
<source name=”System.ServiceModel.MessageLogging” switchValue=”Verbose”>
<listeners>
<add name=”AzureLocalStorage”/>
</listeners>
</source>
</sources>
</system.diagnostics> –>
<system.diagnostics>
<trace>
<listeners>
<add type=”Microsoft.WindowsAzure.Diagnostics.DiagnosticMonitorTraceListener, Microsoft.WindowsAzure.Diagnostics, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35″
name=”AzureDiagnostics”>
<filter type=”” />
</add>
</listeners>
</trace>
</system.diagnostics>
<system.web>
<compilation debug=”true” targetFramework=”4.0″ />
</system.web>
<!–Add Connection Strings–>
<connectionStrings>

 

</connectionStrings>

 

<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior>
<!– To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment –>
<serviceMetadata httpGetEnabled=”true”/>
<!– To receive exception details in faults for debugging purposes, set the value below to true.  Set to false before deployment to avoid disclosing exception information –>
<serviceDebug includeExceptionDetailInFaults=”false”/>
</behavior>
</serviceBehaviors>
<!–Add REST Endpoint Behavior–>
<endpointBehaviors>
<behavior name=”REST”>
<webHttp />
</behavior>
</endpointBehaviors>
</behaviors>
<!–Add Service with webHttpBinding–>
<services>
<service name=”DataSync.SubService”>
<endpoint address=”” behaviorConfiguration=”REST” binding=”webHttpBinding”
contract=”DataSync.ISubService” />
</service>
</services>
<serviceHostingEnvironment aspNetCompatibilityEnabled=”true” multipleSiteBindingsEnabled=”true” />
<!–<serviceHostingEnvironment multipleSiteBindingsEnabled=”true” />–>
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests=”true”/>
</system.webServer>
</configuration>
This Web.Config gives you the webHttpBinding you’re looking for to do a REST service.  I even left you a spot to add your own database or Azure storage connection strings.
This article wraps up the Windows Phone 7 Line of Business App Dev series that I’ve been delivering to you since last September.  Who knew I would make fun of OData or have you create your own NoSQL database to run on your phone along the way?  I think I actually wrote the first article in this series from a hotel room in Nantes, France.
But have no fear, this isn’t the end.
In preparation for Tech Ed 2010 North America coming up on May 16th in Atlanta, I’ve been building the next-gen, super-fast, super-scalable Azure architecture designed for mobile devices roaming on wireless data networks.  I’ve spent the last decade building the world’s largest and most scalable mobile infrastructures for Microsoft’s wonderful global customers.  Now it’s time to make the jump from supporting enterprise-level scalability to the much bigger consumer-level scalability.
Yes, I’m talking millions of devices.
No, you won’t have to recreate Facebook’s servers, NoSQL, Memcache, or Hadoop infrastructure to make it happen.  I’m going to show you how to make it happen with Azure in just two weeks so I’m looking forward to seeing everyone in Atlanta in two weeks.
Keep coding,
Rob

 

Sharing my knowledge and helping others never stops, so connect with me on my blog at http://robtiffany.com , follow me on Twitter at https://twitter.com/RobTiffany and on LinkedIn at https://www.linkedin.com/in/robtiffany

Sign Up for my Newsletter and get a FREE Chapter of “Mobile Strategies for Business!”

[mc4wp_form id=”5975″]

Confronting the Consumerization of IT with Microsoft MEAP

Microsoft MEAP

CIOs are asking for help in confronting the tidal wave of mobile devices entering the enterprise and IT departments have raised the white flag as attempts to block consumer-focused smartphones and tablets have failed.

The Consumerization of IT has been a growing trend fueled by cloud-delivered services and compelling mobile devices with wireless capabilities.  This trend snowballs more and more each year, meaning it’s time to embrace it rather than put your head in the sand.  Microsoft MEAP is the answer.  I’ve been talking to you about how Microsoft aligns with Gartner’s Mobile Enterprise Application Platform (MEAP) for years now, and I wanted to update you on how we’ve evolved with respect to Gartner’s Critical Capabilities.  As a refresher, MEAP is Software + Services that allow IT orgs to extend corporate apps to mobile employees and business partners.  This platform must support:

  1. Multiple mobile applications
  2. Multiple mobile operating systems
  3. Multiple backend systems maximizing ROI vs. tactical solutions

It’s already a $1 Billion business and 95% of orgs will choose MEAP over point solutions by 2012.   The picture below represents some of our familiar cloud and on-premise servers on top and a wide spectrum of mobile devices from Microsoft and other manufacturers on the bottom:

Microsoft MEAP

Let’s do a quick rundown of Gartner’s Critical Capability list so you can see how we rise to their challenge:

  1. Integrated Development Environment for composing server and client-side logic: Microsoft Visual Studio supports on-premise and cloud server development and targets clients such as Windows, Windows Phone 7, Windows Mobile, the Web, Nokia S60, and the Macintosh.
  2. Application Client Runtime: Various flavors of Microsoft .NET (Silverlight, .NET, Compact Framework) run on Azure, Windows Server, Windows, the Mac, Windows Phone 7, Windows Mobile, and Nokia S60.  Guess what, you can use MonoTouch to take your .NET skills to the iPhone, iPad and iPod Touch.  MonoDroid is in the preview stage and will bring .NET to Android phones and tablets in the future.
  3. Enterprise Application Integration Tools: Connecting mobile devices to a variety of backend packages like Dynamics or SAP is critical.  Microsoft supports this integration in the cloud via Windows Azure AppFabric and on-premise though SQL Server Integration Services and dozens of adapters.  Tools like our Business Intelligence Dev Studio make EAI a repeatable, drag and drop exercise.
  4. Packaged Mobile Apps: Microsoft delivers the Office suite across Windows, Windows Phone 7, Windows Mobile, the Web and the Mac.  Office will be coming to Nokia in the future and One Note just arrived on iOS.
  5. Multichannel Servers: Windows Server + SQL Server on-premise and Windows Azure + SQL Azure in the cloud represents Microsoft’s mobile middleware platforms.  Windows Communication Foundation (WCF) delivers cross-platform SOAP & REST Web Services and cross-platform wire protocols like XML, JSON and OData.
  6. Software Distribution: Microsoft System Center Configuration Manager supports pushing software out to Windows and Windows Mobile.  Windows Phone 7 has Marketplace for this function.
  7. Security: Data-in-transit is secured by SSL across all platforms.  Data-at-Rest security for apps is facilitated on Windows by BitLocker, Windows Mobile through encryption policies and Windows Phone 7 through AESManaged in Silverlight.  Cross-platform auth is facilitated by Microsoft Windows Identity Foundation so devices can access resources via a Windows Live ID, Facebook, Google, Yahoo, ADFS and others.
  8. Hosting: It goes without saying the Microsoft knocks the hosting requirement out of the park with Azure.

So what do I want you to take away from all this?

Microsoft has a great MEAP stack comprised of servers and skillsets you probably already have at your company.  You get maximum reuse on our servers and in our cloud which means you save money when it’s time to build and deploy your second, third and fourth mobile app without new training, new servers, and different technologies each time.  I hope you’re pleasantly surprised to see that our .NET application runtime lives on so many mobile platforms.  Again, this means that your existing .NET skills can be reused on Microsoft devices, the Web, Mac, Nokia and even the iPad.  Who knew?  I’m looking forward to bring Android into the .NET camp as well.

It’s a brave new world of disparate devices connected to the cloud.  Companies have no choice but to target most all of them when constructing B2C apps to sell products or bring in new customers.  They’ve also found that this is the case in supporting their own employees and business partners with B2E and B2B apps.  No single company has so many different skillsets and competencies to pull this off.

There is one thing that most companies do have though.  A Microsoft infrastructure in their data center or the cloud, Windows on desktops, laptops and tablets, plus teams of .NET developers.  As I’ve just shown you, these .NET developers armed with Visual Studio or MonoTouch can be unleashed to allow you to reach almost every mobile platform.  This dramatically reduces the amount of extra Java and Eclipse skills that you’ll consider bringing in-house or outsourcing in order to target platforms like Android or the Blackberry.  Through the magic of WCF, all these platforms can connect to your critical Microsoft back-end resources and beyond.  You save money on training, use the servers you already have, resuse business logic and get to market faster.  No matter what platform you need to target, Microsoft and its partners want to help you reach your goals.

Looks like you’re already ahead of the game in taking on the Consumerization of IT.

-Rob

Sharing my knowledge and helping others never stops, so connect with me on my blog at http://robtiffany.com , follow me on Twitter at https://twitter.com/RobTiffany and on LinkedIn at https://www.linkedin.com/in/robtiffany

Sign Up for my Newsletter and get a FREE Chapter of “Mobile Strategies for Business!”

[mc4wp_form id=”5975″]

Reducing SQL Server I/O Contention during Sync :: Tip 2

Database Storage
Indexing Join Columns

In my last Sync/Contention post, I beat up on a select group of SAN administrators who aren’t willing to go the extra mile to optimize the very heart of their organization, SQL Server.  You guys know who you are.

This time, I want to look at something more basic, yet often overlooked.

All DBAs know that Joining tables on non-indexed columns is the most expensive operation SQL Server can perform.  Amazingly, I run into this problem over and over with many of my customers.  Sync technologies like the Sync Framework, RDA and Merge Replication allow for varying levels of server-side filtering.  This is a popular feature used to reduce the size of the tables and rows being downloaded to Silverlight Isolated Storage or SQL Server Compact.

It’s also a performance killer when tables and columns participating in a Join filter are not properly indexed.  Keeping rows locked longer than necessary creates undue blocking and deadlocking.  It also creates unhappy slate and smartphone users who have to wait longer for their sync to complete.

Do yourselft a favor and go take a look at all the filters you’ve created and makes sure that you have indexes on all those Joined columns.

Keep synching,

Rob

Sharing my knowledge and helping others never stops, so connect with me on my blog at http://robtiffany.com , follow me on Twitter at https://twitter.com/RobTiffany and on LinkedIn at https://www.linkedin.com/in/robtiffany

Sign Up for my Newsletter and get a FREE Chapter of “Mobile Strategies for Business!”

[mc4wp_form id=”5975″]

Reducing SQL Server I/O Contention during Sync :: Tip 1

SAN Storage
RAID

Sync technologies like Merge Replication and the Sync Framework track changes on SQL Server using triggers, stored procedures and special tracking tables.  The act of tracking changes made by each SQL Server Compact or Silverlight sync subscriber can cause a lot of locking and blocking on the server.  This diminishes performance and sometimes leads to deadlocks. SAN Storage

Therefore, don’t listen to your SAN administrator when he says the RAID 5 will do.  RAID 1 or 10 must always be used for all databases, tempdb, and transaction logs.  Furthermore, each of these database objects must be placed on their own dedicated RAID arrays.  No sharing!  Remembers, as a DBA and sync expert, knowledge of SAN configuration must always be part of your skillset.

Keeping synching,

Rob

Sharing my knowledge and helping others never stops, so connect with me on my blog at http://robtiffany.com , follow me on Twitter at https://twitter.com/RobTiffany and on LinkedIn at https://www.linkedin.com/in/robtiffany

Sign Up for my Newsletter and get a FREE Chapter of “Mobile Strategies for Business!”

[mc4wp_form id=”5975″]

Windows Phone 7 Line of Business App Dev :: Improving the In-Memory Database

Phone 7

About a month ago, I wrote an article intended to help you fill some of the gaps left by the missing SQL Server Compact database.

Since your Windows Phone 7 Silverlight app is consuming an ObservableCollection of objects streaming down from Windows Azure and SQL Azure, it makes sense to organize those objects in a database-like format that’s easy to work with.  If you’ve ever worked with Remote Data Access (RDA) in the past, the notion of pre-fetching multiple tables to work with locally should look familiar.

In this case, each ObservableCollection represents a table, each object represents a row, and each object property represents a column.  I had you create a Singleton class to hold all these objects in memory to serve as the database.  The fact that Silverlight supports Language Integrated Query (LINQ) means that you can use SQL-like statements to work with the multiple, ObservableCollections of objects.

If you’re wondering why I have you cache everything in memory in a Singleton, there’s a few reasons.  For starters, it makes it easy to query everything with LINQ with the fastest performance possible for single and multi-table JOINs.  Secondly, I don’t represent a Microsoft product group and therefore wouldn’t engineer an unsupported provider that can query subsets of serialized data from files residing in Isolated Storage.  Finally, I don’t want you to accidentally find yourself with multiple instances of the same ObservableCollection when pulling data down from Azure or loading it from Isolated Storage.  Forcing everything into a Singleton prevents you wasting memory or updating objects in the wrong instance of an ObservableCollection.  An inconsistent database is not a good thing.  Don’t worry, you can control which tables are loaded into memory.

So what is this article all about and what are the “improvements” I’m talking about?

This time around, I’m going to focus on saving, loading and deleting the serialized ObservableCollections from Isolated Storage.  In that last article, I showed you how to serialize/de-serialize the ObservableCollections to and from Isolated Storage using the XmlSerializer.  This made it easy for you to save each table to its own XML file which sounds pretty cool.

So what’s wrong with this?

Saving anything as XML means that you’re using the largest, most verbose form of serialization.  After hearing me preach about the virtues of doing SOA with WCF REST + JSON, using the XmlSerializer probably seems out of place.  Luckily, the DataContractJsonSerializer supported by Silverlight on Windows Phone 7 gives you the most efficient wire protocol for data-in-transit can also be used to save those same .NET objects to Isolated Storage.  So the first improvement in this article comes from shrinking the size of the tables and improving the efficiency of the serialization/de-serializing operations to Isolated Storage using out-of-the-box functionality.

While going from XML to JSON for your serializing might be good enough, there’s another improvement in the way you write the code that will make this much easier to implement for your own projects.  A look back to the previous article reveals a tight coupling between the tables that needed to be saved/loaded and the code needed to make that happen.  This meant that you would have to create a SaveTable and LoadTable method for each table that you wanted to retrieve from Azure.  The new code you’re about to see is generic and allows you to use a single SaveTable and LoadTable method even if you decide to download 100 tables.

Enough talk already, let’s see some code.  Launch your ContosoCloud solution in Visual Studio and open Database.cs.  I want you to overwrite the existing code with the code shown below:

using System;
using System.Net;
using System.Windows;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO.IsolatedStorage;
using System.Runtime.Serialization.Json;

namespace ContosoPhone
{
sealed class Database
{
//Declare Instance
private static readonly Database instance = new Database();

        //Private Constructor
private Database() { }

        //The entry point into this Database
public static Database Instance
{
get
{
return instance;
}
}

        //Serialize ObservableCollection to JSON in Isolated Storage
public void SaveTable<T>(T tableToSave, string tableName)
{
if (tableToSave != null)
{
using (IsolatedStorageFile store = IsolatedStorageFile.GetUserStoreForApplication())
{
using (IsolatedStorageFileStream stream = store.CreateFile(tableName + “.txt”))
{
DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(T));
serializer.WriteObject(stream, tableToSave);
}
}
}
else
{
throw new Exception(“Table is empty”);
}
}

        //Deserialize ObservableCollection from JSON in Isolated Storage
public T LoadTable<T>(T tableToLoad, string tableName)
{
using (IsolatedStorageFile store = IsolatedStorageFile.GetUserStoreForApplication())
{
if (store.FileExists(tableName + “.txt”))
{
using (IsolatedStorageFileStream stream = store.OpenFile(tableName + “.txt”, System.IO.FileMode.Open))
{
DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(T));
return (T)serializer.ReadObject(stream);
}
}
else
{
throw new Exception(“Table not found”);
}
}
}

        //Delete ObservableCollection from Isolated Storage
public void DropTable(string tableName)
{
using (IsolatedStorageFile store = IsolatedStorageFile.GetUserStoreForApplication())
{
if (store.FileExists(tableName + “.txt”))
{
store.DeleteFile(tableName + “.txt”);
}
else
{
throw new Exception(“Table not found”);
}
}
}


//Declare Private Table Variables
private ObservableCollection<Customer> customerTable = null;

        //Customer Table
public ObservableCollection<Customer> Customers
{
get { return customerTable; }
set { customerTable = value; }
}
}
}

 

Looking from top to bottom, the first change you’ll notice is the new SaveTable method where you pass in the desired ObservableCollection and table name in order to serialize it as JSON using the DataContractJsonSerializer.  The next method down the list is LoadTable where you pass in the same parameters as SaveTable but you get back a de-serialized ObservableCollection.  The last new method in the Database Singleton is DropTable which simply deletes the serialized table from Isolated Storage if you don’t need it anymore.

So how do you call this code?

Bring up MainPage.xaml.cs, and find the click event for Save button.  Delete the existing XmlSerializer code and replace it with the following:

try
{
Database.Instance.SaveTable<ObservableCollection<Customer>>(Database.Instance.Customers, “Customers”);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}

The code above shows you how to call the SaveTable method in the Singleton with the appropriate syntax to pass in the ObservableCollection type as well as actual ObservableCollection value and name.

Now find the click event for the Load button, delete the existing code and paste in the following:

try
{
Database.Instance.Customers = Database.Instance.LoadTable<ObservableCollection<Customer>>(Database.Instance.Customers, “Customers”);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}

This code looks pretty much the same as the SaveTable code except that you set Database.Instance.Customers equal to the return value from the method.  For completeness sake, drop another button on MainPage.xaml and call it Drop.  In its click event, paste in the following code:

try
{
Database.Instance.DropTable(“Customers”);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}

For this code, just pass in the name of the table you want to delete from Isolated Storage and it’s gone.

It’s time to hit F5 so you can see how things behave.

phone7

When your app comes to life in the emulator, I want you to exercise the system by Getting, Adding, Updating and Deleting Customers.  In between, I want you to tap the Save button, close the app, reload the app and tap the Load button and then View Customers to ensure you’re seeing the list of Customers you expect.  Keep in mind that when you Save, you overwrite the previously saved table.  Likewise, when you Load, you overwrite the current in-memory ObservableCollection.  Additionally, Saving, Loading, and Dropping tables that don’t exist should throw an appropriate error message.

So what’s the big takeaway for these tweaks I’ve made to the in-memory database?

While switching serialization from XML to JSON is a great improvement in size and efficiency, I truly believe that making the SaveTable and LoadTable methods generic and reusable will boost developer productivity.  The new ease with which you can Save and Load 1, 10 or even 1,000 tables makes this more attractive to mobile developers that need to work with local data.

So where do we go from here?

You now have some of the basic elements of a database on Windows Phone 7.  You don’t have ACID support, indexes, stored procedures or triggers but you have a foundation to build on.  So what should be built next?

To help ensure database consistency, I would add an AutoFlush feature next.  SQL Server Compact flushes its data to disk every 10 seconds and there’s nothing to prevent you from using the SaveTable method to do the same.  A timer set to fire at a user-specified interval that iterates through all the ObservableCollections and saves them will help keep your data safe from battery loss and unforeseen system failures.  The fact that your app can be tombstoned at any moment when a user taps the Back button makes an AutoFlush feature even more important.

Anything else?

At the beginning of this article I mentioned RDA which is a simple form of data synchronization.  It’s simple because it only tracks changes on the client but not the server.  To find out what’s new or changed on the server, RDA requires local tables on the device to be dropped and then re-downloaded from SQL Server.  With the system I’ve built and described throughout this series of articles, we already have this brute force functionality.  So what’s missing is client-side change tracking.  To do this, I would need to add code that fires during INSERTS, UPDATES, and DELETES and then writes the appropriate information to local tracking tables.  To push those changes back to SQL Azure, appropriate code would need to call WCF REST + JSON Services that execute DML code on Windows Azure.

I hope with the improvements I’ve made to the in-memory database in this article, you’ll feel even more empowered to build occasionally-connected Windows Phone 7 solutions for consumers and the enterprise.

Keep coding!

-Rob

Sharing my knowledge and helping others never stops, so connect with me on my blog at http://robtiffany.com , follow me on Twitter at https://twitter.com/RobTiffany and on LinkedIn at https://www.linkedin.com/in/robtiffany

Sign Up for my Newsletter and get a FREE Chapter of “Mobile Strategies for Business!”

[mc4wp_form id=”5975″]

Windows Phone 7 Line of Business App Dev :: Network Awareness

Phone 6

By now, you’ve heard me talk a lot about the role wireless data networks play when it comes to the success of your mobile application.

They are unreliable, intermittent, highly latent and often slower than they should be due to overtaxed cellular towers and congested backhaul networks.  Hopefully, you’ve built an app that tackles those challenges head-on using efficient WCF REST + JSON Services coupled with an offline data store.

So what is the user of your new application going to think when a Web Service call fails because the network is unavailable?

An end-user of your app probably won’t be too thrilled when they’re staring at an unintelligible error message.  Or maybe your app will just silently fail when the Web Service call doesn’t succeed.  The user might not know there’s a problem until they can’t view a list of relevant data on their phone.

This is no way to treat your prospective user-base because mobile apps should never diminish the user experience by trying to send or receive data in the absence of network connectivity.

Luckily, Silverlight on Windows Phone 7 provides you with a way to determine network connectivity.

Launch Visual Studio 2010 and load the ContosoCloud solution that we’ve been working with over the last four Windows Phone 7 Line of Business App Dev articles.  First, I want you to drag an Ellipse from the Toolbox and drop it on MainPage.xaml.  Name that control ellipseNet.  Next, I want you to drag a TextBlock control over and drop it beneath the Ellipse.  Name this control textBlockNet.  Now open MainPage.xaml.cs so we can write some code.

Above the ContosoPhone namespace I want you to add:

using Microsoft.Phone.Net.NetworkInformation;

This allows you to tap into the NetworkInterface class.  The next line of code I want you to add may seem a little confusing since it’s similar, yet different from Microsoft.Phone.Net.NetworkInformation.  Inside the MainPage() constructor, beneath InitializeComponent();, add the following code to create an event handler:

System.Net.NetworkInformation.NetworkChange.NetworkAddressChanged += new System.Net.NetworkInformation.NetworkAddressChangedEventHandler(NetworkChange_NetworkAddressChanged);

This is the standard, cross-platform Silverlight way to create an event handler that tells you when your network address has changed.  I wrote it out the long-way because it collides with the phone-specific NetworkInformation class.  Don’t ask.

Underneath the line of code above, add the following:

NetworkStateMachine();

This is going to call a method you haven’t created yet.

Inside your MainPage class, the event handler your just created will appear:

void NetworkChange_NetworkAddressChanged(object sender, EventArgs e)
{
NetworkStateMachine();
}

As you can see, I want you to add the NetworkStateMachine(); line of code inside the event handler to execute this mysterious function.  By now you’re probably saying, “Enough of the suspense already!”  Below the event handler, paste in the following code:

private void NetworkStateMachine()
{
try
{
switch (NetworkInterface.NetworkInterfaceType)
{
//No Network
case NetworkInterfaceType.None:
ellipseNet.Fill = new SolidColorBrush(Colors.Red);
textBlockNet.Text = “No Network”;
break;
//CDMA Network
case NetworkInterfaceType.MobileBroadbandCdma:
ellipseNet.Fill = new SolidColorBrush(Colors.Blue);
textBlockNet.Text = “CDMA”;
break;
//GSM Network
case NetworkInterfaceType.MobileBroadbandGsm:
ellipseNet.Fill = new SolidColorBrush(Colors.Blue);
textBlockNet.Text = “GSM”;
break;
//Wi-Fi Network
case NetworkInterfaceType.Wireless80211:
ellipseNet.Fill = new SolidColorBrush(Colors.Green);
textBlockNet.Text = “Wi-Fi”;
break;
//Ethernet Network
case NetworkInterfaceType.Ethernet:
ellipseNet.Fill = new SolidColorBrush(Colors.Green);
textBlockNet.Text = “Ethernet”;
break;
//No Network
default:
ellipseNet.Fill = new SolidColorBrush(Colors.Red);
textBlockNet.Text = “No Network”;
break;
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}

The switch statement above creates a state machine for your mobile application that lets it know what type of network connection you have at any given moment.  Remember for this example, the sample code is running on the UI thread.  Since the code is synchronous and blocking, you may want to run it on a background thread.

As you can see, the following network types are returned:

  • Wireless80211  (Wi-Fi)
  • Ethernet  (Docked/LAN)
  • MobileBroadbandGSM  (GPRS/EDGE/UMTS/HSDPA/HSPA)
  • MobileBroadbandCDMA  (1xRTT/EV-DO)
  • None

As you’re probably thinking, the primary value in this is to know if you have any kind of network or not.  Obviously, a return value of None means you shouldn’t make any kind of Web Service call.

Hit F5 in Visual Studio and let’s see what you get in the emulator:

phone6

As you can see, the ContosoCloud app detected my laptop’s Wi-Fi connection in the switch statement and therefore gave me a Green Ellipse and a TextBlock that says “Wi-Fi.”  Keep in mind that the emulator doesn’t behave the same way as an actual phone so changing my laptop’s networking while the mobile app is running won’t trigger the NetworkChange_NetworkAddressChanged event handler.  If you close the app, turn off Wi-Fi on your laptop and then restart the app, it will correctly report that no network is available.

So why would you want to know about all the other network return types?

In working with customers all around the world who use Pocket PCs, Windows Mobile devices and Windows Phones, it has become evident that there is always a “cost” in doing anything over the network.  Not everyone has unlimited, “all-you-can-eat” data plans for their employees.  Some companies have very low monthly data usage limits for each employee that has been negotiated with one or more mobile operators.  For these organizations, it’s not enough to know if the network is present or not.  They need to know what kind of network is available so their mobile application can make intelligent decisions.

If I need to download a large amount of data in the morning to allow me to drive my delivery truck route, I probably should only perform this operation over docked Ethernet or Wi-Fi.  This gives me the network speed I need to move a lot of data and I don’t incur any costs with my mobile operator.

If I’ve captured small amounts of data in the field that I need to send back to HQ in near real-time, then a return value of MobileBroadbandGSM  or MobileBroadbandCDMA is perfect.  This would also be appropriate if my app is making lightweight remote method calls via Web Services as well.  The use of WCF REST + JSON is probably making a lot of sense now.

If I’ve captured large amounts of data in the field or I’m batching up several data captures throughout the day, it would make more sense to use Ethernet or Wi-Fi when I returned to the warehouse or distribution center.  On the other hand, if I have a high enough data usage limit or no limit at all, the MobileBroadbandGSM/CDMA would be fine.

Keep in mind that this guidance is just as valuable for B2C and Consumer apps as well.  If you’re building a connected mobile app of any kind, the information I’ve discussed in this article will ensure that you’re always providing a great user experience.

Delighting the end-user is what it’s all about!

-Rob

Sharing my knowledge and helping others never stops, so connect with me on my blog at http://robtiffany.com , follow me on Twitter at https://twitter.com/RobTiffany and on LinkedIn at https://www.linkedin.com/in/robtiffany

Sign Up for my Newsletter and get a FREE Chapter of “Mobile Strategies for Business!”

[mc4wp_form id=”5975″]

Windows Phone 7 Line of Business App Dev :: Working with an In-Memory Database

Phone3

In my last article of this series, you finally got to consume wireless-friendly WCF REST + JSON Services from both Windows Server and Windows Azure with data coming from SQL Server/SQL Azure.

You now have an ObservableCollection of Customer objects residing in a Singleton on your Windows Phone 7 device.  This Singleton looks similar to an in-memory database and the Customers property works like a table.

So now what?

If you’re like me, you probably want to display the list of Customers in the UI.  You might also want to perform other local operations against this data store.  You could add a new Customer and update or even delete an existing one.

I’m going to apologize in advance for not doing the MVVM thing that everyone seems to be into these days and get right to the point. Drag a button on to MainPage.xaml and call it View Customers.  While you’re at it, drag a listbox below the button and name it listBoxCustomers.  Double-click on this Button and add the following code to the click event:

try
{
if (Database.Instance.Customers != null)
{
listBoxCustomers.DisplayMemberPath = “Name”;
listBoxCustomers.ItemsSource = Database.Instance.Customers;
}
else
{
MessageBox.Show(“The Customer Table is Empty”);
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}

In the simple code above, you set the listbox’s ItemsSource equal to the Customer collection in the Database Singleton and set the DisplayMemberPath property equal to the Name property of the Customer objects.

Hit F5 to start debugging this Windows Phone 7 + Azure solution.  As usual, a web page and the emulator will launch.  Tap the Get Customers button to pull the Customer data back from the WCF REST service.  Next, tap on the View Customers button to display the list of Customers from the in-memory database as shown in the picture below:

phone1

Now it’s time to add a new Customer so drop a button underneath the listbox and call it Add Customer.  Creating a new Customer object requires setting values for 8 properties.  Instead of having you add 8 textboxes to type in the info, I’ll keep in simple and let you add it in code.  In the click event of the button, paste in the code you see below:

try
{
if (Database.Instance.Customers != null)
{
Customer customer = new Customer();
customer.CustomerId = 5;
customer.DistributionCenterId = 1;
customer.RouteId = 1;
customer.Name = “ABC Corp”;
customer.StreetAddress = “555 Market Street”;
customer.City = “Seattle”;
customer.StateProvince = “WA”;
customer.PostalCode = “98987”;
Database.Instance.Customers.Add(customer);
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}

After setting all the properties (Columns), you add the Customer object (Row) to the Customers property (Table), in the Singleton Database.  Hit F5, tap the Get Customers button, tap the View Customers button and then tap the Add Customer button.  Through the magic of simple data-binding, you should see the new “ABC Corp” show up in the listbox as shown below:

phone2

Now that you’ve added a new Customer, it’s time to update it because the president of the company decided to change the name.  Drag a new button and drop it underneath the Add Customer button.  Call it Update Customer and in it’s click event, paste in the following code:

try
{
if (Database.Instance.Customers != null)
{
foreach (Customer c in Database.Instance.Customers)
{
if (c.Equals((Customer)listBoxCustomers.SelectedItem))
{
c.Name = “XYZ Inc”;
}
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}

The code above loops through the Customers ObservableCollection until it finds a match for the item that’s been selected in the listbox.  When it finds that match, it updates the Name property to “XYZ Inc” which will automatically update what the user views in the listbox.

Hit F5, tap the Get Customers button, tap the View Customers button and then tap the Add Customer button.  Now tap on “ABC Corp” in the listbox to highlight it.  Clicking the Update Customer button will change it before your eyes.

phone3

It turns out that “XYZ Inc” went out of business because the president was an idiot so you need to delete it.  Guess what, you need yet another button beneath the Update Customer button.  Call it Delete Customer and in it’s click event, paste in the following code:

try
{
if (Database.Instance.Customers != null)
{
Database.Instance.Customers.Remove((Customer)listBoxCustomers.SelectedItem);
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}

In the code above, the Customer object that matches the item selected in the listbox is removed from the Customers ObservableCollection.  Pretty simple stuff in this case.

To find out for sure, hit F5, tap the Get Customers button, tap the View Customers button and then tap the Add Customer button.  Now tap on “ABC Corp” in the listbox to highlight it.  Clicking the Update Customer button will change it to “XYZ Inc.”  Highlighting “XYZ Inc” and clicking the Delete Customer button will cause this defunct company to disappear as shown below:

phone4

Now suppose you only want to display the Customers from Seattle and not the Eastside.  A little LINQ will do the trick here.  Drag and drop a new button called Seattle next to the Test Uri button and paste the following code in the click event:

if (Database.Instance.Customers != null)
{
IEnumerable<Customer> customers = from customer in Database.Instance.Customers
where customer.DistributionCenterId == 1
select customer;
listBoxCustomers.DisplayMemberPath = “Name”;
listBoxCustomers.ItemsSource = customers;
}
else
{
MessageBox.Show(“The Driver Table is Empty”);
}

In the code above, I set an IEnumerable<Customer> variable equal to the Customers table where the DistributionCenterId is equal to 1.  Since the DistributionCenter #1 serves the Seattle area, I know the listbox will be filled with just Adventure Works LLC and City Power & Light.  Start debugging and test it for yourself.

The last thing you need to do with local data is store it offline since you can’t always count on the network being there.  Luckily we’ve got Isolated Storage to serialize stuff.  In order to work with Isolated Storage, I need you to add using System.IO.IsolatedStorage; at the top of the class.  Since in this example I’ll demonstrate XML Serialization of the Customers ObservableCollection, I’ll need you to add a reference to System.Xml.Serialization and then add using System.Xml.Serialization; at the top of the class.  With that plumbing in place, let’s write some actual code.

Drag and drop another button called Save next to the Get Customers button and paste the following code in the click event:

if (Database.Instance.Customers != null)
{
using (IsolatedStorageFile store = IsolatedStorageFile.GetUserStoreForApplication())
{
using (IsolatedStorageFileStream stream = store.CreateFile(“Customers.xml”))
{
XmlSerializer serializer = new XmlSerializer(typeof(ObservableCollection<Customer>));
serializer.Serialize(stream, Database.Instance.Customers);

        }
}
}

In the code above, you use the combination of IsolatedStorageFile and IsolatedStorageFileStream to write data to Isolated Storage.  In this case, you’re going to create an XML file to save the Customers ObservableCollection of Customer objects.  Remember back in the 80’s when databases used to save each table as an individual file?  I’m thinking of DBase III+, FoxPro, and Paradox at the moment.  Anyway, this is exactly what happens here using the power of the XmlSerializer.  Feel free to debug and step through the code to ensure that it executes without error.

To complete the picture, you need to be able to retrieve the Customers ObservableCollection from Isolated Storage and work with the data without ever having to call the WCF REST services.  Drag and drop one last button called Load next to the View Customers button and paste the following code in the click event:

using (IsolatedStorageFile store = IsolatedStorageFile.GetUserStoreForApplication())
{
if (store.FileExists(“Customers.xml”))
{
using (IsolatedStorageFileStream stream = store.OpenFile(“Customers.xml”, System.IO.FileMode.Open))
{
XmlSerializer serializer = new XmlSerializer(typeof(ObservableCollection<Customer>));
Database.Instance.Customers = (ObservableCollection<Customer>)serializer.Deserialize(stream);
}
}
}

The code above does the reverse of the previous Save code by opening the Customers.xml and re-hydrating those objects back into the Customers table using the XmlSerializer.  This is pretty cool stuff.

To make it all real, hit F5 to start debugging this completed mobile project.  When the app loads, tap the Get Customers button to retrieve the data and then tap View Customers to verify that you can see the data.  Now I want you to tap the Save button to serialize the Customers to an XML file in Isolated Storage.  Lastly, I want you to tap on the Back button to close the application.

Hit F5 again to fire up the application.  This time, I don’t want you to retrieve the data from Azure.  Instead, I want you to tap the Load button to de-serialize the Customer objects from XML.  Now for the moment of truth.  Tap the View Customers button to see if you’re actually working with an offline database.  Hopefully, your app will look like the picture below:

phone5

Congratulations!  You’ve made it to the end of this series of articles on building an occasionally-connected Windows Phone 7 application that works with WCF REST + JSON Services in Windows Azure.  Furthermore, you’re now pulling data down from SQL Azure and you’re working with it locally using a simple in-memory database that you built yourself.  I’m hoping that you’ll now feel empowered to go build industrial-strength mobile solutions for your own company or your customers.

Keep coding!

-Rob

Sharing my knowledge and helping others never stops, so connect with me on my blog at http://robtiffany.com , follow me on Twitter at https://twitter.com/RobTiffany and on LinkedIn at https://www.linkedin.com/in/robtiffany

Sign Up for my Newsletter and get a FREE Chapter of “Mobile Strategies for Business!”

[mc4wp_form id=”5975″]