Updating an Entity Using REST (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 Updating an Entity Using REST, the following C# sample the application illustrates a non-blob entity update. The application performs the following steps:

  • Create an XML payload describing a sample book entity.
  • Send a POST request to create the entity. In the request the application sets the Content-Type request header to application/x-ssds+xml indicating XML payload.
  • Send a GET request to retrieve the entity.
  • Load the response string into an XmlDocument object.
  • Add a new property (<year>) to the book XML
  • Serialize the XmlDocument object back to a string.
  • Send the updated string back in a PUT request.

Note

Credentials are required to access the service. To make a working sample, update following code and provide your existing authority id, container id and a unique id for the sample entity.

If you are using the Microsoft Visual Studio integrated development environment, create a console application and add the following code.

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

namespace UpdateEntityUsingREST
{
    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 = "<IdForSampleEntity>";

        private const string HttpGetMethod = "GET";
        private const string HttpPutMethod = "PUT";
        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
            {
                // Send request to create book entity
                String bookUri = CreateEntity(containerUri, requestPayload);
                if (bookUri == null)
                {
                    Console.WriteLine("Book URI is null... problem creating sample entity");
                    return;
                }

                string data = GetEntity(bookUri);

                // Load book XML in
                XmlDocument bookXML = new XmlDocument();
                bookXML.LoadXml(data);
                // Update data by adding new flex property "Year" 
                XmlElement newElem = bookXML.CreateElement("year");
                newElem.InnerXml = "2005";
                newElem.SetAttribute("type", "http://www.w3.org/2001/XMLSchema-instance", "x:string");
                bookXML.DocumentElement.AppendChild(newElem);
                string updatedData = bookXML.OuterXml;

                // Send updated entity back 
                HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(bookUri);
                request.Method = HttpPutMethod; 
                UTF8Encoding encoding = new UTF8Encoding();
                request.ContentLength = encoding.GetByteCount(updatedData);
                request.ContentType = ssdsContentType;
                request.Credentials = new NetworkCredential(userName, password);

                // Write the request data over the wire.
                using (Stream reqStm = request.GetRequestStream())
                {
                    reqStm.Write(encoding.GetBytes(updatedData), 0,
                                 encoding.GetByteCount(updatedData));
                }

                // Get the response and read it in to a string.
                using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
                {
                    if (response.StatusCode == HttpStatusCode.OK)
                    {
                        Console.WriteLine("Entity update. Newer entity version: {0}", response.Headers["ETag"]);
                    }
                    else
                    {
                        Console.WriteLine("Unexpected status code returned: {0}", response.StatusCode);
                    }
                }
            }
            catch (WebException ex)
            {
                using (HttpWebResponse response = ex.Response as HttpWebResponse)
                {
                    if (response != null)
                    {
                        string errorMsg = ReadResponse(response);
                        Console.WriteLine(string.Format("Error:{0}", errorMsg));
                        Console.WriteLine("Unexpected status code returned: {0} ", response.StatusCode);
                    }
                }
            }
        }

        public static string CreateBook(string id, string title, string summary,
                                        string isbn, string author, string publisher)
        {
            
            const string EntityTemplate =
                @"<Book xmlns:s='https://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 GetEntity(string entityUri)
        {
            string data = null;

            if (string.IsNullOrEmpty(entityUri))
            {
                throw new ArgumentOutOfRangeException("entityUri");
            }

            try
            {
                // retrieve
                WebRequest request = HttpWebRequest.Create(entityUri);
                request.Method = HttpGetMethod;
                //request.ContentLength = 0;
                request.ContentType = ssdsContentType;
                request.Credentials = new NetworkCredential(userName, password);

                using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
                {
                    data = ReadResponse(response);
                    if (response.StatusCode != HttpStatusCode.OK)
                    {
                        Console.WriteLine("Error: {0}", data);
                        Console.WriteLine("Unexpected status code returned: {0}", response.StatusCode);
                    }
                }
            }
            catch (WebException ex)
            {
                using (HttpWebResponse response = ex.Response as HttpWebResponse)
                {
                    if (response != null)
                    {
                        string errorMsg = ReadResponse(response);
                        Console.WriteLine("Error:{0}", errorMsg);
                        Console.WriteLine("Unexpected status code returned: {0}", response.StatusCode);
                        throw ex;
                    }
                }
            }

            return data;
        }

        public static string CreateEntity(string containerUri, string requestPayload)
        {
            const string HttpPostMethod = "POST";
            const string ssdsContentType = "application/x-ssds+xml";
            string entityUri = null;

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

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

            try
            {
                // Create the request to send.
                WebRequest request = HttpWebRequest.Create(containerUri);
                request.Credentials = new NetworkCredential(userName, password);
                // POST=create; PUT=update; DELETE=delete; GET=retrieve
                request.Method = HttpPostMethod;
                UTF8Encoding encoding = new UTF8Encoding();
                request.ContentLength = encoding.GetByteCount(requestPayload);
                request.ContentType = ssdsContentType;

                // Write the request data over the wire.
                using (Stream reqStm = request.GetRequestStream())
                {
                    reqStm.Write(encoding.GetBytes(requestPayload), 0,
                                 encoding.GetByteCount(requestPayload));
                }

                // Get the response and read it in to a string.
                using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
                {

                    if (response.StatusCode == HttpStatusCode.Created)
                    {
                        Console.WriteLine("Entity created. System assigned version: {0}", response.Headers["ETag"]);
                        // Since current implementation returns response.Headers[HttpResponseHeader.Location]
                        // value null, construct entity URI
                        entityUri = string.Format(containerUri + "/" + sampleEntityId);
                    }
                    else
                    {
                        Console.WriteLine("Unexpected status code returned: {0}", response.StatusCode);
                    }
                }
            }
            catch (WebException ex)
            {
                string errorMsg = ex.Message;
                if (ex.Response != null)
                {
                    using (HttpWebResponse response = ex.Response as HttpWebResponse)
                    {
                             errorMsg = ReadResponse(response);
                            Console.WriteLine(string.Format("Error:{0}", errorMsg));
                            Console.WriteLine("Unexpected status code returned: {0} ", response.StatusCode);
                    }
                }
                Console.WriteLine("Entity creation failed: {0}", errorMsg);

            }

            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();
        }

    }
}

To verify the update, enter the entity URI in the browser.

https://<authority-id>.data.database.windows.net/v1/<container-id>/<entity-id>

See Also

Concepts

Updating an Entity Using REST