SDS
Conditional GET Operation using REST Interface (C#)
[This document supports a preliminary release of a software product that may be changed substantially prior to final commercial release. This document is provided for informational purposes only.]

As described in Conditional Operations using REST Interface (C#), the following example illustrates the conditional GET operation.

The example first creates a sample "book" entity in the service and then sends a conditional GET request to retrieve the entity if the service has an updated version of it (potentially modified by some other application). For conditional GET the application sets the If-None-Match HTTP request header value to the entity version it has in its local cache. If the service has different version of the entity (modified by some other application), the GET retrieves the modified entity. Otherwise, the application handles the "NotModifed" condition. To test the application, you could add break point after the test entity is created, update entity using SSDS Explorer which creates a new entity version in the service and then continue with this application.

CSharp
using System;
using System.Text;
using System.Net;
using System.Xml;
using System.IO;
using System.Xml.Linq;

namespace ConditionalGetREST
{
    class Program
    {
        // Provide your data here
        private static string userName;
        private static string password;
        private const string authorityId = "<YourExistingAuthorityId>"; 
        private const string containerId = "<YourExistingContainerId>";     
        private const string sampleEntityId = "<SampleEntityId>";

        // HTTP constants
        private const string HttpGetMethod = "GET";
        private const string HttpPutMethod = "PUT";
        private const string HttpPostMethod = "POST";
        private const string ssdsContentType = "application/x-ssds+xml";

        static void Main(string[] args)
        {
            Console.Write("Username: ");
            userName = Console.ReadLine();
            Console.Write("Password: ");
            password = ReadPassword();

            string containerUri = String.Format("https://{0}.data.database.windows.net/v1/{1}",
                                                authorityId, containerId);

            // Data going over to the server
            string requestPayload = CreateBook(sampleEntityId, "My first used book using REST",
                                               "Some summary", "1-57880-057-9",
                                               "Author A", "Publisher B");

            try
            {
                // Begin by creating the entity.
                string eTag;
                String bookUri = CreateEntity(containerUri, requestPayload, out eTag);
                if (String.IsNullOrEmpty(bookUri))
                {
                    // Encountered an error so exit.
                    return;
                }

                // Next, try to retrieve the entity we just created but only do so if the 
                // entity has been modified.
                string data = ConditionallyRetrieveEntity(bookUri, eTag);
                Console.WriteLine("Server returned {0}", data);
            }
            catch (WebException ex)
            {
                if (ex.Response != null)
                {
                    using (HttpWebResponse response = ex.Response as HttpWebResponse)
                    {
                        if (response.StatusCode == HttpStatusCode.NotModified)
                        {
                            Console.WriteLine("Entity has not been updated since your last request");
                        }
                        else
                        {
                            Console.WriteLine("Unexpected status code returned: {0}", response.StatusCode);
                            Console.WriteLine("Error: {0}", ReadResponse(response));
                        }
                    }
                }
            }
        }

        public static string CreateBook(string id, string title, string summary,
                                        string isbn, string author, string publisher)
        {

            const string EntityTemplate =
                @"<Book xmlns:s='http://schemas.microsoft.com/sitka/2008/03/'
                         xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
                         xmlns:x='http://www.w3.org/2001/XMLSchema' >
                     <s:Id>{0}</s:Id> 
                     <title xsi:type='x:string'>{1}</title>
                     <summary xsi:type='x:string'>{2}</summary> 
                     <isbn xsi:type='x:string'>{3}</isbn> 
                     <author xsi:type='x:string'>{4}</author> 
                     <publisher xsi:type='x:string'>{5}</publisher> 
                 </Book>";
            return String.Format(EntityTemplate, id, title, summary, isbn, author, publisher);

        }

        private static string ConditionallyRetrieveEntity(string entityUri, string eTag)
        {
            string data = null;

            // Check inbound parameters
            if (string.IsNullOrEmpty(entityUri))
            {
                throw new ArgumentOutOfRangeException("entityUri");
            }
            // Create the request that we'll use to retrieve the Entity.
            WebRequest request = HttpWebRequest.Create(entityUri);
            request.Method = HttpGetMethod;

            // Set the If-None-Match Http request header value to be the passed
            // in ETag.  This will ensure that we only retrieve the entity again if it
            // has changed.
            request.Headers[HttpRequestHeader.IfNoneMatch] = eTag;
            request.ContentLength = 0;
            request.ContentType = ssdsContentType;
            request.Credentials = new NetworkCredential(userName, password);

            // Next, Get the response.
            using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
            {
                // Then, read in the response body.
                data = ReadResponse(response);
                if (response.StatusCode != HttpStatusCode.OK)
                {
                    Console.WriteLine("Unexpected status code returned: {0}", response.StatusCode);
                    Console.WriteLine(data);
                }
            }

            return data;
        }

        public static string CreateEntity(string containerUri, string requestPayload, out string eTag)
        {
            string entityUri = null;
            eTag = null;

            // Check Inbound Parameters
            if (String.IsNullOrEmpty(containerUri))
            {
                throw new ArgumentOutOfRangeException(containerUri);
            }

            if (String.IsNullOrEmpty(requestPayload))
            {
                throw new ArgumentOutOfRangeException(requestPayload);
            }

            try
            {
                // Create the request that will be used to create the entity.
                WebRequest request = HttpWebRequest.Create(containerUri);
                request.Credentials = new NetworkCredential(userName, password);
                request.Method = HttpPostMethod;
                UTF8Encoding encoding = new UTF8Encoding();
                request.ContentLength = encoding.GetByteCount(requestPayload);
                request.ContentType = ssdsContentType;

                // Begin to transfer the request to the service.
                using (Stream reqStm = request.GetRequestStream())
                {
                    reqStm.Write(encoding.GetBytes(requestPayload), 0,
                                 encoding.GetByteCount(requestPayload));
                }

                // Retrieve the response from the service.
                using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
                {
                    if (response.StatusCode != HttpStatusCode.Created)
                    {
                        Console.WriteLine("Unexpected status code returned: {0}", response.StatusCode);
                        return null;
                    }

                    // get the Version # assigned by the service to the the entity you created.
                    eTag = response.Headers[HttpResponseHeader.ETag];

                    entityUri = String.Format(containerUri + "/" + sampleEntityId);
                }
            }
            catch (WebException ex)
            {
                if (ex.Response != null)
                {
                    using (HttpWebResponse errorResponse = (HttpWebResponse)ex.Response)
                    {
                        string errorMsg = ReadResponse(errorResponse);
                        Console.WriteLine("Error:{0}", errorMsg);
                        Console.WriteLine("Unexpected status code returned: {0} ", errorResponse.StatusCode);
                    }
                }
            }

            return entityUri;
        }

        public static string ReadResponse(HttpWebResponse response)
        {
            // Begin by validating our inbound parameters.
            if (response == null)
            {
                throw new ArgumentNullException("response", "Value cannot be null");
            }

            // Then, open up a reader to the response and read the contents to a string
            // and return that to the caller.
            string responseBody = "";
            using (Stream rspStm = response.GetResponseStream())
            {
                using (StreamReader reader = new StreamReader(rspStm))
                {
                    responseBody = reader.ReadToEnd();
                }
            }

            return responseBody;
        }

        private static string ReadPassword()
        {
            StringBuilder retval = new StringBuilder();
            ConsoleKeyInfo keyInfo;
            while ((keyInfo = Console.ReadKey(true)).Key != ConsoleKey.Enter)
            {
                Console.Write("*");
                retval.Append(keyInfo.KeyChar);
            }
            Console.WriteLine();

            return retval.ToString();
        }

    }
}
See Also

Concepts

Conditional Operations using REST Interface (C#)

Page view tracker