sData

Sage SalesLogix Boot Camp 2011: Unlocking the Power of SData

Posted by Kristin Lisson on November 07, 2011
Blog, Developer / No Comments

Here’s a snippet of the SData discussion at Sage SalesLogix Boot Camp 2011 discussing the groups system endpoint, which implements the request to execute groups a little differently than we’ve seen with SData before. (Because the group itself is only going to get the metadata.) We do this through $queries/execute?[resource]. Here are two examples:

*************************************************************************************************************
Execute a group based on its plugin ID:
/slx/system/-/groups/$queries/execute?_groupId=p6UJ9A0004TS

Execute a group based on its family and name:
/slx/system/-/groups/$queries/execute?_family=Account&_name=All Accounts

*************************************************************************************************************

Why are “_groupId” and “_family” underscored? Nathan (SData expert) joins the SData discussion from Melbourne via Skype and tells us why:

Tags: , , , , , , , ,

Service Pack 4 Brain Dump

Posted by Kristin Lisson on May 26, 2011
Administrator, Blog, Developer / 3 Comments

The Upgrade Process

The upgrade process for Sage SalesLogix v7.5 Service Pack 4 is different than previous service packs because SP4 includes a full install. It’s very similar to the process of installing the base v7.5.0 product—except with a lot more features in the end! They are so similar in fact, that if you are installing Sage SalesLogix in a new, on-premise environment, you can go directly to the SP4 installer (no v7.5.0 necessary). If upgrading from an existing v7.5.X* environment, on the other hand, the SP4 installer runs in the same way except that it first removes applications with prior version and then re-installs them.

During the installation (or re-installation) for each feature (Admin Tools & Servers, Client, Web Host, Web Reporting, and so on), the SP4 installation wizard inspects your system for necessary prerequisites and even finds the appropriate installer for you, which makes the process extremely seamless. The Applying Service Pack 4 for Sage Saleslogix Version 7.5 documentation is the ultimate resource for choosing the right upgrade workplan for your environment. Always defer to the documentation when performing an upgrade in a production environment.

Now that the disclaimer is out of the way, I can reveal the following [abbreviated] steps that we use in Training to upgrade our image from v7.5.0–>v7.5.4. (Upgrading from v7.5.3–>v7.5.4 is similar, but you can skip steps 1, 9, and 10 if you already did them for SP3.)

  1. Delete the MergeConfiguration.xml file and the PotentialMatchConfiguration.xml file in Application Architect.
  2. Run the Setup.exe, and install Administrative Tools and Servers. (Restart.)
  3. Run the Setup.exe, and install the LAN or Remote Client.
  4. Install the LAN bundle in the Administrator.
  5. Run the Setup.exe, and install the Web Host on IIS.
  6. Run the Setup.exe, and install the Web Reporting Server.
  7. Restore the SP4 project backup, rebuild web platform, deploy core portals.
  8. Run the Role Security utility.
  9. Add users to the Standard User role in the Web Client.
  10. Reconfigure Web Reporting in the Application Architect.

Here’s a video of me going through the steps for the RC1 version with a bit more explanation. We skipped many recommended tasks from the documentation that you should perform on a production environment, but did I miss anything?**

For more videos like this one, subscribe to the Sage SalesLogix Administrator’s Subscription or contact training.crm@sage.com.

The Enhancements

