public void Match_ReturnsFalse_IfODataPathCannotBeParsed()
        {
            var values = new Dictionary<string, object>() { { "odataPath", "NotAnODataPath" } };

            var constraint = new ODataPathRouteConstraint(_pathHandler, _model, _routeName, _conventions);
            Assert.False(constraint.Match(_request, null, null, values, HttpRouteDirection.UriResolution));
        }
        public void Match_ReturnsTrue_ForUriGeneration()
        {            
            var values = new Dictionary<string, object>();

            var constraint = new ODataPathRouteConstraint(_pathHandler, _model, _routeName, _conventions);
            Assert.True(constraint.Match(_request, null, null, values, HttpRouteDirection.UriGeneration));
        }
        public void Match_ReturnsTrue_IfODataPathCanBeParsed()
        {
            var values = new Dictionary<string, object>() { { "odataPath", "$metadata" } };

            var constraint = new ODataPathRouteConstraint(_pathHandler, _model, _routeName, _conventions);
            Assert.True(constraint.Match(_request, null, null, values, HttpRouteDirection.UriResolution));

            Assert.Equal("ODataMetadata", values["controller"]);
            Assert.Same(_model, _request.GetEdmModel());
            Assert.Same(_routeName, _request.GetODataRouteName());
            Assert.Equal(_conventions, _request.GetODataRoutingConventions());
            Assert.Same(_pathHandler, _request.GetODataPathHandler());
        }
        /// <summary>
        /// Maps the specified OData route.
        /// </summary>
        /// <param name="routes">A collection of routes for the application.</param>
        /// <param name="routeName">The name of the route to map.</param>
        /// <param name="routePrefix">The prefix to add to the OData route's path template.</param>
        /// <param name="model">The EDM model to use for parsing OData paths.</param>
        /// <param name="pathHandler">The <see cref="IODataPathHandler"/> to use for parsing the OData path.</param>
        /// <param name="routingConventions">The OData routing conventions to use for controller and action selection.</param>
        public static void MapODataRoute(this HttpRouteCollection routes, string routeName, string routePrefix, IEdmModel model,
            IODataPathHandler pathHandler, IEnumerable<IODataRoutingConvention> routingConventions)
        {
            if (routes == null)
            {
                throw Error.ArgumentNull("routes");
            }

            string routeTemplate = String.IsNullOrEmpty(routePrefix) ?
                ODataRouteConstants.ODataPathTemplate :
                routePrefix + "/" + ODataRouteConstants.ODataPathTemplate;
            IHttpRouteConstraint routeConstraint = new ODataPathRouteConstraint(pathHandler, model, routeName, routingConventions);
            HttpRouteValueDictionary constraintDictionary = new HttpRouteValueDictionary() { { ODataRouteConstants.ConstraintName, routeConstraint } };
            routes.MapHttpRoute(routeName, routeTemplate, defaults: null, constraints: constraintDictionary);
        }
        public void Match_ThrowsHttpResponseException_IfPathParserThrowsODataException()
        {
            var values = new Dictionary<string, object>() { { "odataPath", "" } };
            _request.SetConfiguration(new HttpConfiguration() { IncludeErrorDetailPolicy = IncludeErrorDetailPolicy.Always });
            Mock<IODataPathHandler> pathHandler = new Mock<IODataPathHandler>();
            string exceptionMessage = "NOOODATA";
            pathHandler.Setup(handler => handler.Parse(_model, "")).Throws(new ODataException(exceptionMessage));
            var constraint = new ODataPathRouteConstraint(pathHandler.Object, _model, _routeName, _conventions);

            var ex = Assert.Throws<HttpResponseException>(
                () => constraint.Match(_request, null, null, values, HttpRouteDirection.UriResolution));

            Assert.Equal(HttpStatusCode.NotFound, ex.Response.StatusCode);
            HttpError error = ex.Response.Content.ReadAsAsync<HttpError>().Result;
            Assert.Equal("The OData path is invalid.", error.Message);
            Assert.Equal(exceptionMessage, error.ExceptionMessage);
        }
