Example #1
0
        public static void VerifySelectOperationWithAutoRedirectMode(string requestUri, string operationName, UriAndMethodOperationSelector httpOperationSelector, bool shouldAutoRedirect)
        {
            string matchedOperationName;
            bool matchDifferByTrailingSlash;
            HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, requestUri);
            bool result = httpOperationSelector.TrySelectOperation(request, out matchedOperationName, out matchDifferByTrailingSlash);
            Assert.IsTrue(result);
            Assert.AreEqual(matchedOperationName, operationName, String.Format("request {0} should match the operation {1}", requestUri, operationName));
            Assert.AreEqual(matchDifferByTrailingSlash, shouldAutoRedirect);

            Uri originalUri = new Uri(requestUri);
            UriBuilder uriBuilder = new UriBuilder(originalUri);
            uriBuilder.Path = originalUri.AbsolutePath.EndsWith("/") ? uriBuilder.Path.TrimEnd('/') : uriBuilder.Path + "/";
            Uri backSlashAlteredUri = uriBuilder.Uri;

            if (!shouldAutoRedirect)
            {
                matchedOperationName = httpOperationSelector.SelectOperation(request);
                Assert.AreEqual(matchedOperationName, operationName, String.Format("request {0} should match the operation {1}", requestUri, operationName));
            }
            else
            {
                ExceptionAssert.Throws<HttpResponseException>(
                    () => httpOperationSelector.SelectOperation(request),
                    (responseException) =>
                        {
                            HttpResponseMessage expectedResponse = StandardHttpResponseMessageBuilder.CreateTemporaryRedirectResponse(request, originalUri, backSlashAlteredUri);
                            HttpAssert.AreEqual(expectedResponse, responseException.Response);
                        });
            }
        }
Example #2
0
 public static void VerifySelectOperationWithIgnoreMode(string requestUri, string operationName, UriAndMethodOperationSelector httpOperationSelector)
 {
     HttpRequestMessage message = new HttpRequestMessage(HttpMethod.Get, requestUri);
     string matchedOperationName = httpOperationSelector.SelectOperation(message);
     Assert.AreEqual(matchedOperationName, operationName, String.Format("request {0} should match the operation {1}", requestUri, operationName));
 }
