public void SelectOperationThrowsWithUriMatchingButMethodNotMatching() { HttpOperationAssert.Execute <UriTemplateService>( (IEnumerable <HttpOperationDescription> operations) => { Uri baseAddress = new Uri("http://localhost/baseAddress"); UriAndMethodOperationSelector selector = new UriAndMethodOperationSelector(baseAddress, operations, TrailingSlashMode.Ignore); bool oneMethodNotAllowedFound = false; foreach (HttpOperationDescription operation in operations) { List <HttpMethod> otherAllowedMethods = operations .Where(otherOperation => otherOperation.GetUriTemplate().IsEquivalentTo(operation.GetUriTemplate())) .Select(otherOperation => otherOperation.GetHttpMethod()) .ToList(); if (otherAllowedMethods.Count > 1) { UriTemplate uriTemplate = operation.GetUriTemplate(); string expectedOperation = operation.Name; string[] uriParameters = uriTemplate.PathSegmentVariableNames .Concat(uriTemplate.QueryValueVariableNames) .ToArray(); Uri requestUri = uriTemplate.BindByPosition(baseAddress, uriParameters); foreach (HttpMethod method in HttpTestData.AllHttpMethods.Except(otherAllowedMethods)) { HttpRequestMessage request = new HttpRequestMessage(method, requestUri); ExceptionAssert.Throws <HttpResponseException>( () => selector.SelectOperation(request), (responseException) => { HttpResponseMessage expectedResponse = StandardHttpResponseMessageBuilder.CreateMethodNotAllowedResponse(request, otherAllowedMethods, null); HttpAssert.AreEqual(expectedResponse, responseException.Response); oneMethodNotAllowedFound = true; }); } } } Assert.IsTrue(oneMethodNotAllowedFound, "No interesting test cases actually executed."); }); }
/// <summary> /// Selects a service operation based on the HTTP verb and the request Uri of the incoming request message. /// </summary> /// <param name="request">The incoming <see cref="HttpRequestMessage"/>.</param> /// <returns>The name of the operation to be associated with the message.</returns> protected override sealed string OnSelectOperation(HttpRequestMessage request) { Fx.Assert(request != null, "The base class ensures that the 'request' parameter will not be null."); bool matchDifferByTrailingSlash; string operationName = null; HttpResponseMessage errorResponse = null; if (request.RequestUri != null) { if (this.TrySelectOperation(request, out operationName, out matchDifferByTrailingSlash)) { if (matchDifferByTrailingSlash && this.trailingSlashMode == TrailingSlashMode.AutoRedirect) { Uri newLocation = BuildUriDifferingByTrailingSlash(request); errorResponse = StandardHttpResponseMessageBuilder.CreateTemporaryRedirectResponse(request, request.RequestUri, newLocation); } } else if (!CanUriMatch(this.wildcardTable, request.RequestUri, out operationName)) { IEnumerable <HttpMethod> allowedMethods = this.RetrieveAllowedMethodsIfAny(request); if (allowedMethods != null) { errorResponse = StandardHttpResponseMessageBuilder.CreateMethodNotAllowedResponse(request, allowedMethods, this.HelpPageUri); } } } if (operationName == null && errorResponse == null) { errorResponse = StandardHttpResponseMessageBuilder.CreateNotFoundResponse(request, this.HelpPageUri); } if (errorResponse != null) { throw Fx.Exception.AsError(new HttpResponseException(errorResponse)); } return(operationName); }