Code:
/ WCF / WCF / 3.5.30729.1 / untmp / Orcas / SP / ndp / cdf / src / NetFx35 / System.ServiceModel.Web / System / ServiceModel / Dispatcher / WebHttpDispatchOperationSelector.cs / 3 / WebHttpDispatchOperationSelector.cs
//------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//-----------------------------------------------------------
#pragma warning disable 1634, 1691
namespace System.ServiceModel.Dispatcher
{
using System;
using System.Diagnostics.CodeAnalysis;
using System.Collections.Generic;
using System.Globalization;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.ServiceModel.Description;
using System.Collections.ObjectModel;
using System.ServiceModel.Web;
using System.Diagnostics;
using System.ServiceModel.Diagnostics;
using System.ServiceModel.Activation;
public class WebHttpDispatchOperationSelector : IDispatchOperationSelector
{
public const string HttpOperationSelectorUriMatchedPropertyName = "UriMatched";
internal const string redirectOperationName = ""; // always unhandled invoker
internal const string RedirectPropertyName = "WebHttpRedirect";
string catchAllOperationName = ""; // user UT=* Method=* operation, else unhandled invoker
UriTemplateTable table;
public WebHttpDispatchOperationSelector(ServiceEndpoint endpoint)
{
if (endpoint == null)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("endpoint");
}
if (endpoint.Address == null)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(
SR2.GetString(SR2.EndpointAddressCannotBeNull)));
}
#pragma warning disable 56506 // [....], endpoint.Address.Uri is never null
this.table = new UriTemplateTable(endpoint.Address.Uri);
#pragma warning restore 56506
Dictionary alreadyHaves = new Dictionary();
#pragma warning disable 56506 // [....], endpoint.Contract is never null
foreach (OperationDescription od in endpoint.Contract.Operations)
#pragma warning restore 56506
{
// ignore callback operations
if (od.Messages[0].Direction == MessageDirection.Input)
{
string method = WebHttpBehavior.GetWebMethod(od);
string path = UriTemplateClientFormatter.GetUTStringOrDefault(od);
if (UriTemplateHelpers.IsWildcardPath(path) && (method == WebHttpBehavior.WildcardMethod))
{
if (this.catchAllOperationName != "")
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
new InvalidOperationException(
SR2.GetString(SR2.MultipleOperationsInContractWithPathMethod,
endpoint.Contract.Name, path, method)));
}
this.catchAllOperationName = od.Name;
}
UriTemplate ut = new UriTemplate(path);
WCFKey wcfKey = new WCFKey(ut, method);
if (alreadyHaves.ContainsKey(wcfKey))
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
new InvalidOperationException(
SR2.GetString(SR2.MultipleOperationsInContractWithPathMethod,
endpoint.Contract.Name, path, method)));
}
alreadyHaves.Add(wcfKey, od.Name);
WCFLookupResult wlr = new WCFLookupResult(method, od.Name);
table.KeyValuePairs.Add(new KeyValuePair(ut, wlr));
}
}
if (this.table.KeyValuePairs.Count == 0)
{
this.table = null;
}
else
{
this.table.MakeReadOnly(true);
}
}
protected WebHttpDispatchOperationSelector()
{
}
[SuppressMessage("Microsoft.Design", "CA1045:DoNotPassTypesByReference", MessageId = "0#", Justification = "This method is defined by the IDispatchOperationSelector interface")]
public string SelectOperation(ref Message message)
{
if (message == null)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("message");
}
bool uriMatched;
string result = this.SelectOperation(ref message, out uriMatched);
#pragma warning disable 56506 // [....], Message.Properties is never null
message.Properties.Add(HttpOperationSelectorUriMatchedPropertyName, uriMatched);
#pragma warning restore 56506
if (result != null && DiagnosticUtility.ShouldTraceInformation)
{
#pragma warning disable 56506 // [....], Message.Headers is never null
DiagnosticUtility.DiagnosticTrace.TraceEvent(TraceEventType.Information, TraceCode.WebRequestMatchesOperation, SR2.GetString(SR2.TraceCodeWebRequestMatchesOperation, message.Headers.To, result));
#pragma warning restore 56506
}
return result;
}
[SuppressMessage("Microsoft.Design", "CA1045:DoNotPassTypesByReference", MessageId = "0#", Justification = "This method is like that defined by the IDispatchOperationSelector interface")]
[SuppressMessage("Microsoft.Design", "CA1021:AvoidOutParameters", MessageId = "1#", Justification = "This API needs to return multiple things")]
protected virtual string SelectOperation(ref Message message, out bool uriMatched)
{
if (message == null)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("message");
}
uriMatched = false;
if (this.table == null)
{
return this.catchAllOperationName;
}
#pragma warning disable 56506 // [....], message.Properties is never null
if (!message.Properties.ContainsKey(HttpRequestMessageProperty.Name))
{
return this.catchAllOperationName;
}
HttpRequestMessageProperty prop = message.Properties[HttpRequestMessageProperty.Name] as HttpRequestMessageProperty;
if (prop == null)
{
return this.catchAllOperationName;
}
string method = prop.Method;
Uri to = message.Headers.To;
#pragma warning restore 56506
if (to == null)
{
return this.catchAllOperationName;
}
Collection results = table.Match(to);
if (results.Count == 0)
{
UriBuilder ub = new UriBuilder(to);
if (!ub.Path.EndsWith("/", StringComparison.Ordinal))
{
ub.Path = ub.Path + "/";
Uri originalPlusSlash = ub.Uri;
results = table.Match(originalPlusSlash);
if (results.Count != 0)
{
if (message.Properties.ContainsKey(HostedHttpContext.OriginalHttpRequestUriPropertyName))
{
ub.Host = ((Uri)(message.Properties[HostedHttpContext.OriginalHttpRequestUriPropertyName])).Host;
originalPlusSlash = ub.Uri;
}
message.Properties.Add(RedirectPropertyName, originalPlusSlash);
return redirectOperationName;
}
}
}
uriMatched = (results.Count != 0);
string methodStarOperationName = catchAllOperationName;
UriTemplateMatch methodStarMatch = null;
for (int i = 0; i < results.Count; ++i)
{
UriTemplateMatch r = results[i];
WCFLookupResult wlr = r.Data as WCFLookupResult;
Fx.Assert(wlr != null, "bad result");
if (wlr.Method == method)
{
message.Properties.Add(IncomingWebRequestContext.UriTemplateMatchResultsPropertyName, r);
return wlr.OperationName;
}
if (wlr.Method == WebHttpBehavior.WildcardMethod)
{
Fx.Assert(methodStarOperationName == catchAllOperationName, "there should be at most one WildcardMethod result in results");
methodStarMatch = r;
methodStarOperationName = wlr.OperationName;
}
}
if (methodStarMatch != null)
{
message.Properties.Add(IncomingWebRequestContext.UriTemplateMatchResultsPropertyName, methodStarMatch);
}
return methodStarOperationName;
}
// to enforce that no two ops have same UriTemplate & Method
class WCFKey
{
string method;
UriTemplate uriTemplate;
public WCFKey(UriTemplate uriTemplate, string method)
{
this.uriTemplate = uriTemplate;
this.method = method;
}
public override bool Equals(object obj)
{
WCFKey other = obj as WCFKey;
if (other == null)
{
return false;
}
return this.uriTemplate.IsEquivalentTo(other.uriTemplate) && this.method == other.method;
}
public override int GetHashCode()
{
return UriTemplateEquivalenceComparer.Instance.GetHashCode(this.uriTemplate);
}
}
// data of the UriTemplateMatchResults
class WCFLookupResult
{
string method;
string operationName;
public WCFLookupResult(string method, string operationName)
{
this.method = method;
this.operationName = operationName;
}
public string Method
{ get { return this.method; } }
public string OperationName
{ get { return this.operationName; } }
}
}
}
// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- QueryBranchOp.cs
- TextTreeText.cs
- ControlAdapter.cs
- DataContractSerializerOperationBehavior.cs
- ReadWriteSpinLock.cs
- ContentType.cs
- Link.cs
- Int32RectValueSerializer.cs
- SmtpClient.cs
- MsmqChannelFactoryBase.cs
- ActivityMetadata.cs
- DataFieldConverter.cs
- HandlerBase.cs
- CustomPopupPlacement.cs
- ToolStripContainer.cs
- ScriptMethodAttribute.cs
- BamlLocalizableResourceKey.cs
- StreamReader.cs
- VersionUtil.cs
- _SslSessionsCache.cs
- XPathDescendantIterator.cs
- XmlSignificantWhitespace.cs
- ObjectDataSourceEventArgs.cs
- SamlAttributeStatement.cs
- FileController.cs
- MeasureData.cs
- Inline.cs
- StreamHelper.cs
- ActivityScheduledRecord.cs
- ParameterSubsegment.cs
- RawMouseInputReport.cs
- ScriptHandlerFactory.cs
- WS2007HttpBindingCollectionElement.cs
- CapabilitiesRule.cs
- QilPatternFactory.cs
- VisualTreeHelper.cs
- StylusCollection.cs
- InvokeProviderWrapper.cs
- EventTrigger.cs
- counter.cs
- ManagedIStream.cs
- DependencyPropertyChangedEventArgs.cs
- MessagingActivityHelper.cs
- OperationResponse.cs
- TableDesigner.cs
- TextFormatter.cs
- WhereQueryOperator.cs
- DelegatingTypeDescriptionProvider.cs
- CallSiteHelpers.cs
- RelationshipEndCollection.cs
- DataFormats.cs
- TextLineBreak.cs
- EnterpriseServicesHelper.cs
- Assert.cs
- RegistryExceptionHelper.cs
- InputLanguageProfileNotifySink.cs
- XmlSchemaChoice.cs
- HelpKeywordAttribute.cs
- UpdateProgress.cs
- KnowledgeBase.cs
- ServerIdentity.cs
- ProfilePropertySettings.cs
- XmlSchemaAll.cs
- AliasedSlot.cs
- BaseInfoTable.cs
- XmlMemberMapping.cs
- Rules.cs
- RSAProtectedConfigurationProvider.cs
- ReadOnlyTernaryTree.cs
- ComponentSerializationService.cs
- CultureSpecificStringDictionary.cs
- Error.cs
- activationcontext.cs
- RequestStatusBarUpdateEventArgs.cs
- EncryptedKey.cs
- TextClipboardData.cs
- ScriptingRoleServiceSection.cs
- AssemblyInfo.cs
- XmlHierarchyData.cs
- DataPager.cs
- Control.cs
- DesignerActionHeaderItem.cs
- HttpCachePolicy.cs
- AssemblyAttributes.cs
- Brush.cs
- FilteredAttributeCollection.cs
- TailPinnedEventArgs.cs
- OleDbRowUpdatedEvent.cs
- CryptoKeySecurity.cs
- XmlSchemaAny.cs
- StyleSelector.cs
- SettingsProviderCollection.cs
- VersionedStreamOwner.cs
- CreateUserErrorEventArgs.cs
- MenuItemAutomationPeer.cs
- GenericEnumerator.cs
- WebBrowsableAttribute.cs
- IndexerNameAttribute.cs
- CardSpaceException.cs
- EpmTargetTree.cs