Reading Data Using the Infor CRM SData REST API from a .NET Application Using the DotNetSDataClient Library

When working with the Infor CRM SData REST API from a .NET application or website, there are a few different choices for libraries you can use to make the SData code easier. The original library was called the SDataCSharpClientLib, which I have written about previously. However, the SDataCSharpClientLib was replaced with the newer DotNetSDataClient library. I figured it was time to write a few articles using the DotNetSDataClient since, if you’re just starting your app, that is what you’ll want to use. The older SDataCSharpClientLib is still valid, however, any new work is going into the newer DotNetSDataClient since it has a lot of newer features that the other doesn’t have.

How to get the DotNetSDataClient Library

The easiest way to get the DotNetSDataClient Library is via the NuGet packaging system built into Visual Studio. Just search for DotNetSDataClient and you’ll easily find it. Alternatively, you can download it from the source at it’s home on Github.

How to use the DotNetSDataClient Library

There are several ways you can use the DotNetSDataClient library. I’m going to cover my preferred method of using POCO objects. In a nutshell, the DotNetSDataClient library works in the same way that Sublogix does. It does all the work of retrieving and sending data to the SData API and then serializes to and from POCO objects. A POCO object, as-in a “Plain Old CLR Object”, is a simple class that will represent the data that comes from SData. It’s a simple entity objects with properties that match the properties coming from the SData entity. Basically, when you read data from SData it comes back in the form of JSON or Atom/XML. You’ll make a simple class to represent this data and the DotNetSDataClient will serialize the JSON data into your .NET object. For example, if you’re reading contacts, you’ll create a simple contact class, with matching properties to what is in the SData feed, and the DotNetSDataClient will serialize the JSON into your class. Then you have a nice, strongly-typed .NET object(s) to work with.

Let’s take a look at an example POCO class for an Account (this doesn’t include everything for an account, just the ones I want for this example):

using System;
using Saleslogix.SData.Client;

namespace MyApp.Entities
{
    [SDataPath("accounts")]
    public class Account
    {
        [SDataProtocolProperty(SDataProtocolProperty.Key)]
        public string Id { get; set; }

        public string AccountName { get; set; }
        public string Type { get; set; }
        public string Status { get; set; }
        public string MainPhone { get; set; }
        public string WebAddress { get; set; }
    }
}

That’s a pretty simple class that I will use for account data returned from my SData calls. I use the same property names here as what is in my entity and the DotNetSDataClient will map the same property names from the SData entity to the property in the class. Notice the [SDataPath(“accounts”)] attribute on the class, which tells the DotNetSDataClient the SData path the data in this class is for (you can see what an entity’s SData path is by opening the entity in Application Architect and you’ll find it’s path on the SData tab). Also, the [SDataProtocolProperty(SDataProtocolProperty.Key)] on the Id property. This tells the DotNetSDataClient to map the $key property (the primary ID value from the entity) from SData to this property in the class.

Now, to use this Account class we created, we can make a call using the DotNetSDataClient to retrieve an account or accounts, and tell it to use this class for the results.

To get a single Account given it’s ID

// create client and provide SData address & credentials
var client = new SDataClient("http://localhost:3333/sdata/slx/dynamic/-/")
{
	UserName = "admin",
	Password = ""
};

// get single account using it's ID
var account = client.Get<Account>("AGHEA0002669");

In that code, all the magic happens in the one line var account = client.Get<Account>(“IDVALUE”). In that line, we tell the DotNetSDataClient to use our Account class and fill it with the account with the matching ID value. It looks at the SDataPath attribute in the Account class to know what SData path to use and requests the account with that ID value. It takes the result and deserializes it into an instance of our Account class, matching up the property names from the SData result with the property names in our class, and returns that to us.

To get a list of accounts given criteria

// create client and provide SData address & credentials
var client = new SDataClient("http://localhost:3333/sdata/slx/dynamic/-/")
{
	UserName = "admin",
	Password = ""
};

