BatchServiceHost.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / DataWeb / Server / System / Data / Services / BatchServiceHost.cs / 1305376 / BatchServiceHost.cs

                            //---------------------------------------------------------------------- 
// 
//      Copyright (c) Microsoft Corporation.  All rights reserved.
// 
//  
//      Provides an internal implementation for IDataServiceHost to keep track of states
//      for batch operations 
//  
//
// @owner  [....] 
//---------------------------------------------------------------------

namespace System.Data.Services
{ 
    #region Namespaces.
 
    using System; 
    using System.Collections.Generic;
    using System.Collections.Specialized; 
    using System.Diagnostics;
    using System.IO;
    using System.Web;
    using System.Net; 

    #endregion Namespaces. 
 
    /// 
    /// Keeps track of the request and response headers for each 
    /// operation in the batch
    /// 
    internal class BatchServiceHost : IDataServiceHost2
    { 
        #region Private fields.
 
        /// Response separator string. 
        private readonly string boundary;
 
        /// Request Stream.
        private readonly Stream requestStream;

        /// Content Id for this operation. 
        private readonly string contentId;
 
        /// Output writer. 
        private readonly StreamWriter writer;
 
        /// Gets the absolute URI to the resource upon which to apply the request.
        private readonly Uri absoluteRequestUri;

        /// Gets the absolute URI to the service. 
        private readonly Uri absoluteServiceUri;
 
        /// Request Http Method 
        private readonly string requestHttpMethod;
 
        /// Collection of request headers for the current batch operation.
        private readonly WebHeaderCollection requestHeaders;

        /// Collection of response headers for the current batch operation. 
        private readonly WebHeaderCollection responseHeaders;
 
        /// List of query parameters as specified in the request uri. 
        private NameValueCollection queryParameters;
 
        /// Value of the response StatusCode header.
        private int responseStatusCode;

        #endregion Private fields. 

        #region Constructors. 
 
        /// 
        /// Initializes a new dummy host for the batch request. 
        /// This host represents a single operation in the batch.
        /// 
        /// absolute Uri to the service
        /// batch stream which contains the header information. 
        /// content id for the given operation host.
        /// Response separator string. 
        /// Output writer. 
        internal BatchServiceHost(Uri absoluteServiceUri, BatchStream batchStream, string contentId, string boundary, StreamWriter writer)
            : this(boundary, writer) 
        {
            Debug.Assert(absoluteServiceUri != null && absoluteServiceUri.IsAbsoluteUri, "absoluteServiceUri != null && absoluteServiceUri.IsAbsoluteUri");
            Debug.Assert(batchStream != null, "batchStream != null");
 
            this.absoluteServiceUri = absoluteServiceUri;
            this.absoluteRequestUri = RequestUriProcessor.GetAbsoluteUriFromReference(batchStream.ContentUri, absoluteServiceUri); 
            this.requestHttpMethod = GetHttpMethodName(batchStream.State); 
            this.requestStream = batchStream.GetContentStream();
            this.contentId = contentId; 

            foreach (KeyValuePair header in batchStream.ContentHeaders)
            {
                this.requestHeaders.Add(header.Key, header.Value); 
            }
        } 
 
        /// 
        /// Initializes a host for error scenarios - something to which we can write the response header values 
        /// and write them to the underlying stream.
        /// 
        /// Response separator string.
        /// Output writer. 
        internal BatchServiceHost(string boundary, StreamWriter writer)
        { 
            Debug.Assert(!string.IsNullOrEmpty(boundary), "!string.IsNullOrEmpty(boundary)"); 
            Debug.Assert(writer != null, "writer != null");
 
            this.boundary = boundary;
            this.writer = writer;
            this.requestHeaders = new WebHeaderCollection();
            this.responseHeaders = new WebHeaderCollection(); 
        }
 
        #endregion Constructors. 

        #region Properties. 

        /// Gets the absolute URI to the resource upon which to apply the request.
        Uri IDataServiceHost.AbsoluteRequestUri
        { 
            [DebuggerStepThrough]
            get { return this.absoluteRequestUri; } 
        } 

