Update:  The code for the sample application and the How To Guide for this series is now published.

In my previous blog, I had talked about the onboarding process to uniquely identify a device with the SMP Server.  The next logical progression in this blog series is to write about how devices can retrieve data from the backend and also how devices can make changes to the backend data.  As part of this blog, I will try and post code for another sample application that illustrates how to retrieve data and make changes to backend using the SAP Mobile Platform SDK (hereinafter referred to as “SMP SDK” or “SDK”).

CRUD operations

In order to retrieve data from the backend, an HTTP GET request is made along with the application connection id in the headers.

HTTP Request

URL: http://<hostname>:<port>/<appid>/<CollectionName>

Method: GET

Header: { X-SMP-APPCID : <app connection id> }



To accomplish this using the SMP SDK, the following steps need to be taken.  Creating an ODataStore instance and calling OpenAsync is only done once for a session.  From there on, it’s a matter of calling ScheduleReadEntitySet method any number of times.


GETFlow.PNG


The ODataStore library is used to interact with the SMP Server to submit HTTP requests to either GET data or perform CUD operations.  An ODataStore instance is required to interact with an OData Service.  The ODataStore hides a lot of complexities and makes interacting with OData source fairly easy for the developer.   To create an instance of the ODataStore, the developer can use either one of the 2 constructors.  The default value for the 2nd EntityFormat parameter is XML format. However, using JSON format considerably reduces the network traffic.


public ODataStore(string serviceUri, ODataStore.EntityFormat entityFormat = ODataStore.EntityFormat.XML);
public ODataStore(Uri serviceUri, ODataStore.EntityFormat entityFormat = ODataStore.EntityFormat.XML);
public enum EntityFormat
{
    JSON = 0,
    XML = 1,
}
// Sample code snippet for creating an ODataStore
var store = new ODataStore(uri);


Once an instance of ODataStore is created, the method OpenAsync is called.  This method retrieves the service document and the metadata document.   When making the OpenAsync call, it is also necessary to pass in the user credentials and the application connection id as header values.


var client = new SAP.Net.Http.HttpClient( new System.Net.Http.HttpClientHandler { Credentials = new NetworkCredential(“user", “password") }, true);
client.DefaultRequestHeaders.TryAddWithoutValidation("X-SMP-APPCID",appconnid);
await store.OpenAsync(client);


The ScheduleReadEntitySet method is used to schedule an HTTP GET request.  This method takes the collection name as a parameter.  The Response object is then called asynchronously to submit the request.


var execution = store.ScheduleReadEntitySet(collectionName);
var response = await execution.Response;


The response object is then cast as an ODataEntitySet and can be immediately bound to an UI control.  The ODataEntitySet is an IObservableCollection which allows the UI controls to automatically update themselves when the collection is changed.


var response = await execution.Response;
this.EntitySet = (SAP.Data.OData.Online.ODataEntitySet)((IODataResponseSingle)response).Payload;
// Bind this.EntitySet directly to UI controls


Making changes to the backend

The ScheduleCreateEntity method is used to create an entity in the backend.  This method takes an ODataEntity and the CollectionName as parameters.  An entity is created locally and passed in as parameter to the ScheduleCreateEntity method.

POSTFlow.PNG