// get list of accounts where account name starts with 'Ab'
var accounts = client.Execute<List<Account>>(new SDataParameters
{
	Method = HttpMethod.Get,
	Path = "accounts",
	OrderBy = "AccountName",
	Where = "AccountName like 'Ab%'"
});

Well, that’s the basics. Next time we’ll be looking at how to do the same as the above using Linq queries (which is a far better and easier route and even includes built in paging) as well as several other topics using the DotNetSDataClient library.

ABOUT THE AUTHOR

Ryan Farley

Ryan Farley is the Director of Development for Customer FX and creator of slxdeveloper.com. He's been blogging regularly about SalesLogix, now Infor CRM, since 2001 and believes in sharing with the community. His new passion for CRM is Creatio, formerly bpm'online. He loves C#, Javascript, web development, open source, and Linux. He also loves his hobby as an amateur filmmaker.

12 Comments

  1. Hi Ryan,

    var client = new SDataClient(“http://localhost:3333/sdata/slx/dynamic/-/”)
    {
    UserName = “admin”,
    Password = “”
    };

    2 questions:
    (1) What’s the full namespace of SDataClient?
    (2) How do you set credential for Windows Authentication system?

    Reply
    • The fully qualified name for SDataClient is:
      Saleslogix.SData.Client.SDataClient

      I believe the code is the same, no changes, for authenticating using windows auth. Just provide the windows credentials. You’ll have to test it out.

      Ryan

  2. Thanks Ryan!

    Reply
  3. Hi Ryan,

    Because the Account class only has properties, the instance account returned by the SDATA client doesn’t have the methods like Save, Delete and so on, right? If I want the account has those methods, how should I do?

    Thank!

    Reply
    • Right, they won’t have those methods. You need to code those yourself using the Post (for inserts) or Put (for updates) in the SDataClient class. I’ll have some blog posts on using those soon.

  4. Thanks Ryan. Hope to see the blog posts soon.

    Reply
  5. Hi Ryan

    if i use the library like so

    var sd = new SDataClient(“http:///sdata/slx/dynamic/-/”)
    {
    UserName = “”,
    Password = “”
    };

    var contacts = sd.Query(“contacts”)
    .Where(c => c[“AccountName”] == “”)
    .OrderBy(c => c[“LastName”])
    .ThenBy(c => c[“FirstName”])
    .Fetch(c => c[“Address”])
    .ToList();

    i get back a collection of contacts , but if i try and bind that to a grid/list ( using telerik controls) they does not seem to be anything to bind too?

    if i get back one record the grid will bind – but it will bind a row for each key value (which is not what we would expect? )

    do you have any guidance in trying to bind the sdata returned data to controls?

    thanks

    Reply
    • It’s probably because what you are getting back are anonymous objects. Try creating a POCO class for contact and use that instead, this way you’ll be getting back strongly typed contact entities and should have no problem binding to the grid.

      Something like this:
      [SDataPath(“contacts”)]
      public class Contact
      {
      public string AccountName { get; set; }
      public string FirstName { get; set; }
      public string LastName { get; set; }
      public string Status { get; set; }
      public Address Address { get; set; }
      }

      Then you’d change your query to this:

      var contacts = client.Query()
      .Where(c => c.AccountName == “”)
      .OrderBy(c => c.LastName)
      .ThenBy(c => c.FirstName)
      .Fetch(c => c.Address)
      .ToList();

      Ryan

  6. Can Infor CRM connect to Power Bi?

    Reply
    • I’m not aware of any existing integration, that would have to be developed as a custom integration.

  7. Am I able to create a new ID when doing an insert?

    Reply
    • Hi Xena,
      The SData API creates the Id for the insert automatically. You can’t *create* an Id via SData but you don’t need to either. All you need to do is send an Insert payload and the Id will get created for the insert on the server and returned in the response of the POST.
      Ryan

Leave a Reply to JP Cancel reply

Your email address will not be published. Required fields are marked *

Subscribe To Our Newsletter

Join our mailing list to receive the latest Infor CRM (Saleslogix) and Creatio (bpm'online) news and product updates!

You have Successfully Subscribed!