示例#1
0
        private void AddPreflightOperations(ServiceEndpoint endpoint, List <OperationDescription> corsOperations)
        {
            Dictionary <string, PreflightOperationBehavior> uriTemplates =
                new Dictionary <string, PreflightOperationBehavior>(StringComparer.OrdinalIgnoreCase);

            foreach (var operation in corsOperations)
            {
                if (operation.Behaviors.Find <WebGetAttribute>() != null || operation.IsOneWay)
                {
                    // no need to add preflight operation for GET requests, no support for 1-way messages
                    continue;
                }

                string             originalUriTemplate;
                WebInvokeAttribute originalWia = operation.Behaviors.Find <WebInvokeAttribute>();

                if (originalWia != null && originalWia.UriTemplate != null)
                {
                    originalUriTemplate = NormalizeTemplate(originalWia.UriTemplate);
                }
                else
                {
                    originalUriTemplate = operation.Name;
                }

                string originalMethod = originalWia != null && originalWia.Method != null ? originalWia.Method : "POST";

                if (uriTemplates.ContainsKey(originalUriTemplate))
                {
                    // 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;
                    OperationDescription       preflightOperation;
                    PreflightOperationBehavior preflightOperationBehavior;
                    CreatePreflightOperation(operation, originalUriTemplate, originalMethod, contract,
                                             out preflightOperation, out preflightOperationBehavior);
                    uriTemplates.Add(originalUriTemplate, preflightOperationBehavior);

                    contract.Operations.Add(preflightOperation);
                }
            }
        }
示例#2
0
        private static void CreatePreflightOperation(OperationDescription operation, string originalUriTemplate,
                                                     string originalMethod, ContractDescription contract, out OperationDescription preflightOperation,
                                                     out PreflightOperationBehavior preflightOperationBehavior)
        {
            preflightOperation = new OperationDescription(operation.Name + CorsConstants.PreflightSuffix, contract);
            MessageDescription inputMessage =
                new MessageDescription(operation.Messages[0].Action + CorsConstants.PreflightSuffix,
                                       MessageDirection.Input);

            inputMessage.Body.Parts.Add(new MessagePartDescription("input", contract.Namespace)
            {
                Index = 0, Type = typeof(Message)
            });
            preflightOperation.Messages.Add(inputMessage);
            MessageDescription outputMessage =
                new MessageDescription(operation.Messages[1].Action + CorsConstants.PreflightSuffix,
                                       MessageDirection.Output);

            outputMessage.Body.ReturnValue =
                new MessagePartDescription(preflightOperation.Name + "Return", contract.Namespace)
            {
                Type = typeof(Message)
            };
            preflightOperation.Messages.Add(outputMessage);

            WebInvokeAttribute wia = new WebInvokeAttribute();

            wia.UriTemplate = originalUriTemplate;
            wia.Method      = "OPTIONS";

            preflightOperation.Behaviors.Add(wia);
            preflightOperation.Behaviors.Add(new DataContractSerializerOperationBehavior(preflightOperation));
            preflightOperationBehavior = new PreflightOperationBehavior(preflightOperation);
            preflightOperationBehavior.AddAllowedMethod(originalMethod);
            preflightOperation.Behaviors.Add(preflightOperationBehavior);
        }