Create, Update & Delete(CUD) Operations of SQL Server / SQL Azure Data through OData WCF Services from Windows Phone 7.1 Mango


In previous posts, I discussed about the consumption of SQL Server/ SQL Azure data in Windows Phone 7.1 Mango device through the use of OData WCF services. OData ServicesĀ  support not only HTTP GET operations but also supports for HTTP POST, PUT & DELETE by which we can perform CRUD (Create, Read, Update, Delete) operations from SQL Server/SQL Azure/ Oracle / SharePoint 2010 / SSRS 2008 / SAP Netweaver BI data etc.

  • In this post, Let’s discuss how to add new data by HTTP POST through XML ATOMPUB format from Windows Phone 7.1 client to the SQL Server database.
  • Created a new .XAML page called ‘Add.xaml’ which will capture data from Phone UI & save it to the SQL Server / SQL Azure database.

  • Lets check theĀ Source Code for the Create operation:

<phone:PhoneApplicationPage

x:Class=”WP7PanoramaOData.Add”

xmlns=”http://schemas.microsoft.com/winfx/2006/xaml/presentation&#8221;

xmlns:x=”http://schemas.microsoft.com/winfx/2006/xaml&#8221;

xmlns:phone=”clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone”

xmlns:shell=”clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone”

xmlns:d=”http://schemas.microsoft.com/expression/blend/2008&#8243;

xmlns:mc=”http://schemas.openxmlformats.org/markup-compatibility/2006&#8243;

FontFamily=”{StaticResource PhoneFontFamilyNormal}”

FontSize=”{StaticResource PhoneFontSizeNormal}”

Foreground=”{StaticResource PhoneForegroundBrush}”

SupportedOrientations=”PortraitOrLandscape” Orientation=”Portrait”

mc:Ignorable=”d” d:DesignHeight=”768″ d:DesignWidth=”480″

shell:SystemTray.IsVisible=”True”>

<!–LayoutRoot is the root grid where all page content is placed–>

<Grid x:Name=”LayoutRoot”>

<Grid.Background>

<ImageBrush ImageSource=”images/Back.png”/>

</Grid.Background>

<Grid.RowDefinitions>

<RowDefinition Height=”Auto”/>

<RowDefinition Height=”*”/>

</Grid.RowDefinitions>

<!–TitlePanel contains the name of the application and page title–>

<StackPanel x:Name=”TitlePanel” Grid.Row=”0″ Margin=”12,17,0,28″>

<TextBlock x:Name=”ApplicationTitle” Text=”MY APPLICATION” Style=”{StaticResource PhoneTextNormalStyle}”/>

<TextBlock x:Name=”PageTitle” Text=”Customer Data” Margin=”9,-7,0,0″ Style=”{StaticResource PhoneTextTitle1Style}”/>

</StackPanel>

<!–ContentPanel – place additional content here–>

<Grid x:Name=”ContentPanel” Grid.Row=”1″ Margin=”12,-15,12,0″>

<StackPanel Orientation=”Vertical”>

<TextBlock Text=”First Name:” FontSize=”16″ Margin=”5″/>

<TextBox Name=”txtFirstName” />

<TextBlock Text=”Last Name:” FontSize=”16″ Margin=”5″ />

<TextBox Name=”txtLastName”/>

<TextBlock Text=”Address:” FontSize=”16″ Margin=”5″/>

<TextBox Name=”txtAddress” />

<TextBlock Text=”City:” FontSize=”16″ Margin=”5″ />

<TextBox Name=”txtCity”/>

<TextBlock Text=”Zip:” FontSize=”16″ Margin=”5″/>

<TextBox Name=”txtZip” />

<TextBlock Text=”State:” FontSize=”16″ Margin=”5″ />

<TextBox Name=”txtState”/>

</StackPanel>

</Grid>

</Grid>

<!–Sample code showing usage of ApplicationBar–>

<phone:PhoneApplicationPage.ApplicationBar>

<shell:ApplicationBar IsVisible=”True” IsMenuEnabled=”True” Opacity=”.2″>

<shell:ApplicationBarIconButton x:Name=”btnSave” IconUri=”images/Save.png” Text=”Save” Click=”btnSave_Click”/>

<shell:ApplicationBarIconButton x:Name=”btnCancel” IconUri=”images/Cancel.png” Text=”Cancel” Click=”btnCancel_Click”/>

</shell:ApplicationBar>

