Code:
/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / DataWeb / Server / System / Data / Services / HttpContextServiceHost.cs / 1305376 / HttpContextServiceHost.cs
//----------------------------------------------------------------------
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Provides an HttpContext-based implementation.
//
//
// @owner [....]
//---------------------------------------------------------------------
namespace System.Data.Services
{
#region Namespaces.
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Net;
using System.ServiceModel;
using System.ServiceModel.Web;
#endregion Namespaces.
///
/// Provides access to the environment for a DataService, including information about the current request, based
/// on the current WebOperationContext.
///
internal class HttpContextServiceHost : IDataServiceHost2
{
#region Private fields.
/// Message sent to server.
private readonly Stream incomingMessageBody;
/// The WCF-based operation context.
private readonly WebOperationContext operationContext;
/// Whether an error was found when processing this request.
private bool errorFound;
/// Gets the absolute URI to the resource upon which to apply the request.
private Uri absoluteRequestUri;
/// Gets the absolute URI to the service.
private Uri absoluteServiceUri;
#endregion Private fields.
#region Constructors.
///
/// Initializes a new System.Data.Services.HttpContextServiceHost instance.
///
/// Incoming message body to process.
internal HttpContextServiceHost(Stream messageBody)
{
// We capture the current context at initialization time rather
// than accessing it repeatedly.
this.incomingMessageBody = messageBody;
this.operationContext = WebOperationContext.Current;
if (this.operationContext == null)
{
throw new InvalidOperationException(Strings.HttpContextServiceHost_WebOperationContextCurrentMissing);
}
}
#endregion Constructors.
#region Properties.
///
/// Gets the character set encoding that the client requested,
/// possibly null.
///
string IDataServiceHost.RequestAcceptCharSet
{
get
{
// Returns a string that contains the comma-separated list of values
// associated with the specified key, if found; otherwise, null.
return this.operationContext.IncomingRequest.Headers[HttpRequestHeader.AcceptCharset];
}
}
/// Gets or sets the HTTP MIME type of the output stream.
string IDataServiceHost.ResponseContentType
{
get
{
return this.operationContext.OutgoingResponse.ContentType;
}
set
{
this.operationContext.OutgoingResponse.ContentType = value;
}
}
/// Gets the HTTP MIME type of the input stream.
string IDataServiceHost.RequestContentType
{
get
{
return this.operationContext.IncomingRequest.ContentType;
}
}
///
/// Gets a comma-separated list of client-supported MIME Accept types.
///
string IDataServiceHost.RequestAccept
{
get
{
return this.operationContext.IncomingRequest.Accept;
}
}
///
/// Gets the HTTP data transfer method (such as GET, POST, or HEAD) used by the client.
///
string IDataServiceHost.RequestHttpMethod
{
get
{
string result;
string[] methodValues = this.operationContext.IncomingRequest.Headers.GetValues(XmlConstants.HttpXMethod);
if (methodValues == null || methodValues.Length == 0)
{
result = this.operationContext.IncomingRequest.Method;
}
else if (methodValues.Length == 1)
{
result = methodValues[0];
if (this.operationContext.IncomingRequest.Method != XmlConstants.HttpMethodPost)
{
throw DataServiceException.CreateBadRequestError(Strings.HttpContextServiceHost_XMethodNotUsingPost);
}
if (result != XmlConstants.HttpMethodDelete && result != XmlConstants.HttpMethodPut && result != XmlConstants.HttpMethodMerge)
{
throw DataServiceException.CreateBadRequestError(Strings.HttpContextServiceHost_XMethodIncorrectValue(result));
}
}
else
{
throw DataServiceException.CreateBadRequestError(Strings.HttpContextServiceHost_XMethodIncorrectCount(methodValues.Length));
}
return result;
}
}
/// Gets the value of the If-Match header from the request made
string IDataServiceHost.RequestIfMatch
{
get
{
return this.operationContext.IncomingRequest.Headers[HttpRequestHeader.IfMatch];
}
}
/// Gets the value of the If-None-Match header from the request made
string IDataServiceHost.RequestIfNoneMatch
{
get
{
return this.operationContext.IncomingRequest.Headers[HttpRequestHeader.IfNoneMatch];
}
}
/// Gets the value for the MaxDataServiceVersion request header.
string IDataServiceHost.RequestMaxVersion
{
get
{
return this.operationContext.IncomingRequest.Headers[XmlConstants.HttpMaxDataServiceVersion];
}
}
/// Gets the value for the DataServiceVersion request header.
string IDataServiceHost.RequestVersion
{
get
{
return this.operationContext.IncomingRequest.Headers[XmlConstants.HttpDataServiceVersion];
}
}
/// Gets the absolute URI to the resource upon which to apply the request.
Uri IDataServiceHost.AbsoluteRequestUri
{
get
{
if (this.absoluteRequestUri == null)
{
object property;
if (OperationContext.Current.IncomingMessageProperties.TryGetValue(XmlConstants.MicrosoftDataServicesRequestUri, out property))
{
this.absoluteRequestUri = property as Uri;
if (this.absoluteRequestUri == null)
{
throw new InvalidOperationException(Strings.HttpContextServiceHost_IncomingMessagePropertyMustBeValidUriInstance(XmlConstants.MicrosoftDataServicesRequestUri));
}
}
if (this.absoluteRequestUri == null)
{
UriTemplateMatch match = this.operationContext.IncomingRequest.UriTemplateMatch;
this.absoluteRequestUri = WebUtil.ApplyHostHeader(match.RequestUri, this.HostHeader);
}
}
return this.absoluteRequestUri;
}
}
/// Gets or sets the Cache-Control header on the response.
string IDataServiceHost.ResponseCacheControl
{
get { return this.operationContext.OutgoingResponse.Headers[HttpResponseHeader.CacheControl]; }
set { this.operationContext.OutgoingResponse.Headers[HttpResponseHeader.CacheControl] = value; }
}
/// Gets/Sets the value of the ETag header on the outgoing response
string IDataServiceHost.ResponseETag
{
get
{
return this.operationContext.OutgoingResponse.ETag;
}
set
{
this.operationContext.OutgoingResponse.ETag = value;
}
}
/// Gets or sets the Location header on the response.
string IDataServiceHost.ResponseLocation
{
get { return this.operationContext.OutgoingResponse.Headers[HttpResponseHeader.Location]; }
set { this.operationContext.OutgoingResponse.Headers[HttpResponseHeader.Location] = value; }
}
///
/// Gets/Sets the status code for the request made.
///
int IDataServiceHost.ResponseStatusCode
{
get
{
return (int) this.operationContext.OutgoingResponse.StatusCode;
}
set
{
HttpStatusCode statusCode = (HttpStatusCode)value;
this.operationContext.OutgoingResponse.StatusCode = statusCode;
// Some status codes such as NoContent or NotModified MUST NOT include a message-body in the response.
// We need to set SupressEntityBody to true so that in the case of chuncked encoding WCF won't write
// a '0' in the message body to indicate there is no more content.
// Note that not setting this will result in a HTTP Protocol Violation exception when chuncked encoding is on.
this.operationContext.OutgoingResponse.SuppressEntityBody = MustNotReturnMessageBody(statusCode);
}
}
///
/// Gets the to be written to send a response
/// to the client.
///
Stream IDataServiceHost.ResponseStream
{
get
{
// The ResponseStream is not directly accessible - this would
// prevent WCF from streaming results back. For the WCF host,
// a Message subclass should write directly in the OnBodyWrite
// method.
throw Error.NotSupported();
}
}
/// Gets or sets the value for the DataServiceVersion response header.
string IDataServiceHost.ResponseVersion
{
get { return this.operationContext.OutgoingResponse.Headers[XmlConstants.HttpDataServiceVersion]; }
set { this.operationContext.OutgoingResponse.Headers[XmlConstants.HttpDataServiceVersion] = value; }
}
/// Gets the absolute URI to the service.
Uri IDataServiceHost.AbsoluteServiceUri
{
get
{
if (this.absoluteServiceUri == null)
{
object property;
if (OperationContext.Current.IncomingMessageProperties.TryGetValue(XmlConstants.MicrosoftDataServicesRootUri, out property))
{
this.absoluteServiceUri = property as Uri;
if (this.absoluteServiceUri == null)
{
throw new InvalidOperationException(Strings.HttpContextServiceHost_IncomingMessagePropertyMustBeValidUriInstance(XmlConstants.MicrosoftDataServicesRootUri));
}
}
if (this.absoluteServiceUri == null)
{
UriTemplateMatch match = this.operationContext.IncomingRequest.UriTemplateMatch;
// We never want to consider the last segment of the base URI a 'document' type
// of segment to be replaced, ie, http://foo/svc.svc should never remove svc.svc
// from the path.
this.absoluteServiceUri = WebUtil.ApplyHostHeader(match.BaseUri, this.HostHeader);
}
if (!String.IsNullOrEmpty(this.absoluteServiceUri.Fragment))
{
throw new InvalidOperationException(Strings.HttpContextServiceHost_IncomingTemplateMatchFragment(this.absoluteServiceUri));
}
if (!String.IsNullOrEmpty(this.absoluteServiceUri.Query))
{
throw new InvalidOperationException(Strings.HttpContextServiceHost_IncomingTemplateMatchQuery(this.absoluteServiceUri));
}
this.absoluteServiceUri = WebUtil.EnsureLastSegmentEmpty(this.absoluteServiceUri);
}
return this.absoluteServiceUri;
}
}
///
/// Gets the from which the request data can be read from
/// to the client.
///
Stream IDataServiceHost.RequestStream
{
[DebuggerStepThrough]
get { return this.incomingMessageBody; }
}
#region IDataServiceHost2 Properties
/// Dictionary of all request headers from the host.
WebHeaderCollection IDataServiceHost2.RequestHeaders
{
[DebuggerStepThrough]
get { return this.operationContext.IncomingRequest.Headers; }
}
/// Enumerates all response headers that has been set.
WebHeaderCollection IDataServiceHost2.ResponseHeaders
{
[DebuggerStepThrough]
get { return this.operationContext.OutgoingResponse.Headers; }
}
#endregion IDataServiceHost2 Properties
/// Whether an error was found when processing this request.
internal bool ErrorFound
{
get { return this.errorFound; }
}
/// The value for the Host header in the request, possibly null.
private string HostHeader
{
get { return this.operationContext.IncomingRequest.Headers[HttpRequestHeader.Host]; }
}
#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)
{
Debug.Assert(item != null, "item != null");
Debug.Assert(item.Trim() == item, "item.Trim() == item - otherwise, there are leading/trailing spaces in the name");
System.Collections.Specialized.NameValueCollection collection = this.operationContext.IncomingRequest.UriTemplateMatch.QueryParameters;
string[] values = collection.GetValues(item);
if (values == null || values.Length == 0)
{
// Do a scan of arguments ignoring whitespace (SQLBUDT #555944).
string keyFound = null;
foreach (string key in collection.Keys)
{
if (key != null && StringComparer.OrdinalIgnoreCase.Equals(key.Trim(), item))
{
if (keyFound != null)
{
throw DataServiceException.CreateBadRequestError(Strings.HttpContextServiceHost_AmbiguousItemName(item, keyFound, key));
}
keyFound = key;
values = collection.GetValues(key);
}
}
if (values == null || values.Length == 0)
{
return null;
}
}
Debug.Assert(values != null && values.Length > 0, "values != null && values.Length > 0 - otherwise we should have returned already");
if (values.Length == 1)
{
return values[0];
}
else
{
throw DataServiceException.CreateSyntaxError();
}
}
///
/// Method to handle a data service exception during processing.
///
/// Exception handling description.
void IDataServiceHost.ProcessException(HandleExceptionArgs args)
{
Debug.Assert(this.operationContext != null, "this.operationContext != null");
this.errorFound = true;
if (!args.ResponseWritten)
{
((IDataServiceHost)this).ResponseStatusCode = args.ResponseStatusCode;
((IDataServiceHost)this).ResponseContentType = args.ResponseContentType;
if (args.ResponseAllowHeader != null)
{
this.operationContext.OutgoingResponse.Headers[HttpResponseHeader.Allow] = args.ResponseAllowHeader;
}
}
}
/// Verifies that query parameters are valid.
internal void VerifyQueryParameters()
{
HashSet namesFound = new HashSet(StringComparer.Ordinal);
System.Collections.Specialized.NameValueCollection collection = this.operationContext.IncomingRequest.UriTemplateMatch.QueryParameters;
for (int i = 0; i < collection.Count; i++)
{
string name = collection.GetKey(i);
if (name == null)
{
// These are values of the form a&b&c, without '='. We just make sure they aren't system
// values at all.
string[] values = collection.GetValues(i);
if (values != null)
{
for (int j = 0; j < values.Length; j++)
{
string value = values[j].Trim();
if (value.Length > 0 && value[0] == '$')
{
throw DataServiceException.CreateBadRequestError(
Strings.HttpContextServiceHost_QueryParameterMustBeSpecifiedOnce(value));
}
}
}
continue;
}
name = name.Trim();
if (!namesFound.Add(name))
{
throw DataServiceException.CreateBadRequestError(
Strings.HttpContextServiceHost_QueryParameterMustBeSpecifiedOnce(name));
}
if (name.Length > 0 && name[0] == '$')
{
if (name != XmlConstants.HttpQueryStringExpand &&
name != XmlConstants.HttpQueryStringFilter &&
name != XmlConstants.HttpQueryStringOrderBy &&
name != XmlConstants.HttpQueryStringSkip &&
name != XmlConstants.HttpQueryStringSkipToken &&
name != XmlConstants.HttpQueryStringInlineCount &&
name != XmlConstants.HttpQueryStringTop &&
name != XmlConstants.HttpQueryStringSelect)
{
throw DataServiceException.CreateBadRequestError(
Strings.HttpContextServiceHost_UnknownQueryParameter(name));
}
string[] values = collection.GetValues(i);
if (values == null || values.Length != 1)
{
throw DataServiceException.CreateBadRequestError(
Strings.HttpContextServiceHost_QueryParameterMustBeSpecifiedOnce(name));
}
}
}
}
///
/// Check to see if the given status code expects an empty message-body.
///
/// Http status code
/// True if the message-body must be empty for the given status code, false otherwise.
private static bool MustNotReturnMessageBody(HttpStatusCode statusCode)
{
// Both 204 and 304 must not include a message-body in the response.
switch (statusCode)
{
case HttpStatusCode.NoContent: // 204
case HttpStatusCode.ResetContent: // 205
case HttpStatusCode.NotModified: // 304
return true;
default:
return false;
}
}
#endregion Methods.
}
}
// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
//----------------------------------------------------------------------
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Provides an HttpContext-based implementation.
//
//
// @owner [....]
//---------------------------------------------------------------------
namespace System.Data.Services
{
#region Namespaces.
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Net;
using System.ServiceModel;
using System.ServiceModel.Web;
#endregion Namespaces.
///
/// Provides access to the environment for a DataService, including information about the current request, based
/// on the current WebOperationContext.
///
internal class HttpContextServiceHost : IDataServiceHost2
{
#region Private fields.
/// Message sent to server.
private readonly Stream incomingMessageBody;
/// The WCF-based operation context.
private readonly WebOperationContext operationContext;
/// Whether an error was found when processing this request.
private bool errorFound;
/// Gets the absolute URI to the resource upon which to apply the request.
private Uri absoluteRequestUri;
/// Gets the absolute URI to the service.
private Uri absoluteServiceUri;
#endregion Private fields.
#region Constructors.
///
/// Initializes a new System.Data.Services.HttpContextServiceHost instance.
///
/// Incoming message body to process.
internal HttpContextServiceHost(Stream messageBody)
{
// We capture the current context at initialization time rather
// than accessing it repeatedly.
this.incomingMessageBody = messageBody;
this.operationContext = WebOperationContext.Current;
if (this.operationContext == null)
{
throw new InvalidOperationException(Strings.HttpContextServiceHost_WebOperationContextCurrentMissing);
}
}
#endregion Constructors.
#region Properties.
///
/// Gets the character set encoding that the client requested,
/// possibly null.
///
string IDataServiceHost.RequestAcceptCharSet
{
get
{
// Returns a string that contains the comma-separated list of values
// associated with the specified key, if found; otherwise, null.
return this.operationContext.IncomingRequest.Headers[HttpRequestHeader.AcceptCharset];
}
}
/// Gets or sets the HTTP MIME type of the output stream.
string IDataServiceHost.ResponseContentType
{
get
{
return this.operationContext.OutgoingResponse.ContentType;
}
set
{
this.operationContext.OutgoingResponse.ContentType = value;
}
}
/// Gets the HTTP MIME type of the input stream.
string IDataServiceHost.RequestContentType
{
get
{
return this.operationContext.IncomingRequest.ContentType;
}
}
///
/// Gets a comma-separated list of client-supported MIME Accept types.
///
string IDataServiceHost.RequestAccept
{
get
{
return this.operationContext.IncomingRequest.Accept;
}
}
///
/// Gets the HTTP data transfer method (such as GET, POST, or HEAD) used by the client.
///
string IDataServiceHost.RequestHttpMethod
{
get
{
string result;
string[] methodValues = this.operationContext.IncomingRequest.Headers.GetValues(XmlConstants.HttpXMethod);
if (methodValues == null || methodValues.Length == 0)
{
result = this.operationContext.IncomingRequest.Method;
}
else if (methodValues.Length == 1)
{
result = methodValues[0];
if (this.operationContext.IncomingRequest.Method != XmlConstants.HttpMethodPost)
{
throw DataServiceException.CreateBadRequestError(Strings.HttpContextServiceHost_XMethodNotUsingPost);
}
if (result != XmlConstants.HttpMethodDelete && result != XmlConstants.HttpMethodPut && result != XmlConstants.HttpMethodMerge)
{
throw DataServiceException.CreateBadRequestError(Strings.HttpContextServiceHost_XMethodIncorrectValue(result));
}
}
else
{
throw DataServiceException.CreateBadRequestError(Strings.HttpContextServiceHost_XMethodIncorrectCount(methodValues.Length));
}
return result;
}
}
/// Gets the value of the If-Match header from the request made
string IDataServiceHost.RequestIfMatch
{
get
{
return this.operationContext.IncomingRequest.Headers[HttpRequestHeader.IfMatch];
}
}
/// Gets the value of the If-None-Match header from the request made
string IDataServiceHost.RequestIfNoneMatch
{
get
{
return this.operationContext.IncomingRequest.Headers[HttpRequestHeader.IfNoneMatch];
}
}
/// Gets the value for the MaxDataServiceVersion request header.
string IDataServiceHost.RequestMaxVersion
{
get
{
return this.operationContext.IncomingRequest.Headers[XmlConstants.HttpMaxDataServiceVersion];
}
}
/// Gets the value for the DataServiceVersion request header.
string IDataServiceHost.RequestVersion
{
get
{
return this.operationContext.IncomingRequest.Headers[XmlConstants.HttpDataServiceVersion];
}
}
/// Gets the absolute URI to the resource upon which to apply the request.
Uri IDataServiceHost.AbsoluteRequestUri
{
get
{
if (this.absoluteRequestUri == null)
{
object property;
if (OperationContext.Current.IncomingMessageProperties.TryGetValue(XmlConstants.MicrosoftDataServicesRequestUri, out property))
{
this.absoluteRequestUri = property as Uri;
if (this.absoluteRequestUri == null)
{
throw new InvalidOperationException(Strings.HttpContextServiceHost_IncomingMessagePropertyMustBeValidUriInstance(XmlConstants.MicrosoftDataServicesRequestUri));
}
}
if (this.absoluteRequestUri == null)
{
UriTemplateMatch match = this.operationContext.IncomingRequest.UriTemplateMatch;
this.absoluteRequestUri = WebUtil.ApplyHostHeader(match.RequestUri, this.HostHeader);
}
}
return this.absoluteRequestUri;
}
}
/// Gets or sets the Cache-Control header on the response.
string IDataServiceHost.ResponseCacheControl
{
get { return this.operationContext.OutgoingResponse.Headers[HttpResponseHeader.CacheControl]; }
set { this.operationContext.OutgoingResponse.Headers[HttpResponseHeader.CacheControl] = value; }
}
/// Gets/Sets the value of the ETag header on the outgoing response
string IDataServiceHost.ResponseETag
{
get
{
return this.operationContext.OutgoingResponse.ETag;
}
set
{
this.operationContext.OutgoingResponse.ETag = value;
}
}
/// Gets or sets the Location header on the response.
string IDataServiceHost.ResponseLocation
{
get { return this.operationContext.OutgoingResponse.Headers[HttpResponseHeader.Location]; }
set { this.operationContext.OutgoingResponse.Headers[HttpResponseHeader.Location] = value; }
}
///
/// Gets/Sets the status code for the request made.
///
int IDataServiceHost.ResponseStatusCode
{
get
{
return (int) this.operationContext.OutgoingResponse.StatusCode;
}
set
{
HttpStatusCode statusCode = (HttpStatusCode)value;
this.operationContext.OutgoingResponse.StatusCode = statusCode;
// Some status codes such as NoContent or NotModified MUST NOT include a message-body in the response.
// We need to set SupressEntityBody to true so that in the case of chuncked encoding WCF won't write
// a '0' in the message body to indicate there is no more content.
// Note that not setting this will result in a HTTP Protocol Violation exception when chuncked encoding is on.
this.operationContext.OutgoingResponse.SuppressEntityBody = MustNotReturnMessageBody(statusCode);
}
}
///
/// Gets the to be written to send a response
/// to the client.
///
Stream IDataServiceHost.ResponseStream
{
get
{
// The ResponseStream is not directly accessible - this would
// prevent WCF from streaming results back. For the WCF host,
// a Message subclass should write directly in the OnBodyWrite
// method.
throw Error.NotSupported();
}
}
/// Gets or sets the value for the DataServiceVersion response header.
string IDataServiceHost.ResponseVersion
{
get { return this.operationContext.OutgoingResponse.Headers[XmlConstants.HttpDataServiceVersion]; }
set { this.operationContext.OutgoingResponse.Headers[XmlConstants.HttpDataServiceVersion] = value; }
}
/// Gets the absolute URI to the service.
Uri IDataServiceHost.AbsoluteServiceUri
{
get
{
if (this.absoluteServiceUri == null)
{
object property;
if (OperationContext.Current.IncomingMessageProperties.TryGetValue(XmlConstants.MicrosoftDataServicesRootUri, out property))
{
this.absoluteServiceUri = property as Uri;
if (this.absoluteServiceUri == null)
{
throw new InvalidOperationException(Strings.HttpContextServiceHost_IncomingMessagePropertyMustBeValidUriInstance(XmlConstants.MicrosoftDataServicesRootUri));
}
}
if (this.absoluteServiceUri == null)
{
UriTemplateMatch match = this.operationContext.IncomingRequest.UriTemplateMatch;
// We never want to consider the last segment of the base URI a 'document' type
// of segment to be replaced, ie, http://foo/svc.svc should never remove svc.svc
// from the path.
this.absoluteServiceUri = WebUtil.ApplyHostHeader(match.BaseUri, this.HostHeader);
}
if (!String.IsNullOrEmpty(this.absoluteServiceUri.Fragment))
{
throw new InvalidOperationException(Strings.HttpContextServiceHost_IncomingTemplateMatchFragment(this.absoluteServiceUri));
}
if (!String.IsNullOrEmpty(this.absoluteServiceUri.Query))
{
throw new InvalidOperationException(Strings.HttpContextServiceHost_IncomingTemplateMatchQuery(this.absoluteServiceUri));
}
this.absoluteServiceUri = WebUtil.EnsureLastSegmentEmpty(this.absoluteServiceUri);
}
return this.absoluteServiceUri;
}
}
///
/// Gets the from which the request data can be read from
/// to the client.
///
Stream IDataServiceHost.RequestStream
{
[DebuggerStepThrough]
get { return this.incomingMessageBody; }
}
#region IDataServiceHost2 Properties
/// Dictionary of all request headers from the host.
WebHeaderCollection IDataServiceHost2.RequestHeaders
{
[DebuggerStepThrough]
get { return this.operationContext.IncomingRequest.Headers; }
}
/// Enumerates all response headers that has been set.
WebHeaderCollection IDataServiceHost2.ResponseHeaders
{
[DebuggerStepThrough]
get { return this.operationContext.OutgoingResponse.Headers; }
}
#endregion IDataServiceHost2 Properties
/// Whether an error was found when processing this request.
internal bool ErrorFound
{
get { return this.errorFound; }
}
/// The value for the Host header in the request, possibly null.
private string HostHeader
{
get { return this.operationContext.IncomingRequest.Headers[HttpRequestHeader.Host]; }
}
#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)
{
Debug.Assert(item != null, "item != null");
Debug.Assert(item.Trim() == item, "item.Trim() == item - otherwise, there are leading/trailing spaces in the name");
System.Collections.Specialized.NameValueCollection collection = this.operationContext.IncomingRequest.UriTemplateMatch.QueryParameters;
string[] values = collection.GetValues(item);
if (values == null || values.Length == 0)
{
// Do a scan of arguments ignoring whitespace (SQLBUDT #555944).
string keyFound = null;
foreach (string key in collection.Keys)
{
if (key != null && StringComparer.OrdinalIgnoreCase.Equals(key.Trim(), item))
{
if (keyFound != null)
{
throw DataServiceException.CreateBadRequestError(Strings.HttpContextServiceHost_AmbiguousItemName(item, keyFound, key));
}
keyFound = key;
values = collection.GetValues(key);
}
}
if (values == null || values.Length == 0)
{
return null;
}
}
Debug.Assert(values != null && values.Length > 0, "values != null && values.Length > 0 - otherwise we should have returned already");
if (values.Length == 1)
{
return values[0];
}
else
{
throw DataServiceException.CreateSyntaxError();
}
}
///
/// Method to handle a data service exception during processing.
///
/// Exception handling description.
void IDataServiceHost.ProcessException(HandleExceptionArgs args)
{
Debug.Assert(this.operationContext != null, "this.operationContext != null");
this.errorFound = true;
if (!args.ResponseWritten)
{
((IDataServiceHost)this).ResponseStatusCode = args.ResponseStatusCode;
((IDataServiceHost)this).ResponseContentType = args.ResponseContentType;
if (args.ResponseAllowHeader != null)
{
this.operationContext.OutgoingResponse.Headers[HttpResponseHeader.Allow] = args.ResponseAllowHeader;
}
}
}
/// Verifies that query parameters are valid.
internal void VerifyQueryParameters()
{
HashSet namesFound = new HashSet(StringComparer.Ordinal);
System.Collections.Specialized.NameValueCollection collection = this.operationContext.IncomingRequest.UriTemplateMatch.QueryParameters;
for (int i = 0; i < collection.Count; i++)
{
string name = collection.GetKey(i);
if (name == null)
{
// These are values of the form a&b&c, without '='. We just make sure they aren't system
// values at all.
string[] values = collection.GetValues(i);
if (values != null)
{
for (int j = 0; j < values.Length; j++)
{
string value = values[j].Trim();
if (value.Length > 0 && value[0] == '$')
{
throw DataServiceException.CreateBadRequestError(
Strings.HttpContextServiceHost_QueryParameterMustBeSpecifiedOnce(value));
}
}
}
continue;
}
name = name.Trim();
if (!namesFound.Add(name))
{
throw DataServiceException.CreateBadRequestError(
Strings.HttpContextServiceHost_QueryParameterMustBeSpecifiedOnce(name));
}
if (name.Length > 0 && name[0] == '$')
{
if (name != XmlConstants.HttpQueryStringExpand &&
name != XmlConstants.HttpQueryStringFilter &&
name != XmlConstants.HttpQueryStringOrderBy &&
name != XmlConstants.HttpQueryStringSkip &&
name != XmlConstants.HttpQueryStringSkipToken &&
name != XmlConstants.HttpQueryStringInlineCount &&
name != XmlConstants.HttpQueryStringTop &&
name != XmlConstants.HttpQueryStringSelect)
{
throw DataServiceException.CreateBadRequestError(
Strings.HttpContextServiceHost_UnknownQueryParameter(name));
}
string[] values = collection.GetValues(i);
if (values == null || values.Length != 1)
{
throw DataServiceException.CreateBadRequestError(
Strings.HttpContextServiceHost_QueryParameterMustBeSpecifiedOnce(name));
}
}
}
}
///
/// Check to see if the given status code expects an empty message-body.
///
/// Http status code
/// True if the message-body must be empty for the given status code, false otherwise.
private static bool MustNotReturnMessageBody(HttpStatusCode statusCode)
{
// Both 204 and 304 must not include a message-body in the response.
switch (statusCode)
{
case HttpStatusCode.NoContent: // 204
case HttpStatusCode.ResetContent: // 205
case HttpStatusCode.NotModified: // 304
return true;
default:
return false;
}
}
#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
- xamlnodes.cs
- WebException.cs
- DataGridViewColumnCollection.cs
- ToggleButtonAutomationPeer.cs
- FederatedMessageSecurityOverHttpElement.cs
- ReferencedAssembly.cs
- PrivilegeNotHeldException.cs
- HtmlHead.cs
- Keywords.cs
- CommonEndpointBehaviorElement.cs
- XmlWrappingReader.cs
- Logging.cs
- UserControlCodeDomTreeGenerator.cs
- EntityClassGenerator.cs
- DefaultAssemblyResolver.cs
- WeakEventManager.cs
- BitmapEffectInput.cs
- SignedXml.cs
- translator.cs
- EventLogEntryCollection.cs
- NamedPipeConnectionPoolSettings.cs
- SafeNativeMethods.cs
- CookieProtection.cs
- objectresult_tresulttype.cs
- SQLStringStorage.cs
- MutexSecurity.cs
- safePerfProviderHandle.cs
- SqlUdtInfo.cs
- DebuggerAttributes.cs
- XmlReturnReader.cs
- EncoderParameters.cs
- Funcletizer.cs
- Frame.cs
- LOSFormatter.cs
- NavigationPropertySingletonExpression.cs
- StylusSystemGestureEventArgs.cs
- MsdtcWrapper.cs
- CommonDialog.cs
- ContextMenu.cs
- LayoutEvent.cs
- NameValuePermission.cs
- WriteStateInfoBase.cs
- DataSet.cs
- VisualTreeHelper.cs
- GcHandle.cs
- PointValueSerializer.cs
- PropertyPathConverter.cs
- SpecularMaterial.cs
- SettingsSavedEventArgs.cs
- MDIClient.cs
- LowerCaseStringConverter.cs
- XmlDownloadManager.cs
- ExceptionUtility.cs
- InheritanceContextChangedEventManager.cs
- AccessKeyManager.cs
- XmlSecureResolver.cs
- ForeignConstraint.cs
- TemplateInstanceAttribute.cs
- BufferAllocator.cs
- WebPartConnectionsEventArgs.cs
- ConfigurationLocation.cs
- ParallelEnumerable.cs
- XmlDownloadManager.cs
- MailDefinition.cs
- TimerElapsedEvenArgs.cs
- PropertyIdentifier.cs
- CriticalExceptions.cs
- Triplet.cs
- SrgsItemList.cs
- TextServicesProperty.cs
- XmlSchemaAnnotated.cs
- DrawingVisualDrawingContext.cs
- ProtectedProviderSettings.cs
- COSERVERINFO.cs
- OleDbParameterCollection.cs
- StylusLogic.cs
- ControlCollection.cs
- ParentUndoUnit.cs
- Encoder.cs
- PowerStatus.cs
- StreamSecurityUpgradeAcceptor.cs
- DesignerHost.cs
- EventWaitHandle.cs
- IdentityNotMappedException.cs
- XmlSchemaInferenceException.cs
- WorkItem.cs
- DefaultWorkflowTransactionService.cs
- MouseGesture.cs
- InProcStateClientManager.cs
- HtmlControl.cs
- ProtectedConfigurationProviderCollection.cs
- SqlConnectionString.cs
- counter.cs
- IIS7UserPrincipal.cs
- FormViewDeletedEventArgs.cs
- LinqDataSourceDeleteEventArgs.cs
- CqlIdentifiers.cs
- SoapDocumentServiceAttribute.cs
- EventBindingService.cs
- Animatable.cs