Click here to Skip to main content
15,891,529 members
Articles / Web Development / CSS

Building a 3-Tier App with Silverlight 3, .NET RIA Services, and Azure Table Storage

Rate me:
Please Sign up or sign in to vote.
4.89/5 (28 votes)
11 Jul 2009CDDL19 min read 165.1K   1.7K   148  
This article presents the techniques and caveats of building a 3-tire Azure hosted application using Silverlight 3 (presentation tier), .NET RIA services (business logic and data access), and Windows Azure Table (data storage).
//
// <copyright file="RestQueue.cs" company="Microsoft">
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// </copyright>
//
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
using System.Net;
using System.Collections.Specialized;
using System.IO;
using System.Xml;
using System.Diagnostics;
using System.Globalization;
using System.Threading;


namespace Microsoft.Azure.StorageClient
{

    internal class QueueStorageRest : QueueStorage
    {
        private SharedKeyCredentials _credentials;

        internal QueueStorageRest(StorageAccountInfo accountInfo)
            : base(accountInfo)
        {
            byte[] key = null;
            if (accountInfo.Base64Key != null)
            {
                key = Convert.FromBase64String(accountInfo.Base64Key);
            }
            _credentials = new SharedKeyCredentials(accountInfo.AccountName, key);
        }

        /// <summary>
        /// Get a reference to a Queue object with a specified name. This method does not make a call to
        /// the queue service.
        /// </summary>
        /// <param name="queueName">The name of the queue</param>
        /// <returns>A newly created queue object</returns>
        public override MessageQueue GetQueue(string queueName)
        {
            return new QueueRest(queueName,
                                 AccountInfo, 
                                 Timeout,
                                 RetryPolicy
                                 );
        }

        internal class ListQueueResult
        {
            internal ListQueueResult(IEnumerable<string> names, IEnumerable<string> urls, string nextMarker)
            {
                Names = names;
                Urls = urls;
                NextMarker = nextMarker;
            }

            internal IEnumerable<string> Names
            {
                get;
                private set;
            }

            internal IEnumerable<string> Urls
            {
                get;
                private set;
            }

            internal string NextMarker
            {
                get;
                private set;
            }
        }

        /// <summary>
        /// Lists all queues with a given prefix within an account.
        /// </summary>
        /// <param name="prefix"></param>
        /// <returns>The list of queue names.</returns>
        public override IEnumerable<MessageQueue> ListQueues(string prefix)
        {
            string marker = "";
            const int maxResults = StorageHttpConstants.ListingConstants.MaxQueueListResults;

            do
            {
                ListQueueResult result = ListQueuesImpl(prefix, marker, maxResults);
                if (result == null)
                {
                    marker = null;
                }
                else
                {
                    marker = result.NextMarker;

                    foreach (string name in result.Names)
                    {
                        yield return new QueueRest(name, AccountInfo, this.Timeout, this.RetryPolicy);
                    }
                }
            } while (marker != null);
        }

        /// <summary>
        /// Lists the queues within the account.
        /// </summary>
        /// <returns>A list of queues</returns>
        private ListQueueResult ListQueuesImpl(string prefix, string marker, int maxResult)
        {
            ListQueueResult result = null;

            RetryPolicy(() =>
            {
                NameValueCollection col = new NameValueCollection();
                col.Add(StorageHttpConstants.QueryParams.QueryParamComp, StorageHttpConstants.CompConstants.List);
                if (!string.IsNullOrEmpty(prefix))
                {
                    col.Add(StorageHttpConstants.QueryParams.QueryParamPrefix, prefix);
                }
                if (!string.IsNullOrEmpty(marker))
                {
                    col.Add(StorageHttpConstants.QueryParams.QueryParamMarker, marker);
                }
                col.Add(StorageHttpConstants.QueryParams.QueryParamMaxResults, maxResult.ToString(CultureInfo.InvariantCulture));

                ResourceUriComponents uriComponents;
                Uri uri = Utilities.CreateRequestUri(
                                        AccountInfo.BaseUri,
                                        AccountInfo.UsePathStyleUris,
                                        AccountInfo.AccountName,
                                        null,
                                        null,
                                        Timeout,
                                        col,
                                        out uriComponents
                                        );
                HttpWebRequest request = Utilities.CreateHttpRequest(uri, StorageHttpConstants.HttpMethod.Get, Timeout);
                _credentials.SignRequest(request, uriComponents);

                try
                {
                    using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
                    {
                        if (response.StatusCode == HttpStatusCode.OK)
                        {
                            using (Stream stream = response.GetResponseStream())
                            {
                                result = GetQueuesFromResponse(stream);
                                stream.Close();
                            }
                        }
                        else
                        {
                            Utilities.ProcessUnexpectedStatusCode(response);
                        }
                        response.Close();
                    }
                }
                catch (WebException we)
                {
                    throw Utilities.TranslateWebException(we);
                }
            });

            return result;
        }