</phone:PhoneApplicationPage.ApplicationBar>

</phone:PhoneApplicationPage>

  • Paste the code in Add.xaml.cs:

usingĀ System;

usingĀ System.Collections.Generic;

usingĀ System.Linq;

usingĀ System.Net;

usingĀ System.Windows;

usingĀ System.Windows.Controls;

usingĀ System.Windows.Documents;

usingĀ System.Windows.Input;

usingĀ System.Windows.Media;

usingĀ System.Windows.Media.Animation;

usingĀ System.Windows.Shapes;

usingĀ Microsoft.Phone.Controls;

usingĀ WP7PanoramaOData.CustomersModel;

usingĀ System.Data.Services.Client;

namespaceĀ WP7PanoramaOData

{

public partial class Add : PhoneApplicationPage

{

publicĀ  CustomersEntities ctx = newCustomersEntities(new Uri(http://10.12.1.223/ODataSQLWP7/CustomerService.svc/&#8221;, UriKind.Absolute));

Ā Ā Ā Ā  public Add()

{

InitializeComponent();

}

//Ā Ā  Load data for the ViewModel Items

Ā private void btnSave_Click(object sender, EventArgs e)

{

// Instantiate the Client

var newCustomer = newCustomerInfo();

newCustomer.FirstName =Ā this.txtFirstName.Text.Trim();

newCustomer.LastName =Ā this.txtLastName.Text.Trim();

newCustomer.Address =Ā this.txtAddress.Text.Trim();

newCustomer.City =Ā this.txtCity.Text.Trim();

newCustomer.Zip =Ā this.txtZip.Text.Trim();

newCustomer.State =Ā this.txtState.Text.Trim();

ctx.AddObject(“CustomerInfoes”, newCustomer);

ctx.BeginSaveChanges(insertUserInDB_Completed, ctx);

}

Ā Ā  private void insertUserInDB_Completed(IAsyncResult result)

{

ctx.EndSaveChanges(result);

}

Ā Ā  privateĀ  void btnCancel_Click(object sender, EventArgs e)

{

Ā Ā Ā Ā  this.NavigationService.Navigate(newUri(“/MainPage.xaml”, UriKind.Relative));

}

}

}

  • LetsĀ check after addition of new data , the Windows Phone 7.1 UI:

  • Lets check the steps ofĀ updating the existing data :

  • LetsĀ update the list with new data & perform HTTP PUTĀ operation for updating data of Astoria services.

  • Ā After updating existing data, you can refresh the Main list to get updated data. Same update happens in database too.

  • Source code to perform Update Operation with OData WCF ServicesĀ for SQL Server / SQL Azure database for Windows Phone 7.1 Mango:

<phone:PhoneApplicationPage

x:Class=”WP7PanoramaOData.Edit”

xmlns=”http://schemas.microsoft.com/winfx/2006/xaml/presentation&#8221;

xmlns:x=”http://schemas.microsoft.com/winfx/2006/xaml&#8221;

xmlns:phone=”clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone”

xmlns:shell=”clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone”

xmlns:d=”http://schemas.microsoft.com/expression/blend/2008&#8243;

xmlns:mc=”http://schemas.openxmlformats.org/markup-compatibility/2006&#8243;

FontFamily=”{StaticResource PhoneFontFamilyNormal}”

FontSize=”{StaticResource PhoneFontSizeNormal}”

Foreground=”{StaticResource PhoneForegroundBrush}”

SupportedOrientations=”Portrait” Orientation=”Portrait”

mc:Ignorable=”d” d:DesignHeight=”768″ d:DesignWidth=”480″

shell:SystemTray.IsVisible=”True”>

<!–LayoutRoot is the root grid where all page content is placed–>

<Grid x:Name=”LayoutRoot”>

<Grid.Background>

<ImageBrush ImageSource=”images/Back.png”/>

</Grid.Background>

<Grid.RowDefinitions>

<RowDefinition Height=”Auto”/>

<RowDefinition Height=”*”/>

</Grid.RowDefinitions>

<!–TitlePanel contains the name of the application and page title–>

<StackPanel x:Name=”TitlePanel” Grid.Row=”0″ Margin=”12,17,0,28″>

<TextBlock x:Name=”ApplicationTitle” Text=”MY APPLICATION” Style=”{StaticResource PhoneTextNormalStyle}”/>

<TextBlock x:Name=”PageTitle” Text=”Edit Data” Margin=”9,-7,0,0″ Style=”{StaticResource PhoneTextTitle1Style}”/>

</StackPanel>

<!–ContentPanel – place additional content here–>

<Grid x:Name=”ContentPanel” Grid.Row=”1″ Margin=”12,-15,12,0″>

<StackPanel Orientation=”Vertical”>

<TextBlock Text=”First Name:” FontSize=”16″ Margin=”5″/>

<TextBox Name=”txtFirstName” />

<TextBlock Text=”Last Name:” FontSize=”16″ Margin=”5″ />

<TextBox Name=”txtLastName”/>

<TextBlock Text=”Address:” FontSize=”16″ Margin=”5″/>

<TextBox Name=”txtAddress” />

<TextBlock Text=”City:” FontSize=”16″ Margin=”5″ />

<TextBox Name=”txtCity”/>

<TextBlock Text=”Zip:” FontSize=”16″ Margin=”5″/>

<TextBox Name=”txtZip” />

<TextBlock Text=”State:” FontSize=”16″ Margin=”5″ />

<TextBox Name=”txtState”/>

</StackPanel>

</Grid>

</Grid>

<!–Sample code showing usage of ApplicationBar–>

<phone:PhoneApplicationPage.ApplicationBar>

<shell:ApplicationBar IsVisible=”True” IsMenuEnabled=”True” Opacity=”.2″>

<shell:ApplicationBarIconButton x:Name=”btnSave” IconUri=”images/Save.png” Text=”Save” Click=”btnSave_Click”/>

<shell:ApplicationBarIconButton x:Name=”btnCancel” IconUri=”images/Cancel.png” Text=”Cancel” Click=”btnCancel_Click”/>

</shell:ApplicationBar>

</phone:PhoneApplicationPage.ApplicationBar>

</phone:PhoneApplicationPage>

  • Edit.xaml.cs :

using System;

using System.Collections.Generic;

using System.Linq;

using System.Net;

using System.Windows;

using System.Windows.Controls;

using System.Windows.Documents;

using System.Windows.Input;

using System.Windows.Media;

using System.Windows.Media.Animation;

usingĀ  System.Windows.Shapes;

using Microsoft.Phone.Controls;

using WP7PanoramaOData.CustomersModel;

using System.Data.Services.Client;

namespace WP7PanoramaOData

{

public partialclassEdit : PhoneApplicationPage

{

public CustomersEntities ctx = newCustomersEntities(newUri(http://10.12.1.223/ODataSQLWP7/CustomerService.svc/&#8221;, UriKind.Absolute));

public Edit()

{

InitializeComponent();

}

privatevoid btnSave_Click(object sender, EventArgs e)

{

var qry = ctx.CreateQuery<CustomerInfo>(“CustomerInfoes”).AddQueryOption(“$filter”, “FirstName eq” + “\'” + “Maria” + “\'”);

qry.BeginExecute(r =>

{

var query = r.AsyncState asDataServiceQuery<CustomerInfo>;

Ā Ā Ā Ā Ā Ā Ā Ā Ā Ā Ā Ā Ā Ā  try

{

Ā Ā Ā Ā Ā Ā Ā Ā Ā Ā Ā  Deployment.Current.Dispatcher.BeginInvoke(() =>

{

Ā Ā Ā Ā Ā Ā Ā Ā Ā Ā Ā Ā Ā Ā Ā  var result = query.EndExecute(r).First();

result.FirstName =Ā this.txtFirstName.Text;

result.LastName =Ā this.txtLastName.Text.Trim();

result.Address =Ā Ā this.txtAddress.Text.Trim();

result.City =Ā this.txtCity.Text.Trim();

result.Zip =Ā this.txtZip.Text.Trim();

result.State =Ā this.txtState.Text.Trim();

ctx.UpdateObject(result);

ctx.BeginSaveChanges(changeUserInDB_Completed, ctx);

});

}

Ā Ā Ā Ā Ā  catch (Exception ex)

{

MessageBox.Show(ex.ToString());

}

}, qry);

}

private void changeUserInDB_Completed(IAsyncResult result)

{

ctx.EndSaveChanges(result);

}

private void btnCancel_Click(object sender, EventArgs e)

{

this.NavigationService.Navigate(newUri(“/MainPage.xaml”, UriKind.Relative));

}

}

}

 

Consuming OData WCF REST Service from Android Client Device


As in my previous blog , already mentioned to create about OData Service feed in ATOM format which can be consumed in Windows Phone 7, Android, iPhone/iPAD , Silverlight,PHP, Windows Azure Table StorageĀ clients.

  • Lets check , how to consume the OData WCF REST service in Android client. To work with OData Android client lets download Odata4j Android client library from RESTlet: http://www.restlet.org/downloads/Ā & select the OData4j-Bundle.jar in Java Build Path of your Android project.
  • Next, to consume OData service from android device, we need to host the service in IIS. In my demo, i have hosted it in IIS 7.5.
  • Now, Start develop an android client application which can consume OData feed.
  • Modify AndroidManifest.xml as it can consume feed from internet from native application:

<uses-permissionandroid:name=“android.permission.INTERNET”>

</uses-permission>

Ā Ā  Write code forĀ  Activity.java :

package com.example.android.OData;

import java.util.ArrayList;

import java.util.List;

import org.odata4j.consumer.ODataConsumer;

import org.odata4j.core.OEntity;

import android.app.ListActivity;

import android.os.Bundle;

import android.widget.ArrayAdapter;

public class JsonGrabbingConsumerExampleActivityĀ  extendsĀ  ListActivity {

/** Called when the activity is first created. */

@Override

public voidĀ  onCreate(Bundle savedInstanceState) {

Ā super.onCreate(savedInstanceState);

Ā Ā Ā Ā Ā Ā Ā  setListAdapter(new ArrayAdapter<String>(this,Ā Ā  android.R.layout.simple_list_item_1, GetExpenseReports()));

Ā Ā Ā Ā Ā Ā Ā  getListView().setTextFilterEnabled(true);

Ā Ā Ā  }

// read expenses odata feed

Ā Ā Ā  ArrayList<String> GetExpenseReports()

Ā Ā Ā  {

// build a simple array list of strings to test things out

Ā Ā Ā Ā Ā Ā Ā  ArrayList<String> listUI = new ArrayList<String>();

// use odata4j consumer

Ā Ā Ā Ā Ā Ā Ā  ODataConsumer c = ODataConsumer.create(http://10.12.1.223/ODataSample1/Service.svc);

// run a query just for Pending states

Ā Ā Ā Ā Ā Ā Ā  List<OEntity> listExpenses = c.getEntities(“SampleCustomerData”).execute().toList();

for(OEntity expense : listExpenses) {

Ā Ā Ā  listUI.add(expense.getProperty(

“CustomerID”).getValue().toString()

Ā Ā Ā  +

“; “ + expense.getProperty(“CustomerName”).getValue().toString()

Ā Ā Ā  +

“; “ + expense.getProperty(“CustomerNotes”).getValue().toString()

Ā Ā Ā  );

Ā Ā Ā Ā Ā Ā Ā  }

return Ā listUI;Ā Ā Ā 

Ā Ā Ā  }

}

  • Checkout the output in Android 2.3:

Accessing REST based service from Windows Phone 7.1 using SAML Token


Accessing REST based services from Windows Phone 7 client devices include two approaches: Active Federation implementationĀ means how the client application uses OAuth protocol and contacts all the issuers in the trust chain in turn to acquire a valid SWT token to access a online enterprise application where as in passive federation mode device ‘s embedded browser requests the identity provider list from Access Control Service(ACS 2.0)Ā  which in turn requests for token from trusted issuer & issuer sends back the SAML 2.0 token which is received by the device then it send a call to the enterprise REST service as Relying Party (RP) with Simple Web Token (SWT) Token.

  • Comparison of the Federation Difference:
  • The passive federation solution that leverages an embedded browser control offers a simpler approach to obtain an SWT token because the embedded web browser control in combination with the WS-Federation protocol handles most of the logic to visit the issuers and obtain the SWT token that the enterprise application needs.
  • In the active federation solution, the Windows Phone Application must include code to control the interactions with the issuers explicitly. Also, the active solution must include code to handle the requests for SAML tokens from the Relying Party(Issuer).
  • An advantage of passive federation approach is that it enables the Windows Phone Application to dynamically build the list of identity providers to your ACS configuration.
  • You must explicitly add any SWT token caching behavior to the Windows Phone application for both the active or passive federation solutions.
  • Download 9WindowsPhoneClientFederation from http://claimsid.codeplex.comĀ to get Visual Studio development system Ā solution for Claims identity based REST services for Windows Phone .