Example #1
0
        public virtual void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
        {
            if (endpoint == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("endpoint");
            }
            if (endpointDispatcher == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("endpointDispatcher");
            }
            WebMessageEncodingBindingElement webEncodingBindingElement = endpoint.Binding.CreateBindingElements().Find<WebMessageEncodingBindingElement>();
            if (webEncodingBindingElement != null && webEncodingBindingElement.CrossDomainScriptAccessEnabled)
            {
                ISecurityCapabilities securityCapabilities = endpoint.Binding.GetProperty<ISecurityCapabilities>(new BindingParameterCollection());
                if (securityCapabilities.SupportsClientAuthentication)
                {
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException(SR2.CrossDomainJavascriptAuthNotSupported));
                }
                if (endpoint.Contract.Behaviors.Contains(typeof(JavascriptCallbackBehaviorAttribute)))
                {
                    JavascriptCallbackBehaviorAttribute behavior = endpoint.Contract.Behaviors[typeof(JavascriptCallbackBehaviorAttribute)] as JavascriptCallbackBehaviorAttribute;
                    this.JavascriptCallbackParameterName = behavior.UrlParameterName;
                }
                else
                {
                    this.JavascriptCallbackParameterName = defaultCallbackParameterName;
                }
                endpointDispatcher.DispatchRuntime.MessageInspectors.Add(new JavascriptCallbackMessageInspector(this.JavascriptCallbackParameterName));
            }
            if (this.HelpEnabled)
            {
                this.HelpUri = new UriTemplate(HelpPage.OperationListHelpPageUriTemplate).BindByPosition(endpoint.ListenUri);
            }
#pragma warning disable 56506 // Microsoft, endpoint.Contract is never null
            this.reflector = new XmlSerializerOperationBehavior.Reflector(endpoint.Contract.Namespace, null);
#pragma warning restore 56506

            // endpoint filter
            endpointDispatcher.AddressFilter = new PrefixEndpointAddressMessageFilter(endpoint.Address);
            endpointDispatcher.ContractFilter = new MatchAllMessageFilter();
            // operation selector
#pragma warning disable 56506 // Microsoft, endpointDispatcher.DispatchRuntime is never null
            endpointDispatcher.DispatchRuntime.OperationSelector = this.GetOperationSelector(endpoint);
#pragma warning restore 56506
            // unhandled operation
            string actionStarOperationName = null;
#pragma warning disable 56506 // Microsoft, endpoint.Contract is never null
            foreach (OperationDescription od in endpoint.Contract.Operations)
#pragma warning restore 56506
            {
                if (od.Messages[0].Direction == MessageDirection.Input
                    && od.Messages[0].Action == WildcardAction)
                {
                    actionStarOperationName = od.Name;
                    break;
                }
            }
            if (actionStarOperationName != null)
            {
                // WCF v1 installs any Action="*" op into UnhandledDispatchOperation, but WebHttpBehavior
                // doesn't want this, so we 'move' that operation back into normal set of operations
#pragma warning disable 56506 // Microsoft, endpointDispatcher.DispatchRuntime.{Operations,UnhandledDispatchOperation} is never null
                endpointDispatcher.DispatchRuntime.Operations.Add(
                    endpointDispatcher.DispatchRuntime.UnhandledDispatchOperation);
#pragma warning restore 56506
            }

            FormatSelectingMessageInspector formatSelectingMessageInspector = null;
            string xmlContentType = null;
            string jsonContentType = null;

 
            if (webEncodingBindingElement != null)
            {
                XmlFormatMapping xmlFormatMapping = new XmlFormatMapping(webEncodingBindingElement.WriteEncoding, webEncodingBindingElement.ContentTypeMapper);
                JsonFormatMapping jsonFormatMapping = new JsonFormatMapping(webEncodingBindingElement.WriteEncoding, webEncodingBindingElement.ContentTypeMapper);
 
                xmlContentType = xmlFormatMapping.DefaultContentType.ToString();
                jsonContentType = jsonFormatMapping.DefaultContentType.ToString();
 
                if (AutomaticFormatSelectionEnabled)
                {
                    formatSelectingMessageInspector = new FormatSelectingMessageInspector(this, new List<MultiplexingFormatMapping> { xmlFormatMapping, jsonFormatMapping });
                    endpointDispatcher.DispatchRuntime.MessageInspectors.Add(formatSelectingMessageInspector);
                }
            }
            else
            {
                xmlContentType = TextMessageEncoderFactory.GetContentType(XmlFormatMapping.defaultMediaType, TextEncoderDefaults.Encoding);
                jsonContentType = JsonMessageEncoderFactory.GetContentType(null);
            }