Although I won’t review all of the enhancements from SP4—the Applying Service Pack 4 for Sage Saleslogix Version 7.5 documentation is the best resource for a comprehensive list—here are a few that we’re especially partial to in Training:

  • Duplicate Checker (for Web Administrators):
    This tool is available under the Tools menu when logged on as “admin.” You can also grant a standard user access to this tool by adding the user to the Data Quality Manager role. It allows you to search within any group for Account, Contact, or Lead tables and look for duplicate records in the database. This feature locates matches and scores them based on match probability, and then it allows you to resolve any duplicates by merging records. Service Pack 3 introduced the ability to merge records in the Web Client List view (right-click > merge), but you still had to spot-check for the duplicate records manually. The SP4 enhancement automates the process AND includes the Lead table.

  • Notes/History tab (for Web End Users): This enhancement brings the familiar Notes/History tab that we love from the LAN Client into the Web! It combines both history items and notes. You can filter the grid based on a variety of criteria, and you can even send any selected items to e-mail or to Word.

  • Editable Sales Order Data Grid: Now you can more easily update pricing and discount for a sales order. (Not to mention use a revamped Accounting Integration process! More to come on this in later posts.)

  • SData Enhancements (for Web Developers):
    In addition to excluding individual entity properties from the SData payload, you can also prohibit Create/Update/Delete SData operations on an entity. Also, more entities are exposed to SData.

  • Enable Field-Level Security for New Entities (for Web Developers):

  • Many more!

*If upgrading from an existing environment earlier than v7.5.0, you must first upgrade to v7.5.0 before running the SP4 installer.
**If you learned one thing from this post, let it be that you should read the service pack documentation!


Updated: Added the task to delete the PotentialMatchConfiguration.xml file to step 1.

Tags: , , , , , , , , , ,

Configure and Troubleshoot SData™

Posted by Kristin Lisson on April 29, 2011
Administrator, Blog, Developer / No Comments

Sage Data (SData) provides a simple standard protocol for reading data from and writing data to Sage Business Applications. It enables desktop, server, and Web-based applications to communicate with each other, and also with third-party applications and the world wide web. To find out more about SData™, visit http://sdata.sage.com.


Let’s configure SData™ for Sage SalesLogix!

Before you can use SData™ in your Sage SalesLogix customization projects, you need to ensure your environment is configured appropriately. Here are a few steps you should take:

1. Map the Sage SalesLogix admin user to your Windows WebDLL user*:

Learn more about the WebDLL user in this excerpt from the Sage SalesLogix Implementation Guide.

  1. Log on to the SalesLogix Administrator as admin.
  2. From the list of users, double-click the Administrator user.
  3. Select the Use Windows Authentication check box, and then map your WebDLL user on your server inside the Windows ID box. If prompted to import information from Active Directory, say no. (Although it shouldn’t matter for the WebDLL user.)


    WebDLL User Mapping
  4. Click OK.


2. Deploy the SData portal:

  1. Log on to the SalesLogix Application Architect as admin.
  2. From the Deployment Explorer, expand the Deployments node, and then double-click Core Portals.
  3. From the list of Deployment Targets, right-click the sdata node, and then click Deploy Portal.
  4. Close Application Architect.


3. Enable basic authentication:

This step is not necessary anymore (since v7.5.3 HF3) because basic authentication is enabled by default. As long as SData is accessed via https, basic authentication provides you with the security you need. Read more about SData and basic authentication/digest authentication from a previous post.


4. Disable Windows Authentication in IIS:

  1. Within IIS, right-click the sdata node, and then click Properties. The SData Properties window appears.
  2. Click the Directory Security tab.
  3. Next to the Authentication and access control option, click Edit. The Authentication Methods window appears.
  4. Clear the Integrated Windows authentication check box, and then click OK.
  5. Click OK to close the Properties window.


5. Configure handler mapping:

  1. Within IIS, right-click the sdata node, and then click Properties. The SData Properties window appears.
  2. From the Virtual Directory tab, click the Configuration button.
  3. From the list of application extensions, click the ascx extension, and then click Edit.
  4. Right-click in the Executable box, and then click Copy.
  5. Click Cancel to return to the Application Configuration window.
  6. Click Insert.
  7. Right-click in the Executable box, and then click Paste.
  8. Clear the Verify that file exists check box.
  9. Click OK, and then click OK again.
  10. Close and restart IIS.