Beispiel #6
0
        /// <summary>
        /// Initializes a new instance of the <see cref="ODataRoute" /> class.
        /// </summary>
        /// <param name="routePrefix">The route prefix.</param>
        /// <param name="pathConstraint">The OData path constraint.</param>
        /// <param name="defaults">The default values for the route.</param>
        /// <param name="constraints">The route constraints.</param>
        /// <param name="dataTokens">The data tokens.</param>
        /// <param name="handler">The message handler for the route.</param>
        public ODataRoute(
            string routePrefix,
            ODataPathRouteConstraint pathConstraint,
            HttpRouteValueDictionary defaults,
            HttpRouteValueDictionary constraints,
            HttpRouteValueDictionary dataTokens,
            HttpMessageHandler handler)
            : base(GetRouteTemplate(routePrefix), defaults, constraints, dataTokens, handler)
        {
            RoutePrefix = routePrefix;

            // We can only use our fast-path for link generation if there are no open brackets in the route prefix
            // that need to be replaced. If there are, fall back to the slow path.
            _canGenerateDirectLink = routePrefix != null && RoutePrefix.IndexOf('{') == -1;

            if (pathConstraint != null)
            {
                Constraints.Add(ODataRouteConstants.ConstraintName, pathConstraint);
            }
        }
Beispiel #7
0
        /// <summary>
        /// Initializes a new instance of the <see cref="ODataRoute" /> class.
        /// </summary>
        /// <param name="routePrefix">The route prefix.</param>
        /// <param name="pathConstraint">The OData path constraint.</param>
        /// <param name="defaults">The default values for the route.</param>
        /// <param name="constraints">The route constraints.</param>
        /// <param name="dataTokens">The data tokens.</param>
        /// <param name="handler">The message handler for the route.</param>
        public ODataRoute(
            string routePrefix,
            ODataPathRouteConstraint pathConstraint,
            HttpRouteValueDictionary defaults,
            HttpRouteValueDictionary constraints,
            HttpRouteValueDictionary dataTokens,
            HttpMessageHandler handler)
            : base(GetRouteTemplate(routePrefix), defaults, constraints, dataTokens, handler)
        {
            RoutePrefix = routePrefix;

            // We can only use our fast-path for link generation if there are no open brackets in the route prefix
            // that need to be replaced. If there are, fall back to the slow path.
            _canGenerateDirectLink = routePrefix != null && RoutePrefix.IndexOf('{') == -1;

            if (pathConstraint != null)
            {
                Constraints.Add(ODataRouteConstants.ConstraintName, pathConstraint);
            }
        }
Beispiel #8
0
 /// <summary>
 /// Initializes a new instance of the <see cref="ODataRoute" /> class.
 /// </summary>
 /// <param name="routePrefix">The route prefix.</param>
 /// <param name="pathConstraint">The OData path constraint.</param>
 public ODataRoute(string routePrefix, ODataPathRouteConstraint pathConstraint)
     : this(routePrefix, pathConstraint, defaults : null, constraints : null, dataTokens : null, handler : null)
 {
 }
