public void GetUriTemplate_Returns_UriTemplate() { ExceptionAssert.ThrowsArgumentNull("operation", () => ((HttpOperationDescription)null).GetUriTemplate()); ContractDescription contract = ContractDescription.GetContract(typeof(UriTemplateService)); OperationDescription operationDescription = contract.Operations.Where(od => od.Name == "NoAttributeOperation").FirstOrDefault(); HttpOperationDescription httpOperationDescription = operationDescription.ToHttpOperationDescription(); UriTemplate template = httpOperationDescription.GetUriTemplate(); Assert.AreEqual(0, template.PathSegmentVariableNames.Count, "HttpOperationDescription.GetUriTemplate should return a UriTemplate with zero path variables."); Assert.AreEqual(0, template.QueryValueVariableNames.Count, "HttpOperationDescription.GetUriTemplate should return a UriTemplate with zero query variables."); operationDescription = contract.Operations.Where(od => od.Name == "WebInvokeSansTemplateStringOperation").FirstOrDefault(); httpOperationDescription = operationDescription.ToHttpOperationDescription(); template = httpOperationDescription.GetUriTemplate(); Assert.AreEqual(0, template.PathSegmentVariableNames.Count, "HttpOperationDescription.GetUriTemplate should return a UriTemplate with zero path variables."); Assert.AreEqual(0, template.QueryValueVariableNames.Count, "HttpOperationDescription.GetUriTemplate should return a UriTemplate with zero query variables."); operationDescription = contract.Operations.Where(od => od.Name == "WebGetSansTemplateStringOperation").FirstOrDefault(); httpOperationDescription = operationDescription.ToHttpOperationDescription(); template = httpOperationDescription.GetUriTemplate(); Assert.AreEqual(0, template.PathSegmentVariableNames.Count, "HttpOperationDescription.GetUriTemplate should return a UriTemplate with zero path variables."); Assert.AreEqual(0, template.QueryValueVariableNames.Count, "HttpOperationDescription.GetUriTemplate should return a UriTemplate with zero query variables."); operationDescription = contract.Operations.Where(od => od.Name == "WebInvokeWithParametersOperation").FirstOrDefault(); httpOperationDescription = operationDescription.ToHttpOperationDescription(); template = httpOperationDescription.GetUriTemplate(); Assert.AreEqual(0, template.PathSegmentVariableNames.Count, "HttpOperationDescription.GetUriTemplate should return a UriTemplate with zero path variables."); Assert.AreEqual(0, template.QueryValueVariableNames.Count, "HttpOperationDescription.GetUriTemplate should return a UriTemplate with zero query variables."); operationDescription = contract.Operations.Where(od => od.Name == "WebGetWithParametersOperation").FirstOrDefault(); httpOperationDescription = operationDescription.ToHttpOperationDescription(); template = httpOperationDescription.GetUriTemplate(); Assert.AreEqual(0, template.PathSegmentVariableNames.Count, "HttpOperationDescription.GetUriTemplate should return a UriTemplate with zero path variables."); Assert.AreEqual(2, template.QueryValueVariableNames.Count, "HttpOperationDescription.GetUriTemplate should return a UriTemplate with two query variables."); Assert.AreEqual("IN1", template.QueryValueVariableNames[0], "HttpOperationDescription.GetUriTemplate should return a UriTemplate with query variable 'IN1'."); Assert.AreEqual("IN2", template.QueryValueVariableNames[1], "HttpOperationDescription.GetUriTemplate should return a UriTemplate with query variable 'IN2'."); operationDescription = contract.Operations.Where(od => od.Name == "WebInvokeWithEmptyTemplateStringOperation").FirstOrDefault(); httpOperationDescription = operationDescription.ToHttpOperationDescription(); template = httpOperationDescription.GetUriTemplate(); Assert.AreEqual(0, template.PathSegmentVariableNames.Count, "HttpOperationDescription.GetUriTemplate should return a UriTemplate with zero path variables."); Assert.AreEqual(0, template.QueryValueVariableNames.Count, "HttpOperationDescription.GetUriTemplate should return a UriTemplate with zero query variables."); operationDescription = contract.Operations.Where(od => od.Name == "WebInvokeWithTemplateStringOperation").FirstOrDefault(); httpOperationDescription = operationDescription.ToHttpOperationDescription(); template = httpOperationDescription.GetUriTemplate(); Assert.AreEqual(1, template.PathSegmentVariableNames.Count, "HttpOperationDescription.GetUriTemplate should return a UriTemplate with one path variables."); Assert.AreEqual(1, template.QueryValueVariableNames.Count, "HttpOperationDescription.GetUriTemplate should return a UriTemplate with one query variables."); Assert.AreEqual("VARIABLE1", template.PathSegmentVariableNames[0], "HttpOperationDescription.GetUriTemplate should return a UriTemplate with query variable 'VARIABLE1'."); Assert.AreEqual("VARIABLE2", template.QueryValueVariableNames[0], "HttpOperationDescription.GetUriTemplate should return a UriTemplate with query variable 'VARIABLE2'."); operationDescription = contract.Operations.Where(od => od.Name == "WebGetWithTemplateStringOperation").FirstOrDefault(); httpOperationDescription = operationDescription.ToHttpOperationDescription(); template = httpOperationDescription.GetUriTemplate(); Assert.AreEqual(1, template.PathSegmentVariableNames.Count, "HttpOperationDescription.GetUriTemplate should return a UriTemplate with one path variables."); Assert.AreEqual(0, template.QueryValueVariableNames.Count, "HttpOperationDescription.GetUriTemplate should return a UriTemplate with zero query variables."); Assert.AreEqual("VARIABLE1", template.PathSegmentVariableNames[0], "HttpOperationDescription.GetUriTemplate should return a UriTemplate with query variable 'VARIABLE1'."); }
/// <summary> /// Called when the ordered collection of <see cref="HttpOperationHandler"/> instances is being created for /// the given <paramref name="operation"/>. Can be overridden in a derived class to customize the /// collection of <see cref="HttpOperationHandler"/> instances returned. /// </summary> /// <remarks> /// The base implemenation returns the standard request <see cref="HttpOperationHandler"/> instances for the given /// operation. /// </remarks> /// <param name="endpoint">The service endpoint.</param> /// <param name="operation">The description of the service operation.</param> /// <returns> /// The ordered collection of <see cref="HttpOperationHandler"/> instances to use when handling /// <see cref="HttpRequestMessage"/> instances for the given operation. /// </returns> protected virtual Collection <HttpOperationHandler> OnCreateRequestHandlers(ServiceEndpoint endpoint, HttpOperationDescription operation) { if (endpoint == null) { throw Fx.Exception.ArgumentNull("endpoint"); } if (operation == null) { throw Fx.Exception.ArgumentNull("operation"); } Collection <HttpOperationHandler> requestHandlers = new Collection <HttpOperationHandler>(); HttpMethod method = operation.GetHttpMethod(); UriTemplate uriTemplate = operation.GetUriTemplate(); string[] uriTemplateParameterNames = uriTemplate.PathSegmentVariableNames.Concat(uriTemplate.QueryValueVariableNames).ToArray(); if (uriTemplateParameterNames.Length > 0) { requestHandlers.Add(new UriTemplateHandler(endpoint.Address.Uri, uriTemplate)); } if (method != HttpMethod.Get && method != HttpMethod.Head) { HttpParameter requestContentParameter = GetRequestContentHandler(operation, uriTemplateParameterNames); if (requestContentParameter != null) { requestContentParameter.IsContentParameter = true; requestHandlers.Add(new RequestContentHandler(requestContentParameter, this.Formatters)); SetXmlAndJsonSerializers(operation, requestContentParameter, this.Formatters); } } return(requestHandlers); }
public static OperationDescription GetEquivalentOperationDescription(OperationDescription operation) { Fx.Assert(operation != null, "OperationDescription cannnot be null"); OperationDescription copy = CreateEmptyOperationDescription(operation); HttpOperationDescription httpDescription = copy.ToHttpOperationDescription(); HttpOperationDescription originalHttpDescription = operation.ToHttpOperationDescription(); UriTemplate template = originalHttpDescription.GetUriTemplate(); List <string> templateVariables = new List <string>(template.PathSegmentVariableNames.Concat(template.QueryValueVariableNames)); IEnumerable <HttpParameter> originalRequestBodyParameters = originalHttpDescription.InputParameters.Where(param => param.IsContentParameter); IEnumerable <HttpParameter> originalResponseBodyParameters = originalHttpDescription.OutputParameters.Where(param => param.IsContentParameter); IEnumerable <HttpParameter> originalUriTemplateParameters = originalHttpDescription.InputParameters.Where( (param) => { foreach (string templateVariable in templateVariables) { if (string.Equals(templateVariable, param.Name, StringComparison.OrdinalIgnoreCase)) { return(true); } } return(false); }); httpDescription.ReturnValue = originalHttpDescription.ReturnValue; // add UriTemplate parameters foreach (HttpParameter parameter in originalUriTemplateParameters) { httpDescription.InputParameters.Add(parameter); } // add body parameters foreach (HttpParameter parameter in originalRequestBodyParameters) { httpDescription.InputParameters.Add(parameter); } int index = httpDescription.InputParameters.Count; int requestBodyParametersCount = originalRequestBodyParameters.Count <HttpParameter>(); int responseBodyParametersCount = originalResponseBodyParameters.Count <HttpParameter>(); if (requestBodyParametersCount == 0 || responseBodyParametersCount == 0) { // Special case if any input parameter is HttpRequestMessage or HttpResponseMessage foreach (HttpParameter inputParameter in originalHttpDescription.InputParameters) { if (requestBodyParametersCount == 0 && originalHttpDescription.GetHttpMethod() != HttpMethod.Get && httpRequestMessageType.IsAssignableFrom(inputParameter.Type)) { // add the HttpRequestmessage as a body parameter of type Message HttpParameter parameter = new HttpParameter(new MessagePartDescription(inputParameter.Name, string.Empty) { Type = typeof(Message), Index = index++ }); httpDescription.InputParameters.Add(parameter); } if (!operation.IsOneWay && responseBodyParametersCount == 0 && httpResponseMessageType.IsAssignableFrom(inputParameter.Type)) { // add the HttpResponsemessage as a return value of type Message httpDescription.ReturnValue = new HttpParameter(new MessagePartDescription(inputParameter.Name, string.Empty) { Type = typeof(Message) }); } } } foreach (HttpParameter parameter in originalResponseBodyParameters) { // cannot do a byRef comparison here if (parameter.Type != originalHttpDescription.ReturnValue.Type || !string.Equals(parameter.Name, originalHttpDescription.ReturnValue.Name, StringComparison.OrdinalIgnoreCase)) { httpDescription.OutputParameters.Add(parameter); } } if (responseBodyParametersCount == 0) { foreach (HttpParameter outputParameter in originalHttpDescription.OutputParameters) { // special case HttpResponseMessage when it is set as an out parameter if (httpResponseMessageType.IsAssignableFrom(outputParameter.Type)) { httpDescription.ReturnValue = new HttpParameter(new MessagePartDescription(outputParameter.Name, string.Empty) { Type = typeof(Message) }); } } } if (templateVariables.Count > originalUriTemplateParameters.Count <HttpParameter>()) { // this means that we have some UriTemplate variables that are not explicitly bound to an input parameter foreach (HttpParameter parameter in originalUriTemplateParameters) { templateVariables.Remove(parameter.Name); } foreach (string variable in templateVariables) { HttpParameter parameter = new HttpParameter(new MessagePartDescription(variable, operation.DeclaringContract.Namespace) { Type = typeof(string), Index = index++ }); httpDescription.InputParameters.Add(parameter); } } return(httpDescription.ToOperationDescription()); }