/// <summary> /// Adds the preflight operations. /// </summary> /// <param name="endpoint">The endpoint.</param> /// <param name="corsOperations">The cors operations.</param> 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)) { 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)) { PreflightOperationBehavior operationBehavior = uriTemplates[originalUriTemplate]; operationBehavior.AddAllowedMethod(originalMethod); } else { ContractDescription contract = operation.DeclaringContract; OperationDescription 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 preflightOperationBehavior = new PreflightOperationBehavior(preflightOperation); preflightOperationBehavior.AddAllowedMethod(originalMethod); preflightOperationBehavior.AddAllowedMethod("DELETE"); preflightOperation.Behaviors.Add(preflightOperationBehavior); uriTemplates.Add(originalUriTemplate, preflightOperationBehavior); contract.Operations.Add(preflightOperation); } } }
/// <summary> /// Adds the preflight operations. /// </summary> /// <param name="endpoint">The endpoint.</param> /// <param name="corsOperations">The cors operations.</param> 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)) { 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)) { PreflightOperationBehavior operationBehavior = uriTemplates[originalUriTemplate]; operationBehavior.AddAllowedMethod(originalMethod); } else { ContractDescription contract = operation.DeclaringContract; OperationDescription 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 preflightOperationBehavior = new PreflightOperationBehavior(preflightOperation); preflightOperationBehavior.AddAllowedMethod(originalMethod); preflightOperationBehavior.AddAllowedMethod("DELETE"); preflightOperation.Behaviors.Add(preflightOperationBehavior); uriTemplates.Add(originalUriTemplate, preflightOperationBehavior); contract.Operations.Add(preflightOperation); } } }