Beispiel #9
0
 /// <summary>
 /// Initializes a new instance of the <see cref="ODataRoute" /> class.
 /// </summary>
 /// <param name="routePrefix">The route prefix.</param>
 /// <param name="pathConstraint">The OData path constraint.</param>
 public ODataRoute(string routePrefix, ODataPathRouteConstraint pathConstraint)
     : this(routePrefix, pathConstraint, defaults: null, constraints: null, dataTokens: null, handler: null)
 {
 }
        public static void MapODataRoute(this HttpRouteCollection routes, string routeName, string routePrefix, IEdmModel model,
            IODataPathHandler pathHandler, IEnumerable<IODataRoutingConvention> routingConventions, ODataBatchHandler batchHandler)
        {
            if (routes == null)
            {
                throw Error.ArgumentNull("routes");
            }

            if (!String.IsNullOrEmpty(routePrefix))
            {
                int prefixLastIndex = routePrefix.Length - 1;
                if (routePrefix[prefixLastIndex] == '/')
                {
                    // Remove the last trailing slash if it has one.
                    routePrefix = routePrefix.Substring(0, routePrefix.Length - 1);
                }
            }

            if (batchHandler != null)
            {
                batchHandler.ODataRouteName = routeName;
                string batchTemplate = String.IsNullOrEmpty(routePrefix) ? ODataRouteConstants.Batch : routePrefix + '/' + ODataRouteConstants.Batch;
                routes.MapHttpBatchRoute(routeName + "Batch", batchTemplate, batchHandler);
            }

            ODataPathRouteConstraint routeConstraint = new ODataPathRouteConstraint(pathHandler, model, routeName, routingConventions);
            routes.Add(routeName, new ODataRoute(routePrefix, routeConstraint));
        }
        public static void MapODataRoute(this HttpRouteCollection routes, string routeName, string routePrefix, IEdmModel model,
            IODataPathHandler pathHandler, IEnumerable<IODataRoutingConvention> routingConventions, ODataBatchHandler batchHandler)
        {
            if (routes == null)
            {
                throw Error.ArgumentNull("routes");
            }

            if (!String.IsNullOrEmpty(routePrefix))
            {
                int routePrefixLastCharIndex = routePrefix.Length - 1;
                if (routePrefix[routePrefixLastCharIndex] != '/')
                {
                    // Add the last trailing slash if it doesn't have one.
                    routePrefix += "/";
                }
            }

            if (batchHandler != null)
            {
                batchHandler.ODataRouteName = routeName;
                routes.MapHttpBatchRoute(routeName + "Batch", routePrefix + ODataRouteConstants.Batch, batchHandler);
            }

            string routeTemplate = routePrefix + ODataRouteConstants.ODataPathTemplate;
            IHttpRouteConstraint routeConstraint = new ODataPathRouteConstraint(pathHandler, model, routeName, routingConventions);
            HttpRouteValueDictionary constraintDictionary = new HttpRouteValueDictionary() { { ODataRouteConstants.ConstraintName, routeConstraint } };
            routes.MapHttpRoute(routeName, routeTemplate, defaults: null, constraints: constraintDictionary);
        }
        /// <summary>
        /// Enables OData support by adding an OData route and enabling OData controller and action selection, querying, and formatter support for OData.
        /// </summary>
        /// <param name="configuration">The server configuration.</param>
        /// <param name="model">The EDM model to use for the service.</param>
        /// <param name="routePrefix">The prefix to add to the OData route's path template.</param>
        public static void EnableOData(this HttpConfiguration configuration, IEdmModel model, string routePrefix)
        {
            if (configuration == null)
            {
                throw Error.ArgumentNull("configuration");
            }

            if (model == null)
            {
                throw Error.ArgumentNull("model");
            }

            // Querying
            configuration.SetEdmModel(model);
            configuration.EnableQuerySupport();

            // Routing
            string routeTemplate = String.IsNullOrEmpty(routePrefix) ?
                ODataRouteConstants.ODataPathTemplate :
                routePrefix + "/" + ODataRouteConstants.ODataPathTemplate;
            IODataPathHandler pathHandler = configuration.GetODataPathHandler() ?? new DefaultODataPathHandler(model);
            IHttpRouteConstraint routeConstraint = new ODataPathRouteConstraint(pathHandler);
            configuration.Routes.MapHttpRoute(ODataRouteConstants.RouteName, routeTemplate, null, new HttpRouteValueDictionary() { { ODataRouteConstants.ConstraintName, routeConstraint } });

            IEnumerable<IODataRoutingConvention> routingConventions = configuration.GetODataRoutingConventions();
            IHttpControllerSelector controllerSelector = new ODataControllerSelector(routingConventions, configuration.Services.GetHttpControllerSelector());
            IHttpActionSelector actionSelector = new ODataActionSelector(routingConventions, configuration.Services.GetActionSelector());
            configuration.Services.Replace(typeof(IHttpControllerSelector), controllerSelector);
            configuration.Services.Replace(typeof(IHttpActionSelector), actionSelector);

            // Formatter
            configuration.Formatters.InsertRange(0, ODataMediaTypeFormatters.Create(model));
        }