Code:
/ 4.0 / 4.0 / 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.
//----------------------------------------------------------------------
//
// 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

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- BamlRecordHelper.cs
- ApplicationId.cs
- EndPoint.cs
- IgnoreSectionHandler.cs
- KnownTypesHelper.cs
- EventHandlerList.cs
- DesignerAutoFormatStyle.cs
- HtmlInputRadioButton.cs
- QueryableDataSourceView.cs
- _UncName.cs
- ResourceProviderFactory.cs
- EditingCoordinator.cs
- BrowserCapabilitiesCompiler.cs
- Message.cs
- Events.cs
- BooleanAnimationBase.cs
- DependsOnAttribute.cs
- MessageHeaders.cs
- GetChildSubtree.cs
- RC2CryptoServiceProvider.cs
- FormatSettings.cs
- RequestCacheEntry.cs
- OleDbFactory.cs
- Internal.cs
- ExpressionLink.cs
- LambdaCompiler.Lambda.cs
- SqlVisitor.cs
- dtdvalidator.cs
- Context.cs
- RunWorkerCompletedEventArgs.cs
- GPPOINT.cs
- RoleManagerModule.cs
- UTF7Encoding.cs
- MessageFilterException.cs
- RecordConverter.cs
- FileReservationCollection.cs
- ParameterModifier.cs
- UrlMappingsSection.cs
- FieldNameLookup.cs
- safesecurityhelperavalon.cs
- Switch.cs
- DoubleLinkListEnumerator.cs
- TypeDelegator.cs
- ErrorTolerantObjectWriter.cs
- ListViewUpdatedEventArgs.cs
- CustomBindingCollectionElement.cs
- FixUpCollection.cs
- ThicknessAnimationBase.cs
- FileDialogCustomPlace.cs
- DateTimePickerDesigner.cs
- MsmqHostedTransportConfiguration.cs
- UITypeEditor.cs
- EntityDataSourceEntitySetNameItem.cs
- ResourcesBuildProvider.cs
- ArglessEventHandlerProxy.cs
- designeractionlistschangedeventargs.cs
- ContainerSelectorBehavior.cs
- TextFragmentEngine.cs
- Style.cs
- SharedConnectionWorkflowTransactionService.cs
- cryptoapiTransform.cs
- MSAAEventDispatcher.cs
- Table.cs
- ToolboxComponentsCreatedEventArgs.cs
- RotationValidation.cs
- HierarchicalDataBoundControlAdapter.cs
- ConfigurationManagerInternalFactory.cs
- ConnectionManagementSection.cs
- XPathChildIterator.cs
- CompilationLock.cs
- ApplicationProxyInternal.cs
- TextTreeInsertElementUndoUnit.cs
- SelectionWordBreaker.cs
- OrderByQueryOptionExpression.cs
- DnsPermission.cs
- ContentOperations.cs
- ParsedRoute.cs
- Configuration.cs
- SmiRequestExecutor.cs
- CompilationLock.cs
- TreeNodeBindingCollection.cs
- DataGridItemCollection.cs
- PolicyUtility.cs
- XhtmlBasicFormAdapter.cs
- Identity.cs
- SoapCommonClasses.cs
- ExecutionScope.cs
- PageEventArgs.cs
- TemplateKey.cs
- JoinSymbol.cs
- WebBrowserSiteBase.cs
- MenuItem.cs
- DescendantOverDescendantQuery.cs
- XmlArrayAttribute.cs
- TraceContextEventArgs.cs
- OdbcReferenceCollection.cs
- LookupBindingPropertiesAttribute.cs
- SessionEndingCancelEventArgs.cs
- TemplateColumn.cs
- TextTreeExtractElementUndoUnit.cs