Example #3
0
        public void Ignore_TrailingSlash_Tests()
        {
            string baseUri = "http://localhost/myservice";
            List<HttpOperationDescription> operationList1 = GenerateOperationsList1();
            UriAndMethodOperationSelector httpOperationSelector = new UriAndMethodOperationSelector(new Uri(baseUri), operationList1, TrailingSlashMode.Ignore);

            string baseUriWithSlash = "http://localhost/myservice/";
            List<HttpOperationDescription> operationList2 = GenerateOperationsList2();
            UriAndMethodOperationSelector httpOperationSelector2 = new UriAndMethodOperationSelector(new Uri(baseUriWithSlash), operationList2, TrailingSlashMode.Ignore);

            //{"GetCollection", new UriTemplate("")},
            VerifySelectOperationWithIgnoreMode(baseUri, "GetCollection", httpOperationSelector);
            VerifySelectOperationWithIgnoreMode(baseUri + "/", "GetCollection", httpOperationSelector);

            // {"PQuery", new UriTemplate("p?value={value}")},
            VerifySelectOperationWithIgnoreMode(baseUri + "/" + "p", "PQuery", httpOperationSelector);
            VerifySelectOperationWithIgnoreMode(baseUri + "/" + "p/", "PQuery", httpOperationSelector);
            VerifySelectOperationWithIgnoreMode(baseUri + "/" + "p", "PQuery", httpOperationSelector);
            VerifySelectOperationWithIgnoreMode(baseUri + "/" + "p?value=1", "PQuery", httpOperationSelector);
            VerifySelectOperationWithIgnoreMode(baseUri + "/" + "p/?value=1", "PQuery", httpOperationSelector);

            // {"QQuery", new UriTemplate("q/?value={value}")},
            VerifySelectOperationWithIgnoreMode(baseUri + "/" + "q/?value=hello", "QQuery", httpOperationSelector);
            VerifySelectOperationWithIgnoreMode(baseUri + "/" + "q?value=hello", "QQuery", httpOperationSelector);

            // {"BarWildcard", new UriTemplate("bar/{*foo}")},
            VerifySelectOperationWithIgnoreMode(baseUri + "/" + "bar/fooVal", "BarWildcard", httpOperationSelector);
            VerifySelectOperationWithIgnoreMode(baseUri + "/" + "bar/", "BarWildcard", httpOperationSelector);
            VerifySelectOperationWithIgnoreMode(baseUri + "/" + "bar", "BarWildcard", httpOperationSelector);

            // {"GetXY", new UriTemplate("x/y")},
            VerifySelectOperationWithIgnoreMode(baseUri + "/" + "x/y", "GetXY", httpOperationSelector);
            VerifySelectOperationWithIgnoreMode(baseUri + "/" + "x/y/", "GetXY", httpOperationSelector);

            // {"GetRS", new UriTemplate("r/s/")},
            VerifySelectOperationWithIgnoreMode(baseUri + "/" + "r/s/", "GetRS", httpOperationSelector);
            VerifySelectOperationWithIgnoreMode(baseUri + "/" + "r/s", "GetRS", httpOperationSelector);

            // {"Test", new UriTemplate("test/{a=1}")},
            VerifySelectOperationWithIgnoreMode(baseUri + "/" + "test/", "Test", httpOperationSelector);
            VerifySelectOperationWithIgnoreMode(baseUri + "/" + "test/", "Test", httpOperationSelector);
            VerifySelectOperationWithIgnoreMode(baseUri + "/" + "test/aVal", "Test", httpOperationSelector);
            VerifySelectOperationWithIgnoreMode(baseUri + "/" + "test/aVal/", "Test", httpOperationSelector);

            // {"GetCollection", new UriTemplate("?value={value}")},
            VerifySelectOperationWithIgnoreMode(baseUriWithSlash, "GetCollection", httpOperationSelector2);
            VerifySelectOperationWithIgnoreMode(baseUri + "/", "GetCollection", httpOperationSelector2);
            VerifySelectOperationWithIgnoreMode(baseUriWithSlash + "?value=hello", "GetCollection", httpOperationSelector2);
            VerifySelectOperationWithIgnoreMode(baseUri + "?value=hello", "GetCollection", httpOperationSelector2);

            // {"QQuery", new UriTemplate("q/{name}/?value={value}")},
            VerifySelectOperationWithIgnoreMode(baseUriWithSlash + "q/nameVal/?value=hello", "QQuery", httpOperationSelector2);
            VerifySelectOperationWithIgnoreMode(baseUriWithSlash + "q/nameVal?value=hello", "QQuery", httpOperationSelector2);

            //{"GetId", new UriTemplate("{id}")},
            VerifySelectOperationWithIgnoreMode(baseUriWithSlash + "idVal", "GetId", httpOperationSelector2);
            VerifySelectOperationWithIgnoreMode(baseUriWithSlash + "idVal/", "GetId", httpOperationSelector2);
        }
