Archive

Posts Tagged ‘ASMX’

Web Services and Date Values

February 4, 2011 Leave a comment

From time to time we are contacted by developers who are confused about the handling of Date values by the Store 4 platform. To help clarify this, I’d like to present these three things that every developer MUST be aware of when writing code for the Store 4 web services:

All Date values have times associated with them.

The most important thing to remember is that Date values are not just arbitrary; they represent a specific moment in time. So when you see the value “1-1-2011”, you need to be aware that it actually represents “1-1-2011 12:00:00 AM”.

All Date values have time zones associated with them.

Following the same pattern, all Date values contain time zone information–whether you see it or not. Most software platforms consider Date values to be in local time by default, so that’s most likely a safe assumption for any client. XML, as a universal data format, is an example of this: If you look at any Date parameters in XML, you can plainly see the time zone information there. When an XML Date parameter reaches the Store 4 servers, it is translated into local server time before being processed.

This is done for 2 reasons:

  1. The server is like any other platform in that it prefers to work in local time.
  2. As stated above, the Date value represents a specific moment in time. Midnight in New York is the same moment in time as 10:00 PM the previous day Utah; so converting the value to local time is really the more accurate approach.

But here’s the real kicker that causes the most confusion:

Store uses Mountain time for all date values.

The Store client and server treat all dates as if they were in Mountain time, regardless of the client’s actual location. This includes daylight savings time as well. So when a site in New York records a transaction at 1:00 PM Eastern time, Store actually saves it as 11:00 AM Mountain time in the database. The same thing happens with a site in California: A transaction at 1:00 PM Pacific time is recorded as 2:00 PM Mountain time.

We definitely want to find a more robust solution for this in the future. It’s obviously not an approach that will work well on a global scale; but for the time being we’re only in the U.S. market and it makes reporting much easier for the users if they don’t have to consider time zones.

The downside to this is that special consideration must be taken by our web service clients. We handle all the time zone conversions in our own client, but any custom clients must do the same. So let’s walk through an example to see how the whole process works.

Let’s suppose a client in New York wants to pull down its list of transactions for a single day–January 1st, 2011. The client would create a request message using these Start and End dates:

  • StartDate = 1-1-2011
  • EndDate = 1-2-2011

Now, different client technologies may encode the date in slightly different formats in XML. It’s important to find out how your particular technology serializes dates, so you can adjust accordingly. But when the message is sent to Store, it will probably look something like this:

  • <StartDate>2011-01-01T00:00:00-05:00</StartDate>
  • <EndDate>2011-01-02T00:00:00-05:00</EndDate>

Note the time and time zone information that was automatically included with the values. The server will take these values and convert them to its own local time (MST), so the values will then be:

  • StartDate = 12-31-2011 10:00:00 PM
  • EndDate = 1-1-2011 10:00:00 PM

Now when the query executes on the server using these values, you can see that it will be off by two hours, and the data returned may be inaccurate. To counteract this, the client needs to shift its date values by its own local offset from MST. So, since New York is 2 hours ahead of MST, they should add 2 hours to all of its date values before sending them to Store–that way they’ll be converted to the correct time in MST, and the query will return the desired results. By the same token, any date values returned from the web services will probably be automatically converted to the client’s local time (EST in this case), so they should remove 2 hours from each date value coming back to make sure they are used consistently.

Categories: API General Tags: ,

ASMX vs. SVC

January 31, 2011 Leave a comment

The web services in Store are all based on Microsoft’s WCF technology instead of the older ASMX model. While this has been a huge boost in flexibility for Store, it has led to some confusion for some of our clients. In this article, I’ll attempt to explain the differences between the two and the reason why Store 4 is built the way it is. (This may get a little technical, so hang on!) Let’s start at the beginning:

In Store 3.1, the web services were written using ASMX. That allowed us to easily expose all kinds of internal datatypes as XML – and since many of our services returned tables of data, it seemed like a logical solution to simply return .NET DataSet objects to our clients. However, since a .NET DataSet is only defined at runtime, the WSDL schema definitions for those tables don’t know what they will look like. As a result, the WSDL file uses a simple tag to represent the table: <xml:any> This tag is basically the XML equivalent of “Object” or “Var”. It is type-less. It means that when a client calls this service, they will receive a blob of unidentified XML in this location. It is then up to the client to parse through the XML, figure out what it means, and do something with it.

Now, when Microsoft technology is used on the client side, it knows what this XML means and automatically converts it into a .NET DataSet for the client to consume. But for any other clients, the XML coming down from the server has to be parsed manually. It’s not very fun, and no one wants to do it. Because of this, the use of .NET DataSets in XML web services is commonly viewed as a “Microsoft-specific practice” and not very cross-platform compatible (even though technically it can still be used by any client.)

So for Store 4, we decided to go in a direction that is more accessible to the mainstream. We now have clearly-defined XML structures for every request, response, and object we move across the wire. The services should now be completely compatible with any modern web service client technology. Except

A single, ginormous WSDL file with everything in it is considered by some in the industry to be a bad XML practice. The argument is that the XML should be neatly parsed into a few separate files, and <xml:Import> tags be used to combined them on-the-fly into a single WSDL definition. Microsoft has adopted this philosophy, and the new WCF engine generates its WSDL files in a few distinct pieces – which is then left to the client to compile into a single WSDL contract. The problem is that some (usually older) client-side technologies do not yet support the <xml:Import> command. when these clients connect to a WCF web service, they download the main WSDL file but not all the other related pieces that contain the actual “meat” of the web service. Some clients view this action too as being Microsoft-specific; but it’s actually not, it’s an industry standard.

So – How can a client connect to SWS using older client technology? One flexibility provided to us by WCF is that we can expose our services through multiple endpoints without changing any code. So in addition to the default WCF endpoint (SWS.svc), we can also expose our services using the older ASMX engine (SWS.asmx) with minimal adjustments. And this second, ASMX endpoint generates an almost identical WSDL definition, but as a single file instead of split up into pieces.

Currently we’ve only exposed our main web service bundle in this way (SWS). But over the while we’ll be creating ASMX copies of our other web services as well. The .svc version is still the endpoint we recommend to all our clients; but if you’re having trouble connecting to it, then by all means give the .asmx version a try. Our goal is to provide complete compatibility with all platforms – and we’ll do what we need to do to make that a reality!

Categories: API General Tags: , , , ,