#pragma warning disable 56506 // Microsoft, endpointDispatcher.DispatchRuntime.UnhandledDispatchOperation is never null
            // always install UnhandledDispatchOperation (WebHttpDispatchOperationSelector may choose not to use it)
            endpointDispatcher.DispatchRuntime.UnhandledDispatchOperation = new DispatchOperation(endpointDispatcher.DispatchRuntime, "*", WildcardAction, WildcardAction);
            endpointDispatcher.DispatchRuntime.UnhandledDispatchOperation.DeserializeRequest = false;
            endpointDispatcher.DispatchRuntime.UnhandledDispatchOperation.SerializeReply = false;
            endpointDispatcher.DispatchRuntime.UnhandledDispatchOperation.Invoker = new HttpUnhandledOperationInvoker { HelpUri = this.HelpUri };
#pragma warning restore 56506
            // install formatters and parameter inspectors
            foreach (OperationDescription od in endpoint.Contract.Operations)
            {
                DispatchOperation dop = null;
#pragma warning disable 56506 // Microsoft, endpointDispatcher.DispatchRuntime, DispatchRuntime.Operations are never null
                if (endpointDispatcher.DispatchRuntime.Operations.Contains(od.Name))
#pragma warning restore 56506
                {
                    dop = endpointDispatcher.DispatchRuntime.Operations[od.Name];
                }
#pragma warning disable 56506 // Microsoft, endpointDispatcher.DispatchRuntime.UnhandledDispatchOperation is never null
                else if (endpointDispatcher.DispatchRuntime.UnhandledDispatchOperation.Name == od.Name)
                {
                    dop = endpointDispatcher.DispatchRuntime.UnhandledDispatchOperation;
                }
#pragma warning restore 56506
                if (dop != null)
                {
                    IDispatchMessageFormatter requestDispatch = GetRequestDispatchFormatter(od, endpoint);
                    IDispatchMessageFormatter replyDispatch = GetReplyDispatchFormatter(od, endpoint);

                    MultiplexingDispatchMessageFormatter replyDispatchAsMultiplexing = replyDispatch as MultiplexingDispatchMessageFormatter;

                    if (replyDispatchAsMultiplexing != null)
                    {
                        // here we are adding all default content types, despite the fact that
                        // some of the formatters in MultiplexingDispatchMessageFormatter might not be present
                        // i.e. the JSON formatter

                        replyDispatchAsMultiplexing.DefaultContentTypes.Add(WebMessageFormat.Xml, xmlContentType);
                        replyDispatchAsMultiplexing.DefaultContentTypes.Add(WebMessageFormat.Json, jsonContentType);

                        if (formatSelectingMessageInspector != null)
                        {
                            formatSelectingMessageInspector.RegisterOperation(od.Name, replyDispatchAsMultiplexing);
                        }
                    }

                    dop.Formatter = new CompositeDispatchFormatter(requestDispatch, replyDispatch);
                    dop.FaultFormatter = new WebFaultFormatter(dop.FaultFormatter);
                    dop.DeserializeRequest = (requestDispatch != null);
                    dop.SerializeReply = od.Messages.Count > 1 && (replyDispatch != null);
                }
            }
            
            if (this.HelpEnabled)
            {
                HelpPage helpPage = new HelpPage(this, endpoint.Contract);
                DispatchOperation dispatchOperation = new DispatchOperation(endpointDispatcher.DispatchRuntime, HelpOperationInvoker.OperationName, null, null)
                {
                    DeserializeRequest = false,
                    SerializeReply = false,
                    Invoker = new HelpOperationInvoker(helpPage, endpointDispatcher.DispatchRuntime.UnhandledDispatchOperation.Invoker),
                };
                endpointDispatcher.DispatchRuntime.Operations.Add(dispatchOperation);
            }
            AddServerErrorHandlers(endpoint, endpointDispatcher);
        }
 public HelpOperationInvoker(HelpPage helpPage, IOperationInvoker unhandledDispatchOperation)
 {
     this.helpPage = helpPage;
     this.unhandledDispatchOperation = unhandledDispatchOperation;
 }