Example #4
0
        /// <summary>
        /// Override in a derived class to extened or modify the behavior of the service across an endpoint.
        /// </summary>
        /// <remarks>
        /// This base implementation sets up the proper operation dispatcher, formatter, and effor handler.
        /// Derived implementations shyould always call the base.
        /// </remarks>
        /// <param name="endpoint">The endpoint that exposes the contract.</param>
        /// <param name="endpointDispatcher">The endpoint dispatcher to be modified or extended.</param>
        protected virtual void OnApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
        {
            if (endpoint == null)
            {
                throw Fx.Exception.ArgumentNull("endpoint");
            }

            if (endpointDispatcher == null)
            {
                throw Fx.Exception.ArgumentNull("endpointDispatcher");
            }

            Uri helpUri = null;

            OperationDescription[] helpOperations = null;
            if (this.HelpEnabled)
            {
                helpUri        = new UriTemplate(HelpPage.OperationListHelpPageUriTemplate).BindByPosition(endpoint.ListenUri);
                helpOperations = HelpPage.AddHelpOperations(endpoint.Contract, endpointDispatcher.DispatchRuntime);
            }

            List <HttpOperationDescription> httpOperations = new List <HttpOperationDescription>();

            foreach (OperationDescription operationDescription in endpoint.Contract.Operations)
            {
                HttpOperationDescription httpOperationDescription = operationDescription.ToHttpOperationDescription();
                httpOperations.Add(httpOperationDescription);
            }

            // endpoint filter
            endpointDispatcher.AddressFilter  = new PrefixEndpointAddressMessageFilter(endpoint.Address);
            endpointDispatcher.ContractFilter = new MatchAllMessageFilter();

            // operation selector
            endpointDispatcher.DispatchRuntime.OperationSelector = this.OnGetOperationSelector(endpoint, httpOperations);
            UriAndMethodOperationSelector httpOperationSelector = endpointDispatcher.DispatchRuntime.OperationSelector as UriAndMethodOperationSelector;

            if (httpOperationSelector != null)
            {
                httpOperationSelector.HelpPageUri = helpUri;
            }

            // unhandled operation
            string actionStarOperationName = null;

            foreach (OperationDescription operation in endpoint.Contract.Operations)
            {
                if (operation.Messages[0].Direction == MessageDirection.Input &&
                    operation.Messages[0].Action == WildcardAction)
                {
                    actionStarOperationName = operation.Name;
                    break;
                }
            }

            if (actionStarOperationName != null)
            {
                endpointDispatcher.DispatchRuntime.Operations.Add(
                    endpointDispatcher.DispatchRuntime.UnhandledDispatchOperation);
            }

            // message formatter
            foreach (HttpOperationDescription httpOperationDescription in httpOperations)
            {
                DispatchOperation dispatchOperation = null;
                if (endpointDispatcher.DispatchRuntime.Operations.Contains(httpOperationDescription.Name))
                {
                    dispatchOperation = endpointDispatcher.DispatchRuntime.Operations[httpOperationDescription.Name];
                }
                else if (endpointDispatcher.DispatchRuntime.UnhandledDispatchOperation.Name == httpOperationDescription.Name)
                {
                    dispatchOperation = endpointDispatcher.DispatchRuntime.UnhandledDispatchOperation;
                }

                if (dispatchOperation != null)
                {
                    dispatchOperation.Formatter          = this.OnGetMessageFormatter(endpoint, httpOperationDescription);
                    dispatchOperation.DeserializeRequest = true;
                    dispatchOperation.SerializeReply     = !dispatchOperation.IsOneWay;
                }

                //FIX: GB - IQueryable
                if (httpOperationDescription.ReturnValue != null)
                {
                    var returnType = httpOperationDescription.ReturnValue.Type;
                    if (returnType.IsGenericType && returnType.GetGenericTypeDefinition() == typeof(IQueryable <>))
                    {
                        httpOperationDescription.Behaviors.Add(new QueryCompositionAttribute());
                    }
                }
            }

            // add any user error handlers
            IEnumerable <HttpErrorHandler> errorHandlers = this.OnGetHttpErrorHandlers(endpoint, httpOperations);

            if (errorHandlers != null)
            {
                foreach (HttpErrorHandler errorHandler in errorHandlers)
                {
                    endpointDispatcher.ChannelDispatcher.ErrorHandlers.Add(errorHandler);
                }
            }

            // add the default error handler
            HttpErrorHandler defaultErrorHandler = new HttpResponseErrorHandler(
                this.OperationHandlerFactory.Formatters,
                helpUri,
                endpointDispatcher.DispatchRuntime.ChannelDispatcher.IncludeExceptionDetailInFaults);

            endpointDispatcher.ChannelDispatcher.ErrorHandlers.Add(defaultErrorHandler);

            // remove the help operations from the contract if they were added
            if (helpOperations != null)
            {
                foreach (OperationDescription helpOperation in helpOperations)
                {
                    if (endpoint.Contract.Operations.Contains(helpOperation))
                    {
                        endpoint.Contract.Operations.Remove(helpOperation);
                    }
                }
            }
        }