Now let’s check to see if it’s working!

  1. Open Internet Explorer. (You can use any browser, but the feed is easier to read in IE.)
  2. Browse to http://[yourservername]:3333/sdata/$system/adapters.
  3. A log on prompt should appear. Make sure the dialog says “The server [yourservername] at SalesLogix Client requires a username and password.” If it is blank or says something else, something isn’t right.

  4. Enter any SalesLogix username and password, and then click OK.

    SData Logon
  5. You should now see your SalesLogix SData feed. Click on some of the links to see what kind of data is returned. For example, http://[yourservername]:3333/sdata/slx/dynamic/-accounts. You should see a list of all your SalesLogix accounts.

    SData Feed


Uh oh. It’s not working

If your SData feed did not appear, recheck your steps. The error message that you receive from your browser can tell you a lot. Check out this flow chart to see if your error matches any of these.

Troubleshoot SData

Another option is to visit the Sage SalesLogix community. Chances are, someone has already posted a question that relates to the same issue you might be having. If not, you can post your own and get answers from other Sage SalesLogix experts.

Also check out the Sage SalesLogix Customer Resource Center for links and other contact information for the Sage SalesLogix Support team.


*As of 7.5.3 HF3, when using Basic Authentication, you no longer need to configure the WebDLL user with ADMIN User.


Tags: , , , , , , ,

Use SData for everything! or not?

Posted by Jason Huber on May 10, 2010
Administrator, Developer / No Comments

Sometimes when we learn of a new technology we tend to want to use that technology for everything. In many cases this is a good thing, in other cases you end up pounding a square peg into a round hole. Perhaps the round hole hole is large enough to accommodate the square peg, but it is still not the best fit.

SData is a very nice square peg

You probably have several projects that SData can fit into. Perhaps integrating with a third party application or data loads from remote employees. Stuff like that. It makes sense to use SData when the systems are different enough — Java interfacing with ASP.NET — or far enough apart — the application is not able to communicate with the database via other means. It is ok to be excited about the newest method to retrieve data from SalesLogix. Once you understand SData and have learned to use the client libraries then the world is yours.

In SalesLogix training we usually get questions when something goes wrong not when new code is being written and everything is going fine. Recently we had the chance to work on a new project that was going just fine, but we were asked to work as developers on the project. The project was a web based project written in ASP.NET (C#) and would in all likelihood sit on the same web server as the slxclient portal. A request would come into this website against one of about 7 pages. It would contain an xml feed. The page would take the xml feed and fill it in with data from SalesLogix and return the filled in xml as the response.

Using SData you would have had the initial request to my page, the http request from my page to SData, and then SData‘s request to the database using the entity model. Since the new website sat on the same web server as SData, you can be sure that there is a port open (probably 1706) to the SalesLogix server, and that we could use ADO.NET to eliminate that last request from my webpage to SData.

The final result

The final result was we ended up with a website returning xml data which it retrieved using ADO.NET directly from the database. Nothing fancy — the same thing we have been doing for years. We were not using SData at all though. No client libraries were used just plain old ADO.NET and ASP.NET.

Other considerations

By not using SData we were also not using the entity model. This means any onbeforeupdate type events we had written will not be used. The argument can be made that these are important and if that is the case SData or working directly with the entity model is a good option. The learning curve of working directly with the entity model outside of SalesLogix might outweigh the gains initially, but the performance and code reuse benefits will certainly be there.

Tags:

SData Client Library Changes v1.1

Posted by Jason Huber on February 01, 2010
Developer / 1 Comment

It looks like the development team has taken the steps necessary to officially release the SData Client Libraries to Partners. There are a couple demo apps included and one is a rewrite of the app we use in our SData Master’s Series class! Well they took that app and updated the Client Libraries and together reduced the code we need to write by more than 25%.

What changed?

Really the payload was put into a dictionary. A simple explanation of a dictionary in C# is a multidimensional array. Most of the time you have a key and a value. So in our case this becomes the field name (or entity property name if you must) and the value. There are a few other changes as well, but this is the biggest.

What does this do for me, the developer?

This means that in order to get a value from an SData feed you need to get the payload and then request the field by name. Seem familiar? It is sort of like getting a recordset and asking for a field. In most cases we treat a recordset in ADO like a multidimensional array. This should be an easy transition for most of us.

In my opinion this makes the Client Libraries much more useful. As the (genius) develop put it: “the user no longer needs to know any xml.” – WOW. No more of the nil=true mistakes or missing a namespace.

Code

Some simple code changes (as outlined by the developer in the rewritten app:

Before:

doccontact = new XmlDocument();
    doccontact.LoadXml(entry.GetSDataPayload().OuterXml);
    nav = doccontact.CreateNavigator();
    manager = new XmlNamespaceManager(doccontact.NameTable);
    manager.AddNamespace("sdata", "http://schemas.sage.com/sdata/2008/1");
    manager.AddNamespace("slx", "http://schemas.sage.com/dynamic/2007");
    var prop = nav.SelectSingleNode("//slx:Address", manager);
    dr[3] = prop.SelectSingleNode("@sdata:key", manager).Value;

After:

dr[3] = ((SDataPayload) entry.GetSDataPayload().Values["Address"]).Key;

So this is a reduction of 8 lines of code.

Another example from the developer:
Before:

    XPathNavigator tempContactPayload = tempContactEntry.GetSDataPayload();
    //create the XML document for the new
    var doc = new XmlDocument();
    doc.LoadXml(tempContactPayload.OuterXml);
    //setup the navigator and namespace alias
    XPathNavigator navContact = doc.DocumentElement.CreateNavigator();
    XmlNamespaceManager managerTemplate = new XmlNamespaceManager(tempContactPayload.NameTable);
    managerTemplate.AddNamespace("slx", "http://schemas.sage.com/dynamic/2007");
    managerTemplate.AddNamespace("sdata", "http://schemas.sage.com/sdata/2008/1");
    managerTemplate.AddNamespace("xsi", "http://www.w3.org/2001/XMLSchema-instance");
    navContact.MoveToFirst();
    navContact.SelectSingleNode("//slx:FirstName", managerTemplate).SetValue(txtFirstName.Text.ToString());
    //delete xsi:null from payload...
    var nil = navContact.SelectSingleNode("//slx:FirstName", managerTemplate).SelectSingleNode("@xsi:nil", managerTemplate);
    if (nil != null) nil.DeleteSelf();
    //update the payload
    tempContactEntry.SetSDataPayload(navContact);

After:

    var tempContactPayload = tempContactEntry.GetSDataPayload();
    tempContactPayload.Values["FirstName"] = txtFirstName.Text;

So you can see this is much cleaner, easier and thus faster to develop against.

How can you tell which version you are using?

Well if you have downloaded anything from training prior to the date of this post you have the “old” version. This will usually mean the .Values from the above code will fail. So you can easily tell from that OR the new dll should have a version of 1.1 .

We will be offering an updated version of the SData class using the new and improved code. If you have attended the previous SData class you know there is no additional cost for you to attend and we plan on providing a simplified “what’s changed” version in that class as well.

Tags: ,

Basic Authentication in SData – is it there by default?

Posted by Jason Huber on December 14, 2009
Administrator, Developer / No Comments

No. It isn’t.

By default SData will use Digest Authentication. We talked about this a bit already here.

Enable it

In the web.config you can change the following section:

		<httpModules>
			<clear/>
			<add name="Session" type="System.Web.SessionState.SessionStateModule"/>
			<add name="AppManager" type="Sage.Platform.Application.UI.Web.AppManagerModule, Sage.Platform.Application.UI.Web"/>
			<add name="BasicAuthenticationModule" type="Sage.SalesLogix.Web.SLXWebBasicAuthenticationModule, Sage.SalesLogix.Web"/>

This allows the BasicAuthenticationModule to do it’s thing.

Tags: ,

SData client libraries – where to PUT them.

Posted by Jason Huber on December 07, 2009
Developer / No Comments

So we have completed our first set of SData Master’s Series classes and they have been a great success.

One of the points of this blog is to answer questions that do not fit into the various videos we have on SalesLogix in the Developer’s Subscription or in the various classes we offer for SalesLogix Web, Lan, Mobile, VA or even .NET Fundamentals.

Where do we put the client libraries?

The question was as simple as that. You get a DLL with the SalesLogix SData Client Libraries — where does it go?

The answer is easier than you might think: It goes somewhere that the application that references it can use it. Just like any other .NET assembly you would probably place it in the bin of the application using the client libraries or in the GAC if you have multiple applications on the same machine using it.

Why the confusion?

I think the confusion is due to the fact that people think the SData Client Libraries modify SData in some way. They certainly do not. They make consuming an SData feed or portal easier for the developer, so they go with the consuming application.

What are the considerations?

The considerations are that you must be using the correct version of the client libraries for the version of the SData portal for the version of SalesLogix you are using. This will be handled by the official delivery of the SData Client Libraries – which is coming soon through the partner community.

Right now we are talking about SData version 1.0 and SalesLogix web version 7.5.2.

In the meantime you can get them as part of the classfiles for our SData Master’s Series on SData here: Classfiles

Tags: ,

SData helper functions — C# code to make SData consumption easier

Posted by Jason Huber on November 11, 2009
Developer / No Comments

What about the Client Libraries?

The first thing that comes to mind when you read the title is “What about the SData Client Libraries?” The easy answer? They are here, they will work with SP2 and will be your first choice when starting an SData project with .NET.

What we have here are a set of helper functions that may do two things: 1. Help you understand what needs to be done in code to work with SData (increase your understanding) and 2. provide an outline for converting this sort of thing to another language (such as JavaScript or Java).

GETting some SData

To GET started you need to pull some data from SalesLogix SData. This usually requires some sort of http request and then parsing the response. We do this in a few methods:

  1. Download the XML passing in the URI (http address of the resource)
  2. Get the <entry> from the feed
  3. Work with some values in the feed

Download the XML

_user = “Lee”
and
_password = “”

1
2
3
4
5
6
7
8
9
10
11
12
13
 private string DownloadXML(string sUrl)
        {
            System.Net.WebClient client = new System.Net.WebClient();
            client.Encoding = Encoding.UTF8;
            client.Headers.Add(System.Net.HttpRequestHeader.ContentType, "application/atom+xml");
            client.Credentials = new System.Net.NetworkCredential(_User, _Password);
 
            string result = client.DownloadString(sUrl);
            client.Dispose();
            client = null;
            return result.Substring(1);
 
        }

Get the entry from the feed

Remember that the SData feed is an ATOM feed. You usually want the entry node from this feed. So let’s get that and work with it. This step makes parsing the xml later a bit easier.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
private string GetEntryFromFeed(string xinput, string entry)
        {
            var doc = new XmlDocument();
            doc.LoadXml(xinput);
 
            System.Xml.XPath.XPathNavigator xmlNav = doc.DocumentElement.CreateNavigator();
            var manager = new XmlNamespaceManager(doc.NameTable);
            XmlNamespaceManagerAddNamespacesforslx(ref manager);
            //get the first entry node and put the feed node back on (now you have a feed entry)
 
            XPathNodeIterator nav = xmlNav.Select(entry, manager);
            nav.MoveNext();
            return nav.Current.InnerXml;
 
            nav = null;
            manager = null;
            doc = null;
 
 
 
        }

and the call to this function is:

1
GetEntryFromFeed(results, "//atom:entry")

Which leads us into the issue with namespaces. You have several of them in this atom feed and each must be defined. You can see I called a function to set these up for me:

1
XmlNamespaceManagerAddNamespacesforslx(ref manager);

And all it does is add all the namespaces for me:

1
2
3
4
5
6
7
8
9
 private void XmlNamespaceManagerAddNamespacesforslx(ref XmlNamespaceManager xnsm)
        {
            xnsm.AddNamespace("xsi", "http://www.w3.org/2001/XMLSchema-instance");
            xnsm.AddNamespace("slx", "http://schemas.sage.com/dynamic/2007");
            xnsm.AddNamespace("sdata", "http://schemas.sage.com/sdata/2008/1");
            xnsm.AddNamespace("atom", "http://www.w3.org/2005/Atom");
            xnsm.AddNamespace("opensearch", "http://a9.com/-/spec/opensearch/1.1/");
            xnsm.AddNamespace("http", "http://schemas.sage.com/sdata/http/2008/1");
        }

Work with some values in the feed

Before I can work with the xml I need to get it into an XmlDocument:

1
2
            XmlDocument xmlTicket = new XmlDocument();
            xmlTicket.LoadXml("&lt;entry>" + GetEntryFromFeed(results, "//atom:entry") + "&lt;/entry>");

You can see that I re-add the <entry> node around the result from the function calls above.

The call to get a single value is here:

1
GetSingleValueFromxmldoc(xmldoc, "//slx:TicketNumber");

And what code is needed to get the value?

1
2
3
4
5
6
7
8
         private string GetSingleValueFromxmldoc(XmlDocument xdoc, string sNodeName)
        {
            var manager = new XmlNamespaceManager(xdoc.NameTable);
            XmlNamespaceManagerAddNamespacesforslx(ref manager);
 
            XmlNode xnode = xdoc.SelectSingleNode(sNodeName, manager);
            return  xnode.InnerText;
        }

So that is 4-5 simple helper functions for working with xml in C#. The same goes for JavaScript in FF. You do nearly the same operations. The major differences are that you do not need to specify the namespaces in any certain way:

xml.getElementsByTagName can be used and just pass in the actual node name.

Tags: , , ,

SData debugging — where can I find my errors?

Posted by Jason Huber on October 28, 2009
Developer / 2 Comments

When writing code against an SData feed you are bound to make some mistakes along the way. You will likely leave off a required field, miss a dependency, and a variety of other mistakes that will cause SData to respond with an error message. The good news is that these are well defined and contain a good deal of information to help you find what went wrong.

First you can look at the response that is returned:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<diagnosis xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sdata="http://schemas.sage.com/sdata/2008/1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:opensearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:sme="http://schemas.sage.com/sdata/sme/2007" xmlns:http="http://schemas.sage.com/sdata/http/2008/1">
  <sdata:severity>error</sdata:severity>
  <sdata:sdataCode>ApplicationDiagnosis</sdata:sdataCode>
  <sdata:applicationCode />
  <sdata:message>Exception caught during the processing of a message
 
Verb: GET
Uri: http://localhost:3333/sdata/slx/dynamic/-/Addresses?where=asdasdasd
 
Original Message: Unable to cast object of type 'NHibernate.Criterion.PropertyProjection' to type 'NHibernate.Criterion.ICriterion'.
 
Stack Trace:    at System.Linq.Enumerable.<CastIterator>d__aa`1.MoveNext()
   at Sage.Platform.SData.Dynamic.DynamicRequestBase`3.GetEntities(ISession session, SDataUri uri, Boolean isNested, Int64&amp; totalResults, Int32&amp; startIndex, Int32&amp; itemsPerPage)
   at Sage.Platform.SData.Dynamic.DynamicRequestBase`3.InternalGet(ISession session, IRequest request, Boolean isNested)
   at Sage.Platform.SData.Dynamic.DynamicRequestBase`3.DoGet(IRequest request)
   at Sage.Integration.Entity.Adapter.AddressRequest.GetAddresses(IRequest request) in c:\Documents and Settings\Administrator\Application Data\Sage\Platform\Output\sdata\Address.cs:line 68
   at Invokef7c9a0ead7974fb398c076d409441bb3.Invoke(Object , IRequest )
   at Sage.Integration.Messaging.RequestTargetRegistration.RequestTargetInvoker.Invoke(IRequest request)
   at Sage.Integration.Messaging.Request.Process(RequestTargetInvoker invoker)
   at Sage.Integration.Messaging.MessagingService.Process(IRequest request)
 
</sdata:message>

As defined by the SData spec sdata:severity can be Info, Warning, Transient, Error, or Fatal.
sdata:sdataCode is used to provide a bit more information. Some examples are BadUrlSyntax and BadQueryParameter

What I think is the most useful is the message and the response.status. If the HTTP response is not 200 or 301 (it is 400 or 500 series) then we have a problem and need to handle the response. In code this can all be handled in a try .. catch or an IF statement at worst. We are talking about debugging here so what can you do with the response?

If you are working with FireFox and Firebug (or IE8 and the dev tools) you can just look at the response:
SData_errorFF

if you are working with .NET the problem isn’t described so well. It is “hidden” from you a bit. You can still get to it, but it isn’t as easy. The good news? As defined in the log4net.config file in your SData portal all errors are also logged to the event log:
SData_errorEventViewer

What you do with the information will vary from case to case, but getting the information quickly as as completely is the important part when writing code. Remember you can always edit the Log4Net.config to log in a variety of ways. This is covered well in our developer classes and in the developer subscription.

Tags: , ,

SData changes in SP2 — what you need to know to upgrade your code

Posted by Jason Huber on October 22, 2009
Developer / No Comments

SP2 brings some changes to the SData portal within SalesLogix. In conversation we say something like “there is a new Payload node and some enhancements such as batch loading and transaction tracking.” Where does this leave your 7.5.0 or 7.5.1 SData code? Some changes are needed and here is the short and sweet of it.

First there is a new payload node. Sorry, but I had to point it out. What this really means is that you cannot just go to the <entry> node anymore. You still need the <entry> node for the etag and some other things, but the actual data you want is actually two nodes down.

Also the URL has changed. Really a /-/ was added. Instead of:


'Dim result As String = client.DownloadString("http://localhost:3333/sdata/slx/dynamic/addresses")

you need this:


Dim result As String = client.DownloadString("http://localhost:3333/sdata/slx/dynamic/-/addresses")

That was easy.

If you look at the xml that you get back (in either case) you will see some namespaces defined at the top. Things like http, slx, sdata with a url at the end. These correspond to elements in your result. You need to have a XNamespace for each of these:


ReadOnly cf As XNamespace = XNamespace.Get("http://www.microsoft.com/schemas/rss/core/2005")
ReadOnly atom As XNamespace = XNamespace.Get("http://www.w3.org/2005/Atom")
ReadOnly slx As XNamespace = XNamespace.Get("http://schemas.sage.com/dynamic/2007")
ReadOnly sdata As XNamespace = XNamespace.Get("http://schemas.sage.com/sdata/2008/1")
ReadOnly xhttp As XNamespace = XNamespace.Get("http://schemas.sage.com/sdata/http/2008/1")

What this allow you to do is something like:


entry = (From Entry In doc.Descendants(atom + "entry") Select Entry).First()
etag = entry.Element(xhttp + "etag").Value

Now the code above is both LINQ and some xml manipulation. Basically the node called <entry> is within the atom namespace (because it is not specified) and I can get each one. I only want the first in this example because I am selecting an address by id (not shown).

Then I retrieve the etag using the xhttp namepace I declared above and the tag etag. This represents a hash of the entity and if this etag does not match when I PUT an update then I will receive an error telling me that the address I am trying to change has changed since I last got (GET) it.

I will use this etag later to place an if-match header when I try and update (PUT) later:


client.Headers.Add(HttpRequestHeader.ContentType, "application/atom+xml;type=entry")
client.Headers.Add(HttpRequestHeader.IfMatch, etag)
client.UploadString(putURI, "PUT", putPayload)

What else changed?

When you go to get the values for the actual address you need to get past the <entry> and into the <sdata:payload> and then you can get to your entity:


address = (From Entry In doc.Descendants(slx + "Address") Select Entry).First()

Again, LINQ and slx from the XNameSpace from above. In my example I am only getting one address, so I get the first one. (not shown).

The address will not contain the entry node or the payload node so you can add these back on:


Dim putPayload As String = " " & address.ToString() & ""

Now there are 101 ways to get this done and this is one way. Give it a try and editing your existing code to work with the new SP2 changes should be a piece of cake.

Tags: , , , ,