Connecting to NAV Web Services from the Cloud–part 5 out of 5

If you haven’t already read part 4 (and the prior parts) you should do so here, before continuing to read this post.

In this post, I am going to create a small Windows Phone 7 application, which basically will be a phone version of the sidebar gadgets from this post. When we are done, your Windows Phone 7 will look like:

WP7

During the other posts, I have been describing how to make the Proxy and one way of securing this.

For this sample, I have created a new Proxy (Proxy2) and added 3 functions to this proxy:

Customer[] GetMyCustomers(string username, string password)
Vendor[] GetMyVendors(string username, string password)
Item[] GetMyItems(string username, string password)

You can imagine that these functions are implemented in the Proxy simply by authenticating and calling the corresponding function in the MyStuff codeunit from this post, I will not go into further detail about how the Proxy is done.

A small Console Application

Try the following:

  • In Visual Studio 2010, create a Windows Console Application
  • Add a service reference to sb://navdemo.servicebus.windows.net/Proxy2/mex and use the namespace Proxy2 (note that you need the Windows Azure AppFabric SDK to do this and you can download that here).
  • Use the following code in main:

static void Main(string[] args)
{
Proxy2.ProxyClassClient client = new Proxy2.ProxyClassClient("NetTcpRelayBinding_IProxyClass");
foreach(Proxy2.Customer customer in client.GetMyCustomers("freddy", "password"))
Console.WriteLine(string.Format("{0} {1}", customer.Name, customer.Phone));
Console.ReadLine();
}

  • Run the app, and you should get something like:

image

This in effect calls my NAV proxy2 (which is placed in Redmond) through the Service bus and returns My Customers. I will try to keep the server running, but please understand that it might be down for various reasons (I might be doing development work on the Proxy).

A Windows Phone 7 application

Now for the real thing.

In order to create solutions for Windows Phone 7, you will need the developer tools and they can be downloaded for free here: https://create.msdn.com/en-us/home/getting_started:

There are three steps to the install process:

  1. Download and install the Windows Phone Developer Tools (Release Notes)
  2. Download and install the Windows Phone Developer Tools January 2011 Update (Release Notes) [Note: Installation may take several minutes and is complete when the install dialog box closes.]
  3. Download and install the Windows Phone Developer Tools Fix

Trist smiley

Anyway – when done – you are ready.

I created a Windows Phone Panorama Application from the templates:

image

After this, I add a service reference to the Proxy (sb://navdemo.servicebus.windows.net/Proxy2/mex) with the namespace Proxy2.

Looking at the ServiceReferences.ClientConfig, you will see that only the https:// and the https:// endpoints are mentioned here as the Windows Phone doesn’t support sb://.

In Windows Phone applications it is common to have a ViewModel, which is the data for the app. The templates comes with a default ViewModel, which we need to modify:

Declaring the collections:

/// <summary>
/// Collections for My stuff objects.
/// </summary>
public ObservableCollection<Proxy2.Customer> MyCustomers { get; private set; }
public ObservableCollection<Proxy2.Vendor> MyVendors { get; private set; }
public ObservableCollection<Proxy2.Item> MyItems { get; private set; }

Initializing the ViewModel:

public MainViewModel()
{
this.MyCustomers = new ObservableCollection<Proxy2.Customer>();
this.MyVendors = new ObservableCollection<Proxy2.Vendor>();
this.MyItems = new ObservableCollection<Proxy2.Item>();
}

Loading the data:

/// <summary>
/// Load data into collections
/// </summary>
public void LoadData()
{
BasicHttpBinding binding;
EndpointAddress endpoint;

    // Emulator doesn't support HTTPS reliably
binding = new BasicHttpBinding(BasicHttpSecurityMode.None);
endpoint = new EndpointAddress("https://navdemo.servicebus.windows.net/http/Proxy2/");
 
Proxy2.ProxyClassClient client = new Proxy2.ProxyClassClient(binding, endpoint);

    client.GetMyCustomersCompleted += new EventHandler<Proxy2.GetMyCustomersCompletedEventArgs>(client_GetMyCustomersCompleted);
client.GetMyCustomersAsync("freddy", "password");

    client.GetMyVendorsCompleted += new EventHandler<Proxy2.GetMyVendorsCompletedEventArgs>(client_GetMyVendorsCompleted);
client.GetMyVendorsAsync("freddy", "password");

    client.GetMyItemsCompleted += new EventHandler<Proxy2.GetMyItemsCompletedEventArgs>(client_GetMyItemsCompleted);
client.GetMyItemsAsync("freddy", "password");

    this.IsDataLoaded = true;
}

void client_GetMyCustomersCompleted(object sender, Proxy2.GetMyCustomersCompletedEventArgs e)
{
foreach (Proxy2.Customer customer in e.Result)
this.MyCustomers.Add(customer);
}

void client_GetMyVendorsCompleted(object sender, Proxy2.GetMyVendorsCompletedEventArgs e)
{
foreach (Proxy2.Vendor vendor in e.Result)
this.MyVendors.Add(vendor);
}

void client_GetMyItemsCompleted(object sender, Proxy2.GetMyItemsCompletedEventArgs e)
{
foreach (Proxy2.Item item in e.Result)
this.MyItems.Add(item);
}

As you can see, the data is loaded using asynchronous data access – as everything on the phone works this way.

In the SampleData folder, I have modified the Sample Data xaml for the ViewModel to:

<local:MainViewModel
xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"      
xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:MyStuff"
xmlns:proxy2="clr-namespace:MyStuff.Proxy2">

<local:MainViewModel.MyCustomers>
<proxy2:Customer No="1" Name="Freddy Kristiansen" Phone="(425) 111-2222" EMail="freddy@cronus.com" />
<proxy2:Customer No="2" Name="Pernille Kristiansen" Phone="(425) 222-3333" EMail="pernille@cronus.com" />
</local:MainViewModel.MyCustomers>

    <local:MainViewModel.MyVendors>
<proxy2:Vendor No="1" Name="Niklas Kristiansen" Phone="(425) 333-4444" />
<proxy2:Vendor No="2" Name="Mads Kristiansen" Phone="(425) 444-5555" />
<proxy2:Vendor No="3" Name="Jonas Kristiansen" Phone="(425) 555-6666" />
</local:MainViewModel.MyVendors>

    <local:MainViewModel.MyItems>
<proxy2:Item No="1" Description="Bike" />
<proxy2:Item No="2" Description="Car" />
</local:MainViewModel.MyItems>

</local:MainViewModel>

Also the xaml for the panorama control in the MainPage has been modified to include 3 PanoramaItems, which binds to Customers, Vendors and Items:

<!--Panorama control-->
<controls:Panorama Title="my stuff">
<controls:Panorama.Background>
<ImageBrush ImageSource="PanoramaBackground.png"/>
</controls:Panorama.Background>

    <!-- My Customers -->
<controls:PanoramaItem Header="My Customers">
<ListBox Name="lbMyCustomers" Margin="0,0,-12,0" ItemsSource="{Binding MyCustomers}" ManipulationStarted="ListBox_ManipulationStarted" ManipulationCompleted="ListBox_ManipulationCompleted" MouseLeftButtonUp="ListBox_MouseLeftButtonUp" ManipulationDelta="ListBox_ManipulationDelta">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Margin="0,0,0,17" Width="432">
<TextBlock Text="{Binding Name}" TextWrapping="NoWrap" Style="{StaticResource PhoneTextExtraLargeStyle}"/>
<TextBlock Text="{Binding Phone}" TextWrapping="NoWrap" Margin="12,-6,12,0" Style="{StaticResource PhoneTextSubtleStyle}"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</controls:PanoramaItem>

    <!-- My Vendors -->
<controls:PanoramaItem Header="My Vendors">
<ListBox Name="lbMyVendors" Margin="0,0,-12,0" ItemsSource="{Binding MyVendors}" ManipulationDelta="lbMyVendors_ManipulationDelta" ManipulationStarted="lbMyVendors_ManipulationStarted" MouseLeftButtonUp="lbMyVendors_MouseLeftButtonUp">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Margin="0,0,0,17" Width="432">
<TextBlock Text="{Binding Name}" TextWrapping="NoWrap" Style="{StaticResource PhoneTextExtraLargeStyle}"/>
<TextBlock Text="{Binding Phone}" TextWrapping="NoWrap" Margin="12,-6,12,0" Style="{StaticResource PhoneTextSubtleStyle}"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</controls:PanoramaItem>

    <!-- My Items -->
<controls:PanoramaItem Header="My Items">
<ListBox Name="lbMyItems" Margin="0,0,-12,0" ItemsSource="{Binding MyItems}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Margin="0,0,0,17" Width="432">
<TextBlock Text="{Binding Description}" TextWrapping="NoWrap" Style="{StaticResource PhoneTextExtraLargeStyle}"/>
<TextBlock Text="{Binding No}" TextWrapping="NoWrap" Margin="12,-6,12,0" Style="{StaticResource PhoneTextSubtleStyle}"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</controls:PanoramaItem>

</controls:Panorama>

That’s it – running the application in the Windows Phone Emulator should give you the desired output.

If you want to download the entire MyStuff solution and try it out, you can download it here.

Note, that this application doesn’t do anything for local caching or updating of data, nor does it do anything when the App is tombstoned – it merely shows how to access data. The solution does however also support Dialing customers or vendors just by clicking on the line on the phone.

Enjoy

Freddy Kristiansen
PM Architect
Microsoft Dynamics NAV