        /// Gets the absolute URI to the service. 
        Uri IDataServiceHost.AbsoluteServiceUri
        {
            [DebuggerStepThrough]
            get { return this.absoluteServiceUri; } 
        }
 
        ///  
        /// Gets the character set encoding that the client requested,
        /// possibly null. 
        /// 
        string IDataServiceHost.RequestAccept
        {
            get { return this.requestHeaders[HttpRequestHeader.Accept]; } 
        }
 
        ///  
        /// Gets the character set encoding that the client requested,
        /// possibly null. 
        /// 
        string IDataServiceHost.RequestAcceptCharSet
        {
            get { return this.requestHeaders[HttpRequestHeader.AcceptCharset]; } 
        }
 
        /// Gets the HTTP MIME type of the input stream. 
        string IDataServiceHost.RequestContentType
        { 
            get { return this.requestHeaders[HttpRequestHeader.ContentType]; }
        }

        ///  
        /// Gets the HTTP data transfer method (such as GET, POST, or HEAD) used by the client.
        ///  
        string IDataServiceHost.RequestHttpMethod 
        {
            [DebuggerStepThrough] 
            get { return this.requestHttpMethod; }
        }

        /// Gets the value of the If-Match header from the request made 
        string IDataServiceHost.RequestIfMatch
        { 
            get { return this.requestHeaders[HttpRequestHeader.IfMatch]; } 
        }
 
        /// Gets the value of the If-None-Match header from the request made
        string IDataServiceHost.RequestIfNoneMatch
        {
            get { return this.requestHeaders[HttpRequestHeader.IfNoneMatch]; } 
        }
 
        /// Gets the value for the MaxDataServiceVersion request header. 
        string IDataServiceHost.RequestMaxVersion
        { 
            get { return this.requestHeaders[XmlConstants.HttpMaxDataServiceVersion]; }
        }

        /// Gets the value for the DataServiceVersion request header. 
        string IDataServiceHost.RequestVersion
        { 
            get { return this.requestHeaders[XmlConstants.HttpDataServiceVersion]; } 
        }
 
        /// Gets or sets the Cache-Control header on the response.
        string IDataServiceHost.ResponseCacheControl
        {
            get { return this.responseHeaders[HttpResponseHeader.CacheControl]; } 
            set { this.responseHeaders[HttpResponseHeader.CacheControl] = value; }
        } 
 
        /// Gets or sets the HTTP MIME type of the output stream.
        string IDataServiceHost.ResponseContentType 
        {
            get { return this.responseHeaders[HttpResponseHeader.ContentType]; }
            set { this.responseHeaders[HttpResponseHeader.ContentType] = value; }
        } 

        /// Gets/Sets the value of the ETag header on the outgoing response 
        string IDataServiceHost.ResponseETag 
        {
            get { return this.responseHeaders[HttpResponseHeader.ETag]; } 
            set { this.responseHeaders[HttpResponseHeader.ETag] = value; }
        }

        /// Gets or sets the Location header on the response. 
        string IDataServiceHost.ResponseLocation
        { 
            get { return this.responseHeaders[HttpResponseHeader.Location]; } 
            set { this.responseHeaders[HttpResponseHeader.Location] = value; }
        } 

        /// 
        /// Gets/Sets the status code for the request made.
        ///  
        int IDataServiceHost.ResponseStatusCode
        { 
            get { return this.responseStatusCode; } 
            set { this.responseStatusCode = value; }
        } 

        /// 
        /// Gets the  to be written to send a response
        /// to the client. 
        /// 
        Stream IDataServiceHost.ResponseStream 
        { 
            get
            { 
                // There is a batch stream for writing requests for batch operations.
                // Hence this method should never be called.
                throw Error.NotSupported();
            } 
        }
 
        /// Gets or sets the value for the DataServiceVersion response header. 
        string IDataServiceHost.ResponseVersion
        { 
            get { return this.responseHeaders[XmlConstants.HttpDataServiceVersion]; }
            set { this.responseHeaders[XmlConstants.HttpDataServiceVersion] = value; }
        }
 
        /// 
        /// Gets the  from which the request data can be read from 
        /// to the client. 
        /// 
        Stream IDataServiceHost.RequestStream 
        {
            [DebuggerStepThrough]
            get { return this.requestStream; }
        } 

        #region IDataServiceHost2 Properties 
 
        /// Dictionary of all request headers.
        WebHeaderCollection IDataServiceHost2.RequestHeaders 
        {
            get { return this.requestHeaders; }
        }
 
        /// Enumerates all response headers that has been set.
        WebHeaderCollection IDataServiceHost2.ResponseHeaders 
        { 
            get { return this.responseHeaders; }
        } 

        #endregion IDataServiceHost2 Properties

        /// Response separator string. 
        internal string BoundaryString
        { 
            get { return this.boundary; } 
        }
 
        /// 
        /// Gets/Sets the content id as specified in the batch request.
        /// This same value is written out in the response headers also to allow mapping requests on the client.
        ///  
        internal string ContentId
        { 
            get { return this.contentId; } 
        }
 
        /// Output writer.
        internal StreamWriter Writer
        {
            get { return this.writer; } 
        }
 
        #endregion Properties. 

        #region Methods. 

        /// Gets the value for the specified item in the request query string.
        /// Item to return.
        ///  
        /// The value for the specified item in the request query string;
        /// null if  is not found. 
        ///  
        string IDataServiceHost.GetQueryStringItem(string item)
        { 
            this.GetUriAndQueryParameters();

            string[] result = this.queryParameters.GetValues(item);
            if (result == null || result.Length == 0) 
            {
                return null; 
            } 
            else if (result.Length == 1)
            { 
                return result[0];
            }
            else
            { 
                throw DataServiceException.CreateBadRequestError(
                    Strings.DataServiceHost_MoreThanOneQueryParameterSpecifiedWithTheGivenName(item, this.absoluteRequestUri)); 
            } 
        }
 
        /// Method to handle a data service exception during processing.
        /// Exception handling description.
        void IDataServiceHost.ProcessException(HandleExceptionArgs args)
        { 
            // This would typically set headers on the host.
            WebUtil.CheckArgumentNull(args, "args"); 
            Debug.Assert(WebUtil.IsCatchableExceptionType(args.Exception), "WebUtil.IsCatchableExceptionType(args.Exception)"); 
            this.responseStatusCode = args.ResponseStatusCode;
            this.responseHeaders[HttpResponseHeader.ContentType] = args.ResponseContentType; 
            this.responseHeaders[HttpResponseHeader.Allow] = args.ResponseAllowHeader;

            // Only write the headers if the response is not written
            if (!args.ResponseWritten) 
            {
                System.Data.Services.Serializers.BatchWriter.WriteBoundaryAndHeaders(this.writer, this, this.contentId, this.boundary); 
            } 
        }
 
        /// 
        /// Returns the http method name given the batch stream state
        /// 
        /// state of the batch stream. 
        /// returns the http method name
        private static string GetHttpMethodName(BatchStreamState state) 
        { 
            Debug.Assert(
                state == BatchStreamState.Get || 
                state == BatchStreamState.Post ||
                state == BatchStreamState.Put ||
                state == BatchStreamState.Delete ||
                state == BatchStreamState.Merge, 
                "Expecting BatchStreamState (" + state + ") to be Delete, Get, Post or Put");
 
            switch (state) 
            {
                case BatchStreamState.Delete: 
                    return XmlConstants.HttpMethodDelete;
                case BatchStreamState.Get:
                    return XmlConstants.HttpMethodGet;
                case BatchStreamState.Post: 
                    return XmlConstants.HttpMethodPost;
                case BatchStreamState.Merge: 
                    return XmlConstants.HttpMethodMerge; 
                default:
                    Debug.Assert(BatchStreamState.Put == state, "BatchStreamState.Put == state"); 
                    return XmlConstants.HttpMethodPut;
            }
        }
 
        /// 
        /// Given the request uri, parse the uri and query parameters and cache them 
        ///  
        private void GetUriAndQueryParameters()
        { 
            if (this.queryParameters == null)
            {
                this.queryParameters = HttpUtility.ParseQueryString(this.absoluteRequestUri.Query);
            } 
        }
 
        #endregion Methods. 
    }
} 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.


                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK