internal static void AddPreflightOperations(ServiceEndpoint endpoint, List <OperationDescription> corsOperations)
        {
            Dictionary <string, PreflightOperationBehavior> uriTemplates = new Dictionary <string, PreflightOperationBehavior>(StringComparer.OrdinalIgnoreCase);

            //
            foreach (OperationDescription operation in corsOperations)
            {
                if (operation.Behaviors.Find <WebGetAttribute>() != null || operation.IsOneWay == true)
                {
                    // no need to add preflight operation for GET requests, no support for 1-way messages
                    continue;
                }
                //
                WebInvokeAttribute originalWia         = operation.Behaviors.Find <WebInvokeAttribute>();
                string             originalUriTemplate = ((originalWia != null && originalWia.UriTemplate != null) ? NormalizeTemplate(originalWia.UriTemplate) : operation.Name);
                //
                string originalMethod = ((originalWia != null && originalWia.Method != null) ? originalWia.Method : "POST");
                if (uriTemplates.ContainsKey(originalUriTemplate) == true)
                {
                    // there is already an OPTIONS operation for this URI, we can reuse it
                    PreflightOperationBehavior operationBehavior = uriTemplates[originalUriTemplate];
                    operationBehavior.AddAllowedMethod(originalMethod);
                }
                else
                {
                    ContractDescription        contract = operation.DeclaringContract;
                    PreflightOperationBehavior preflightOperationBehavior = null;
                    OperationDescription       preflightOperation         = CreatePreflightOperation(operation, originalUriTemplate, originalMethod, out preflightOperationBehavior);
                    uriTemplates.Add(originalUriTemplate, preflightOperationBehavior);
                    //
                    contract.Operations.Add(preflightOperation);
                }
            }
        }
Exemple #2
0
        private void addPreflightOperations(ServiceEndpoint endpoint)
        {
            List <OperationDescription> corsEnabledOperations = endpoint.Contract.Operations.Where(_ => _.Behaviors.Find <CORSEnabledOperationAttribute>() != null).ToList();

            if (corsEnabledOperations != null && corsEnabledOperations.Any() == true)
            {
                PreflightOperationBehavior.AddPreflightOperations(endpoint, corsEnabledOperations);
            }
        }
        internal static OperationDescription CreatePreflightOperation(OperationDescription operation, string originalUriTemplate, string originalMethod, out PreflightOperationBehavior preflightOperationBehavior)
        {
            ContractDescription contract = operation.DeclaringContract;
            //
            // create new Operation Contract for the Method="OPTIONS"
            OperationDescription ret = new OperationDescription(operation.Name + CORSEnabledOperationAttribute.PreflightSuffix, contract);

            //
            // configure Messages
            {
                MessageDescription inputMessage = new MessageDescription(operation.Messages[0].Action + CORSEnabledOperationAttribute.PreflightSuffix, MessageDirection.Input);
                inputMessage.Body.Parts.Add(new MessagePartDescription("input", contract.Namespace)
                {
                    Index = 0, Type = typeof(Message)
                });
                ret.Messages.Add(inputMessage);
            }
            {
                MessageDescription outputMessage = new MessageDescription(operation.Messages[1].Action + CORSEnabledOperationAttribute.PreflightSuffix, MessageDirection.Output);
                outputMessage.Body.ReturnValue = new MessagePartDescription(ret.Name + "Return", contract.Namespace)
                {
                    Type = typeof(Message)
                };
                ret.Messages.Add(outputMessage);
            }
            //
            // configure Behaviors
            {
                // configure default Behaviors
                ret.Behaviors.Add(new WebInvokeAttribute()
                {
                    Method = "OPTIONS", UriTemplate = originalUriTemplate,
                });
                ret.Behaviors.Add(new DataContractSerializerOperationBehavior(ret));
                //
                // configure custom Behavior
                preflightOperationBehavior = new PreflightOperationBehavior(ret);
                preflightOperationBehavior.AddAllowedMethod(originalMethod);
                ret.Behaviors.Add(preflightOperationBehavior);
            }
            //
            return(ret);
        }