        private static ListQueueResult GetQueuesFromResponse(Stream stream)
        {
            ListQueueResult result = null;
            List<string> names = new List<string>();
            List<string> urls = new List<string>();
            string nextMarker = null;

            XmlDocument doc = new XmlDocument();
            try
            {
                doc.Load(stream);
            }
            catch (XmlException xe)
            {
                throw new StorageServerException(StorageErrorCode.ServiceBadResponse,
                    "The result of a ListQueue operation could not be parsed", default(HttpStatusCode), xe);
            }

            // get queue names and urls
            XmlNodeList queueNameNodes = doc.SelectNodes(XPathQueryHelper.QueueListQuery);
            foreach (XmlNode queueNameNode in queueNameNodes)
            {
                string queueName = XPathQueryHelper.LoadSingleChildStringValue(queueNameNode, StorageHttpConstants.XmlElementNames.QueueName, true);
                names.Add(queueName);
                string url = XPathQueryHelper.LoadSingleChildStringValue(queueNameNode, StorageHttpConstants.XmlElementNames.Url, true);
                urls.Add(url);
            }

            // Get the nextMarker
            XmlNode nextMarkerNode = doc.SelectSingleNode(XPathQueryHelper.NextMarkerQuery);
            if (nextMarkerNode != null && nextMarkerNode.FirstChild != null)
            {
                nextMarker = nextMarkerNode.FirstChild.Value;
            }
            if (names.Count > 0)
            {
                Debug.Assert(names.Count == urls.Count);
                result = new ListQueueResult(names, urls, nextMarker);
            }
            return result;
        }
    }

    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1001:TypesThatOwnDisposableFieldsShouldBeDisposable", 
                                                     Justification = "Disposable types are only used for automatic receiving of messages, which handle the disposal themselves.")]
    internal class QueueRest : MessageQueue
    {
        #region Member variables and constructors

        private Uri _queueUri;
        private SharedKeyCredentials _credentials;
        private int _pollInterval = DefaultPollInterval;


        internal QueueRest(
                    string name,
                    StorageAccountInfo account,
                    TimeSpan timeout,
                    RetryPolicy retryPolicy
                    )
            : base(name, account)
        {
            byte[] key = null;
            if (AccountInfo.Base64Key != null)
            {
                key = Convert.FromBase64String(AccountInfo.Base64Key);
            }
            ResourceUriComponents uriComponents = new ResourceUriComponents(account.AccountName, name, null);
            _credentials = new SharedKeyCredentials(AccountInfo.AccountName, key);
            _queueUri = HttpRequestAccessor.ConstructResourceUri(account.BaseUri, uriComponents, account.UsePathStyleUris);
            Timeout = timeout;
            RetryPolicy = retryPolicy;
        }
        #endregion

        #region Public interface

        public override Uri QueueUri
        {
            get
            {
                return _queueUri;
            }
        }

        public override bool CreateQueue(out bool queueAlreadyExists)
        {
            bool result = false;
            queueAlreadyExists = false;
            // cannot use ref or out parameters in the retry expression below
            bool exists = false;

            RetryPolicy(() =>
            {
                ResourceUriComponents uriComponents;
                Uri uri = CreateRequestUri(null, new NameValueCollection(), false, out uriComponents);
                HttpWebRequest request = CreateHttpRequest(uri, StorageHttpConstants.HttpMethod.Put);
                _credentials.SignRequest(request, uriComponents);

                try
                {
                    using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
                    {
                        if (response.StatusCode == HttpStatusCode.Created)
                        {
                            // as an addition we could parse the result and retrieve
                            // queue properties at this point
                            exists = false;
                            result = true;
                        }
                        else if (response.StatusCode == HttpStatusCode.NoContent)
                        {
                            exists = true;
                        }
                        else
                        {
                            Utilities.ProcessUnexpectedStatusCode(response);
                        }
                        response.Close();
                    }
                }
                catch (WebException we)
                {
                    if (we.Response != null && 
                        ((HttpWebResponse)we.Response).StatusCode == HttpStatusCode.Conflict)
                    {
                        exists = true;
                    }
                    else
                    {
                        throw Utilities.TranslateWebException(we);
                    }
                }
            });

            queueAlreadyExists = exists;
            return result;
        }

        public override bool DeleteQueue()
        {
            bool result = false;

            RetryPolicy(() =>
            {
                NameValueCollection col = new NameValueCollection();                
                
                ResourceUriComponents uriComponents;
                Uri uri = CreateRequestUri(null, col, false, out uriComponents);
                HttpWebRequest request = CreateHttpRequest(uri, StorageHttpConstants.HttpMethod.Delete);
                _credentials.SignRequest(request, uriComponents);

                try
                {
                    using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
                    {
                        if (response.StatusCode == HttpStatusCode.NoContent)
                        {
                            result = true;
                        }
                        else
                        {
                            Utilities.ProcessUnexpectedStatusCode(response);
                        }
                        response.Close();
                    }
                }
                catch (WebException we)
                {
                    if (we.Response != null &&
                        (((HttpWebResponse)we.Response).StatusCode == HttpStatusCode.NotFound ||
                         ((HttpWebResponse)we.Response).StatusCode == HttpStatusCode.PreconditionFailed ||
                         ((HttpWebResponse)we.Response).StatusCode == HttpStatusCode.Conflict))
                    {
                        result = false;
                    }
                    else
                    {
                        throw Utilities.TranslateWebException(we);
                    }
                }
            });

            return result;
        }

        public override bool SetProperties(QueueProperties properties)
        {
            if (properties == null)
            {
                throw new ArgumentNullException("properties");
            }

            bool result = false;

            RetryPolicy(() =>
            {
                NameValueCollection col = new NameValueCollection();
                col.Add(StorageHttpConstants.QueryParams.QueryParamComp, StorageHttpConstants.CompConstants.Metadata);

                ResourceUriComponents uriComponents;
                Uri uri = CreateRequestUri(null, col, out uriComponents);
                HttpWebRequest request = CreateHttpRequest(uri, StorageHttpConstants.HttpMethod.Put, properties.Metadata);
                _credentials.SignRequest(request, uriComponents);

                try
                {
                    using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
                    {
                        if (response.StatusCode == HttpStatusCode.NoContent)
                        {
                            result = true;
                        }
                        else
                        {
                            Utilities.ProcessUnexpectedStatusCode(response);
                        }
                        response.Close();
                    }
                }
                catch (WebException we)
                {
                    throw Utilities.TranslateWebException(we);
                }
            });

            return result;
        }

        public override QueueProperties GetProperties()
        {
            QueueProperties result = null;

            RetryPolicy(() =>
            {
                NameValueCollection col = new NameValueCollection();
                col.Add(StorageHttpConstants.QueryParams.QueryParamComp, StorageHttpConstants.CompConstants.Metadata);

                ResourceUriComponents uriComponents;
                Uri uri = CreateRequestUri(null, col, out uriComponents);
                HttpWebRequest request = CreateHttpRequest(uri, StorageHttpConstants.HttpMethod.Get, null);
                _credentials.SignRequest(request, uriComponents);

                try
                {
                    using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
                    {
                        if (response.StatusCode == HttpStatusCode.OK)
                        {
                            result = GetPropertiesFromHeaders(response);
                        }
                        else
                        {
                            Utilities.ProcessUnexpectedStatusCode(response);
                        }
                        response.Close();
                    }
                }
                catch (WebException we)
                {
                    throw Utilities.TranslateWebException(we);
                }
            });

            return result;
        }

        public override int ApproximateCount()
        {
            QueueProperties props = GetProperties();
            return props.ApproximateMessageCount;
        }

        // getting and putting messages

        public override bool PutMessage(Message msg)
        {
            return PutMessage(msg, -1);
        }

        public override bool PutMessage(Message msg, int timeToLiveInSeconds)
        {
            if (timeToLiveInSeconds < -1)
            {
                throw new ArgumentException("ttl parameter must be equal or larger than 0.");
            }
            else if (timeToLiveInSeconds > Message.MaxTimeToLive)
            {
                throw new ArgumentException(string.Format(CultureInfo.InvariantCulture,
                    "timeToLiveHours parameter must be smaller or equal than {0}, which is 7 days in hours.", Message.MaxTimeToLive));
            }
            if (msg == null || msg.ContentAsBytes() == null)
            {
                throw new ArgumentNullException("msg");
            }
            if (Convert.ToBase64String(msg.ContentAsBytes()).Length > Message.MaxMessageSize)
            {
                throw new ArgumentException(string.Format(CultureInfo.InvariantCulture, "Messages cannot be larger than {0} bytes.", Message.MaxMessageSize));
            }

            bool result = false;

            RetryPolicy(() =>
            {
                NameValueCollection col = new NameValueCollection();
                if (timeToLiveInSeconds != -1)
                {
                    col.Add(StorageHttpConstants.RequestParams.MessageTtl, timeToLiveInSeconds.ToString(CultureInfo.InvariantCulture));
                }

                ResourceUriComponents uriComponents;
                Uri uri = CreateRequestUri(StorageHttpConstants.RequestParams.Messages, col, out uriComponents);
                HttpWebRequest request = CreateHttpRequest(uri, StorageHttpConstants.HttpMethod.Post, null);
                int len;
                byte[] body = msg.GetContentXMLRepresentation(out len);
                request.ContentLength = len;
                _credentials.SignRequest(request, uriComponents);

                try
                {
                    using (Stream requestStream = request.GetRequestStream())
                    {                                               
                        requestStream.Write(body, 0, body.Length);
                        requestStream.Close();
                        using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
                        {
                            if (response.StatusCode == HttpStatusCode.Created)
                            {
                                result = true;
                            }
                            else
                            {
                                Utilities.ProcessUnexpectedStatusCode(response);
                            }
                            response.Close();
                        }
                    }
                }
                catch (WebException we)
                {
                    throw Utilities.TranslateWebException(we);
                }
            });

            return result;
        }

        public override Message GetMessage()
        {
            IEnumerable<Message> result = GetMessages(1);
            if (result == null || result.Count() == 0)
            {
                return null;
            }
            return result.First();
        }

        public override Message GetMessage(int visibilityTimeoutInSeconds)
        {
            IEnumerable<Message> result = GetMessages(1, visibilityTimeoutInSeconds);
            if (result == null || result.Count() == 0)
            {
                return null;
            }
            return result.First();
        }

        public override IEnumerable<Message> GetMessages(int numberOfMessages)
        {
            return GetMessages(numberOfMessages, -1);
        }

        public override IEnumerable<Message> GetMessages(int numberOfMessages, int visibilityTimeout)
        {
            return InternalGet(numberOfMessages, visibilityTimeout, false);
        }

        public override Message PeekMessage()
        {
            IEnumerable<Message> result = PeekMessages(1);
            if (result == null || result.Count() == 0)
            {
                return null;
            }
            return result.First();
        }

        public override IEnumerable<Message> PeekMessages(int numberOfMessages)
        {
            return InternalGet(numberOfMessages, -1, true);
        }

        // deleting messages
        public override bool DeleteMessage(Message msg)
        {
            if (msg.PopReceipt == null)
            {
                throw new ArgumentException("No PopReceipt for the given message!");
            }

            bool result = false;

            RetryPolicy(() =>
            {
                NameValueCollection col = new NameValueCollection();
                col.Add(StorageHttpConstants.RequestParams.PopReceipt, msg.PopReceipt.ToString());

                ResourceUriComponents uriComponents;
                Uri uri = CreateRequestUri(StorageHttpConstants.RequestParams.Messages + "/" + msg.Id, col, out uriComponents);
                HttpWebRequest request = CreateHttpRequest(uri, StorageHttpConstants.HttpMethod.Delete, null);
                _credentials.SignRequest(request, uriComponents);

                try
                {
                    using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
                    {
                        if (response.StatusCode == HttpStatusCode.NoContent)
                        {
                            result = true;
                        }
                        else
                        {
                            Utilities.ProcessUnexpectedStatusCode(response);
                        }
                        response.Close();
                    }

                }
                catch (WebException we)
                {
                    throw Utilities.TranslateWebException(we);
                }
            });

            return result;
        }

        public override bool Clear()
        {
            bool result = false;

            RetryPolicy(() =>
            {
                NameValueCollection col = new NameValueCollection();

                ResourceUriComponents uriComponents;
                Uri uri = CreateRequestUri(StorageHttpConstants.RequestParams.Messages, col, out uriComponents);
                HttpWebRequest request = CreateHttpRequest(uri, StorageHttpConstants.HttpMethod.Delete, null);
                _credentials.SignRequest(request, uriComponents);

                try
                {
                    using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
                    {
                        if (response.StatusCode == HttpStatusCode.NoContent)
                        {
                            result = true;
                        }
                        else
                        {
                            Utilities.ProcessUnexpectedStatusCode(response);
                        }
                        response.Close();
                    }

                }
                catch (WebException we)
                {
                    throw Utilities.TranslateWebException(we);
                }
            });

            return result;
        }

        // automatic receiving of messages
        public override int PollInterval
        {
            get
            {
                return _pollInterval;
            }
            set
            {
                if (value < 0)
                {
                    throw new ArgumentException("The send threshold must be a positive value.");
                }
                if (_run)
                {
                    throw new ArgumentException("You cannot set the poll interval while the receive thread is running");
                }
                _pollInterval = value;
            }
        }

        private AutoResetEvent _evStarted;
        private AutoResetEvent _evStopped;
        private AutoResetEvent _evQuit;
        private bool _run;
        private Thread _receiveThread;
        private int _internalPollInterval;


        private void PeriodicReceive()
        {
            Message msg;

            _evStarted.Set();
            _internalPollInterval = PollInterval;
            while (!_evQuit.WaitOne(_internalPollInterval, false))
            {
                // time is up, so we get the message and continue
                msg = GetMessage();
                if (msg != null)
                {
                    MessageReceived(this, new MessageReceivedEventArgs(msg));
                    // continue receiving fast until we get no message
                    _internalPollInterval = 10;
                }
                else
                {
                    // we got no message, so we can fall back to the normal speed
                    _internalPollInterval = PollInterval;
                }
            }
            _evStopped.Set();
        }

        public override bool StartReceiving()
        {
            lock (this)
            {
                if (_run)
                {
                    return true;
                }
                _run = true;
            }
            if (_evStarted == null) {
                _evStarted = new AutoResetEvent(false);
            }
            if (_evStopped == null) {
                _evStopped = new AutoResetEvent(false);
            }
            if (_evQuit == null) {
                _evQuit = new AutoResetEvent(false);
            }
            _receiveThread = new Thread(new ThreadStart(this.PeriodicReceive));
            _receiveThread.Start();
            if (!_evStarted.WaitOne(10000, false))
            {
                _receiveThread.Abort();
                CloseEvents();
                _run = false;
                return false;
            }
            return true;
        }

        public override void StopReceiving()
        {
            _evQuit.Set();
            if (!_evStopped.WaitOne(10000, false))            
            {
                _receiveThread.Abort();
            }
            CloseEvents();
            _run = false;
        }

        private void CloseEvents()
        {
            if (_evStarted != null)
            {
                _evStarted.Close();
            }
            if (_evStopped != null)
            {
                _evStopped.Close();
            }
            if (_evQuit != null)
            {
                _evQuit.Close();
            }
        }

        public override event MessageReceivedEventHandler MessageReceived;

        #endregion

        #region Helper methods

        private static QueueProperties GetPropertiesFromHeaders(HttpWebResponse response)
        {
            QueueProperties properties = new QueueProperties();
            int prefixLength = StorageHttpConstants.HeaderNames.PrefixForMetadata.Length;
            foreach (string key in response.Headers.AllKeys)
            {
                if (key.Equals(StorageHttpConstants.HeaderNames.ApproximateMessagesCount, StringComparison.OrdinalIgnoreCase))
                {
                    properties.ApproximateMessageCount = Convert.ToInt32(response.Headers[key], CultureInfo.InvariantCulture);
                }
                else if (key.StartsWith(StorageHttpConstants.HeaderNames.PrefixForMetadata, StringComparison.OrdinalIgnoreCase))
                {
                    if (properties.Metadata == null)
                    {
                        properties.Metadata = new NameValueCollection();
                    }
                    properties.Metadata.Add(key.Substring(prefixLength), response.Headers[key]);
                }
            }
            return properties;
        }


        private IEnumerable<Message> InternalGet(int numberOfMessages, int visibilityTimeout, bool peekOnly)
        {
            if (peekOnly && visibilityTimeout != -1)
            {
                throw new ArgumentException("A peek operation does not change the visibility of messages", "visibilityTimeout");
            }
            if (numberOfMessages < 1)
            {
                throw new ArgumentException("numberOfMessages must be a positive integer", "numberOfMessages");
            }
            if (visibilityTimeout < -1)
            {
                throw new ArgumentException("Visibility Timeout must be 0 or a positive integer", "visibilityTimeout");
            }

            IEnumerable<Message> result = null;

            RetryPolicy(() =>
            {
                NameValueCollection col = new NameValueCollection();
                col.Add(StorageHttpConstants.RequestParams.NumOfMessages, numberOfMessages.ToString(CultureInfo.InvariantCulture));
                if (visibilityTimeout != -1)
                {
                    col.Add(StorageHttpConstants.RequestParams.VisibilityTimeout,
                            visibilityTimeout.ToString(CultureInfo.InvariantCulture));
                }
                if (peekOnly)
                {
                    col.Add(StorageHttpConstants.RequestParams.PeekOnly,
                            peekOnly.ToString(CultureInfo.InvariantCulture));
                }

                ResourceUriComponents uriComponents;
                Uri uri = CreateRequestUri(StorageHttpConstants.RequestParams.Messages, col, out uriComponents);
                HttpWebRequest request = CreateHttpRequest(uri, StorageHttpConstants.HttpMethod.Get, null);
                _credentials.SignRequest(request, uriComponents);

                try
                {
                    using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
                    {
                        if (response.StatusCode == HttpStatusCode.OK)
                        {
                            using (Stream stream = response.GetResponseStream())
                            {
                                result = GetMessageFromResponse(stream);
                                stream.Close();
                            }
                        }
                        else
                        {
                            Utilities.ProcessUnexpectedStatusCode(response);
                        }
                        response.Close();
                    }

                }
                catch (WebException we)
                {
                    throw Utilities.TranslateWebException(we);
                }
            });


            return result;
        }

        private static IEnumerable<Message> GetMessageFromResponse(Stream stream)
        {
            List<Message> result = null;
            Message msg;

            XmlDocument doc = new XmlDocument();
            try
            {
                doc.Load(stream);
            }
            catch (XmlException xe)
            {
                throw new StorageServerException(StorageErrorCode.ServiceBadResponse,
                    "The result of a get message opertation could not be parsed", default(HttpStatusCode), xe);
            }

            XmlNodeList messagesNodes = doc.SelectNodes(XPathQueryHelper.MessagesListQuery);
            if (messagesNodes.Count > 0)
            {
                result = new List<Message>();
            }
            foreach (XmlNode messageNode in messagesNodes)
            {
                msg = new Message();
                msg.Id = messageNode.SelectSingleNode(StorageHttpConstants.XmlElementNames.MessageId).FirstChild.Value.Trim();
                Debug.Assert(msg.Id != null);
                if (messageNode.SelectSingleNode(StorageHttpConstants.XmlElementNames.PopReceipt) != null)
                {
                    msg.PopReceipt = messageNode.SelectSingleNode(StorageHttpConstants.XmlElementNames.PopReceipt).FirstChild.Value.Trim();
                    Debug.Assert(msg.PopReceipt != null);
                }                
                msg.InsertionTime = XPathQueryHelper.LoadSingleChildDateTimeValue(messageNode, StorageHttpConstants.XmlElementNames.InsertionTime, false).Value;
                msg.ExpirationTime = XPathQueryHelper.LoadSingleChildDateTimeValue(messageNode, StorageHttpConstants.XmlElementNames.ExpirationTime, false).Value;
                if (XPathQueryHelper.LoadSingleChildDateTimeValue(messageNode, StorageHttpConstants.XmlElementNames.TimeNextVisible, false) != null)
                {
                    msg.TimeNextVisible = XPathQueryHelper.LoadSingleChildDateTimeValue(messageNode, StorageHttpConstants.XmlElementNames.TimeNextVisible, false).Value;
                }
                msg.SetContentFromBase64String(XPathQueryHelper.LoadSingleChildStringValue(messageNode, StorageHttpConstants.XmlElementNames.MessageText, false));
                result.Add(msg);
            }
            return result.AsEnumerable();
        }

        private HttpWebRequest CreateHttpRequest(Uri uri, string httpMethod)
        {
            return CreateHttpRequest(uri, httpMethod, null);
        }

        private HttpWebRequest CreateHttpRequest(Uri uri, string httpMethod, NameValueCollection metadata)
        {
            HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(uri);
            request.Timeout = (int)Timeout.TotalMilliseconds;
            request.ReadWriteTimeout = (int)Timeout.TotalMilliseconds;
            request.Method = httpMethod;
            request.ContentLength = 0;
            request.Headers.Add(StorageHttpConstants.HeaderNames.StorageDateTime,
                                Utilities.ConvertDateTimeToHttpString(DateTime.UtcNow));
            if (metadata != null)
            {
                Utilities.AddMetadataHeaders(request, metadata);
            }
            return request;
        }

        private Uri CreateRequestUri(
                        string uriSuffix,
                        NameValueCollection queryParameters,
                        out ResourceUriComponents uriComponents
                        )
        {
            return CreateRequestUri(uriSuffix, queryParameters, false, out uriComponents);
        }

        private Uri CreateRequestUri(
            string uriSuffix,
            NameValueCollection queryParameters,
            bool accountOperation,
            out ResourceUriComponents uriComponents
            )
        {
            return Utilities.CreateRequestUri(
                            this.AccountInfo.BaseUri,
                            this.AccountInfo.UsePathStyleUris,
                            this.AccountInfo.AccountName,
                            accountOperation ? null : this.Name,
                            uriSuffix,
                            this.Timeout,
                            queryParameters,
                            out uriComponents
                            );
        }

        #endregion

    }
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Common Development and Distribution License (CDDL)


Written By
Technical Lead
United States United States
https://github.com/modesty

https://www.linkedin.com/in/modesty-zhang-9a43771

https://twitter.com/modestyqz

Comments and Discussions