var entity = new SAP.Data.OData.Online.ODataEntity(“TypeName");
entity.Properties["ID"].Value = XYZ;
entity.Properties["Name"].Value = “<XYZ>";
store.AllocateProperties(entity, SAP.Data.OData.Store.PropertyCreationMode.All);
var execution = store.ScheduleCreateEntity(entity, collectionName);
var response = await execution.Response;


Similarly, the ScheduleUpdateEntity is used to update an entity in the backend.  This method takes an ODataEntity as a parameter.  It is recommended to use the DeepCopy() method to make a real copy of an entity (not just a reference copy).  Make the necessary updates on the temporary ODataEntity. This way, even if the update operation fails (network disconnects, server error or whatever), the original entity is still intact and the app would not be in an inconsistent state.


var copiedEntity = entity.DeepCopy();      
copiedEntity.Properties[“Name"].Value = newName;
var execution = store.ScheduleUpdateEntity(copiedEntity);
var response = await execution.Response;


The ScheduleDeleteEntity method is used to delete an entity in the backend.



var execution = store.ScheduleDeleteEntity(entity);
var response = await execution.Response;


Update:  The code for the sample application and the How To Guide is now published.  The Windows Store Flight Sample Application Series illustrates the various techniques involved in creating an online Windows Store application using the Windows SMP 3.0 SP05 SDK.  This sample application series uses the universal Windows app project templates to build apps that can run on Windows Phones, tablets, laptops and workstations.

In conclusion, in this blog I have highlighted some of the important methods involved in performing CRUD operations against an OData Source using the SAP Mobile Platform.  This current version of SMP SDK only supports online functionality for Windows.  However, future releases of the SMP SDK will support additional functionality.  In upcoming blogs, I will talk more about the newer functionality and also provide more code samples to help build Windows applications using the new SAP Mobile Platform SDK.  Also, if you have questions building Windows applications, please feel free to reach out to me.

To report this post you need to login first.

24 Comments

You must be Logged on to comment or reply to a post.

    1. Milton Chandradas Post author

      SAP Mobile Platform SDK SP05 (referred to as “SMP SDK”) contains the Windows SDK.  If you install SMP SDK in the default location, you will find the Windows SDK in the following folder: C:\SAP\MobileSDK3\NativeSDK\ODataFramework\Windows

      The size of the Windows SDK is only about 250 kb.  They are packaged as NuGet packages.  The .nupkg files contain libraries for both Windows Store and Windows Desktop applications. 

      (0) 
  1. Markus Reich

    Hi Milton,

    I have another question πŸ™‚

    As EntitySet is a dynamic data structure, is it possible to use LINQ to query against a returned entityset? We want to load the data once from backend to our app, and then the user should have the possibility to search the EntitySet?

    regards

    Meex

    (0) 
    1. Markus Reich

      ok found it myself πŸ™‚

      var entities = from entity in EntitySet

                                     where ((string)entity.Properties[“Description”].Value).Contains(“Test”)

                                     select entity;

      Meex

      (0) 
      1. Milton Chandradas Post author

        // LINQ extension method using the lambda style

        var filteredEntitySet = entitySet.Where(e => ((string)e.Properties[“Address/State”].Value) == “WA”);

        // LINQ extension method using the SQL style

        var filteredEntitySet = from e in entitySet

        where ((string)e.Properties[“Address/State”].Value) == “WA”

                                select e;

        foreach (var e in filteredEntitySet)

        {

            Console.WriteLine(e.Properties[“Name”].Value);

        }

        (0) 
  2. Markus Reich

    is there a way to transform ODataEntity to XML or JSON? I want to serialize the object so ein can store data in as BLOB in sqlite DB?

    regards

    Meex

    (0) 
    1. Milton Chandradas Post author

      var execution = Store.ScheduleReadEntitySet(collectionName);

      IODataResponse response = await execution.Response;

      string json = JsonConvert.SerializeObject(((IODataResponseSingle)response).Payload);

      You can add the Newtonsoft.Json nuget package and use the code above to serialize the object as JSON. 

      (0) 
  3. William Griep

    Was there an SDK change from SP5 to SP6 that would cause problems wtih the sample?

    ODataContext.DownloadRelatedItems breaks when trying to use the navigationProperty.AssociationResourcePath.  That value is a mangled URI that ScheduleRequest fails on.

    We worked around that by extracting the CarrierCollection(“airlinecode”)/carrierFlights from the URI and passing it in as the resourcePath instead of the mangled URI.

    Beyond that, we have problems booking flights and haven’t figured out a work around yet.

    (0) 
    1. Milton Chandradas Post author

      It should work fine.  What error are you getting when trying to use the navigationProperty.AssociationResourcePath ?  Is it implemented in the backend OData source ?

      navProp.png

      Also, does your metadata document have a navigation property named carrierFlights ?

      /wp-content/uploads/2015/01/metadata_628427.png

      (0) 
      1. Milton Chandradas Post author

        Your workaround should also work.  Your approach requires prior knowledge of the relationship between the tables, whereas the approach above queries for the relationship and figures out the related table. 

        (0) 
  4. Markus Reich

    Hi, for CRUD operations you need to send a X-CSRF-TOKEN, I’ve tried this, but I still get a 403 satus. Maybe you can provide an example?

    kind regards

    Meex

    (0) 
  5. Hendrik LΓΆsch

    Hi Milton,

    could you please explain how to get a specific entity? For example I have a flight with an id == 3 and want only this on entity.

    Regards,

    Hendrik

    (0) 
    1. Milton Chandradas

      public async Task ReadEntity(string resourcePath)

      {

      var execution = Store.ScheduleReadEntity(resourcePath);

      IODataResponse response = await execution.Response;

      this.Entity = (SAP.Data.OData.Online.ODataEntity)((IODataResponseSingle)response).Payload;

      }

      await ReadEntity(“Suppliers(3)”);

      (0) 
  6. Maged Kamal

    Hi Milton,

    Currently I am building an online windows application that will be deployed on an Intermec  device with OS version  “Windows Embeded handhled 6.5 classic, CE OS 5.2.29040”. can I use online oData SDK for communicating with SAP?

    Regards,

    Maged

    (0) 
  7. Manikanta tps

    Hi Milton,

    How to create a Entity set with json string?

    I tried in below way but its throwing a  error message while adding the data as Object reference not found.

    Dictionary<string, IODataNavigationProperty> navigationProperties = new Dictionary<string, IODataNavigationProperty>();

    Dictionary<IODataAnnotationName, string> annotations = new Dictionary<IODataAnnotationName, string>();

    ODataEntity odataEntity = new ODataEntity(“EntityType”, navigationProperties, annotations);

    odataEntity.Properties[key].Value = “SAP”;

    (0) 

Leave a Reply