Click here to Skip to main content
Click here to Skip to main content
Add your own
alternative version

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

, 11 Jul 2009
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).
Azurelight_SourceCode.zip
Azurelight
Azure
DomainServices
Linq
Properties
StorageClient
Azurelight
Azurelight
Azurelight.ccproj
Azurelight_WebRole
ServiceConfiguration.cscfg
ServiceDefinition.csdef
Azurelight_WebRole
App_Data
Azurelight.mdf
Azurelight_log.ldf
App_GlobalResources
System.Web.Silverlight.dll
ClientBin
Global.asax
Model
Properties
Service
AzurelightNav
Command
Control
Generated_Code
Model
Properties
Resources
SilverlightCairngorm
Business
Command
Control
Model
Properties
Views
//
// <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)

About the Author

Modesty Zhang
Technical Lead
United States United States
Tech Lead of large scale consumer facing software offerings, specializing in Web and Mobile application architecting and development.
 
Specialties:
Web App/ iOS / Cocoa Touch / HTML5 / CSS3 / Ajax / jQuery / jQuery Mobile / jQuery UI / Node.js / Rich JavaScript Application / RESTful Web Services / Java EE 6 / Java 7 / PHP / Ruby on Rails / and Windows / .NET / RIA / Flex / Flash / Silverlight / Software Architecting / Front End Design and Development

| Advertise | Privacy | Mobile
Web04 | 2.8.140718.1 | Last Updated 12 Jul 2009
Article Copyright 2009 by Modesty Zhang
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid