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)); }
/// <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) : this(routePrefix, (IHttpRouteConstraint)pathConstraint, defaults, constraints, dataTokens, handler) { }
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("Metadata", values["controller"]); Assert.Same(_model, _request.ODataProperties().Model); Assert.Same(_routeName, _request.ODataProperties().RouteName); Assert.Equal(_conventions, _request.ODataProperties().RoutingConventions); Assert.Same(_pathHandler, _request.ODataProperties().PathHandler); }
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); }
public void Match_DeterminesExpectedServiceRoot_ForFunctionCallWithEscapedSeparator( string prefixString, string oDataString) { // Arrange var originalRoot = "http://any/" + prefixString; var expectedRoot = originalRoot; if (!String.IsNullOrEmpty(prefixString)) { originalRoot += "%2F"; // Escaped '/' } var oDataPath = String.Format("Unbound(p0='{0}')", oDataString); var request = new HttpRequestMessage(HttpMethod.Get, originalRoot + oDataPath); var httpRouteCollection = new HttpRouteCollection { { _routeName, new HttpRoute() }, }; request.SetConfiguration(new HttpConfiguration(httpRouteCollection)); var builder = new ODataModelBuilder(); builder.Function("Unbound").Returns <string>().Parameter <string>("p0"); var model = builder.GetEdmModel(); var pathHandler = new TestPathHandler(); var constraint = new ODataPathRouteConstraint(pathHandler, model, _routeName, _conventions); var values = new Dictionary <string, object> { { ODataRouteConstants.ODataPath, Uri.UnescapeDataString(oDataPath) }, }; // Act var matched = constraint.Match(request, null, null, values, HttpRouteDirection.UriResolution); // Assert Assert.True(matched); Assert.NotNull(pathHandler.ServiceRoot); Assert.Equal(expectedRoot, pathHandler.ServiceRoot); Assert.NotNull(pathHandler.ODataPath); Assert.Equal(oDataPath, pathHandler.ODataPath); }
/// <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; PathRouteConstraint = pathConstraint; // 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); } }
public void Match_ReturnsFalse_IfODataPathHasNotImplementedSegment() { // Arrange var request = new HttpRequestMessage(HttpMethod.Get, "http://any/Customers/$count"); HttpRouteCollection httpRouteCollection = new HttpRouteCollection(); httpRouteCollection.Add(_routeName, new HttpRoute()); request.SetConfiguration(new HttpConfiguration(httpRouteCollection)); var values = new Dictionary <string, object>() { { "odataPath", "Customers/$count" } }; ODataConventionModelBuilder builder = new ODataConventionModelBuilder(); builder.EntitySet <Customer>("Customers"); IEdmModel model = builder.GetEdmModel(); var constraint = new ODataPathRouteConstraint(_pathHandler, model, _routeName, _conventions); // Act & Assert Assert.False(constraint.Match(request, null, null, values, HttpRouteDirection.UriResolution)); }
public void Match_DeterminesExpectedServiceRoot_ForMetadataWithEscapedSeparator(string prefixString) { // Arrange var originalRoot = "http://any/" + prefixString; var expectedRoot = originalRoot; if (!String.IsNullOrEmpty(prefixString)) { originalRoot += "%2F"; // Escaped '/' } var request = new HttpRequestMessage(HttpMethod.Get, originalRoot + "$metadata"); var httpRouteCollection = new HttpRouteCollection { { _routeName, new HttpRoute() }, }; request.SetConfiguration(new HttpConfiguration(httpRouteCollection)); var pathHandler = new TestPathHandler(); var constraint = new ODataPathRouteConstraint(pathHandler, _model, _routeName, _conventions); var values = new Dictionary <string, object> { { ODataRouteConstants.ODataPath, "$metadata" }, }; // Act var matched = constraint.Match(request, null, null, values, HttpRouteDirection.UriResolution); // Assert Assert.True(matched); Assert.NotNull(pathHandler.ServiceRoot); Assert.Equal(expectedRoot, pathHandler.ServiceRoot); Assert.NotNull(pathHandler.ODataPath); Assert.Equal("$metadata", pathHandler.ODataPath); }
public void Match_ReturnsTrue_IfODataPathCanBeParsed() { // Arrange var request = new HttpRequestMessage(HttpMethod.Get, "http://any/odata/$metadata"); HttpRouteCollection httpRouteCollection = new HttpRouteCollection(); httpRouteCollection.Add(_routeName, new HttpRoute()); request.SetConfiguration(new HttpConfiguration(httpRouteCollection)); var values = new Dictionary <string, object>() { { "odataPath", "$metadata" } }; var constraint = new ODataPathRouteConstraint(_pathHandler, _model, _routeName, _conventions); // Act & Assert Assert.True(constraint.Match(request, null, null, values, HttpRouteDirection.UriResolution)); Assert.Equal("Metadata", values["controller"]); Assert.Same(_model, request.ODataProperties().Model); Assert.Same(_routeName, request.ODataProperties().RouteName); Assert.Equal(_conventions, request.ODataProperties().RoutingConventions); Assert.Same(_pathHandler, request.ODataProperties().PathHandler); }
/// <summary> /// Maps the specified OData route. When the <paramref name="defaultHandler"/> is non-<c>null</c>, it will map /// it as the handler for the route. /// </summary> /// <param name="configuration">The server configuration.</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> /// <param name="defaultHandler">The default <see cref="HttpMessageHandler"/> for this route.</param> /// <returns>The added <see cref="ODataRoute"/>.</returns> public static ODataRoute MapODataServiceRoute(this HttpConfiguration configuration, string routeName, string routePrefix, IEdmModel model, IODataPathHandler pathHandler, IEnumerable<IODataRoutingConvention> routingConventions, HttpMessageHandler defaultHandler) { if (configuration == null) { throw Error.ArgumentNull("configuration"); } // We have a more specific overload to map batch handlers that creates a different route for the batch // endpoint instead of mapping that handler as the per route handler. Given that HttpMessageHandler is a // base type of ODataBatchHandler, it's possible the compiler will call this overload instead of the one // for the batch handler, so we detect that case and call the appropiate overload for the user. // The case in which the compiler picks the wrong overload is: // HttpRequestMessageHandler batchHandler = new DefaultODataBatchHandler(httpServer); // config.Routes.MapODataServiceRoute("routeName", "routePrefix", model, batchHandler); if (defaultHandler != null) { ODataBatchHandler batchHandler = defaultHandler as ODataBatchHandler; if (batchHandler != null) { return MapODataServiceRoute(configuration, routeName, routePrefix, model, batchHandler); } } HttpRouteCollection routes = configuration.Routes; routePrefix = RemoveTrailingSlash(routePrefix); DefaultODataPathHandler odataPathHandler = pathHandler as DefaultODataPathHandler; if (odataPathHandler != null) { odataPathHandler.ResolverSetttings = configuration.GetResolverSettings(); } ODataPathRouteConstraint routeConstraint = new ODataPathRouteConstraint(pathHandler, model, routeName, routingConventions); ODataRoute route = new ODataRoute( routePrefix, routeConstraint, defaults: null, constraints: null, dataTokens: null, handler: defaultHandler); routes.Add(routeName, route); return route; }
public static ODataRoute MapODataServiceRoute(this HttpConfiguration configuration, string routeName, string routePrefix, IEdmModel model, IODataPathHandler pathHandler, IEnumerable<IODataRoutingConvention> routingConventions, ODataBatchHandler batchHandler) { if (configuration == null) { throw Error.ArgumentNull("configuration"); } HttpRouteCollection routes = configuration.Routes; routePrefix = RemoveTrailingSlash(routePrefix); if (batchHandler != null) { batchHandler.ODataRouteName = routeName; string batchTemplate = String.IsNullOrEmpty(routePrefix) ? ODataRouteConstants.Batch : routePrefix + '/' + ODataRouteConstants.Batch; routes.MapHttpBatchRoute(routeName + "Batch", batchTemplate, batchHandler); } DefaultODataPathHandler odataPathHandler = pathHandler as DefaultODataPathHandler; if (odataPathHandler != null) { odataPathHandler.ResolverSetttings = configuration.GetResolverSettings(); } ODataPathRouteConstraint routeConstraint = new ODataPathRouteConstraint(pathHandler, model, routeName, routingConventions); ODataRoute route = new ODataRoute(routePrefix, routeConstraint); routes.Add(routeName, route); return route; }
/// <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 void Match_ReturnsFalse_IfODataPathHasNotImplementedSegment() { // Arrange var request = new HttpRequestMessage(HttpMethod.Get, "http://any/Customers(1)/OpenProperty"); HttpRouteCollection httpRouteCollection = new HttpRouteCollection(); httpRouteCollection.Add(_routeName, new HttpRoute()); request.SetConfiguration(new HttpConfiguration(httpRouteCollection)); var model = new EdmModel(); var customer = new EdmEntityType( namespaceName: "NS", name: "Customer", baseType: null, isAbstract: false, isOpen: true); customer.AddKeys(customer.AddStructuralProperty("ID", EdmPrimitiveTypeKind.Int32)); model.AddElement(customer); var container = new EdmEntityContainer("NS", "Container"); container.AddEntitySet("Customers", customer); model.AddElement(container); var values = new Dictionary<string, object>() { { "odataPath", "Customers(1)/OpenProperty" } }; var constraint = new ODataPathRouteConstraint(_pathHandler, model, _routeName, _conventions); // Act & Assert Assert.False(constraint.Match(request, null, null, values, HttpRouteDirection.UriResolution)); }
public void Match_DeterminesExpectedServiceRoot_ForFunctionCallWithEscapedSeparator( string prefixString, string oDataString) { // Arrange var originalRoot = "http://any/" + prefixString; var expectedRoot = originalRoot; if (!String.IsNullOrEmpty(prefixString)) { originalRoot += "%2F"; // Escaped '/' } var oDataPath = String.Format("Unbound(p0='{0}')", oDataString); var request = new HttpRequestMessage(HttpMethod.Get, originalRoot + oDataPath); var httpRouteCollection = new HttpRouteCollection { { _routeName, new HttpRoute() }, }; request.SetConfiguration(new HttpConfiguration(httpRouteCollection)); var builder = new ODataModelBuilder(); builder.Function("Unbound").Returns<string>().Parameter<string>("p0"); var model = builder.GetEdmModel(); var pathHandler = new TestPathHandler(); var constraint = new ODataPathRouteConstraint(pathHandler, model, _routeName, _conventions); var values = new Dictionary<string, object> { { ODataRouteConstants.ODataPath, Uri.UnescapeDataString(oDataPath) }, }; // Act var matched = constraint.Match(request, null, null, values, HttpRouteDirection.UriResolution); // Assert Assert.True(matched); Assert.NotNull(pathHandler.ServiceRoot); Assert.Equal(expectedRoot, pathHandler.ServiceRoot); Assert.NotNull(pathHandler.ODataPath); Assert.Equal(oDataPath, pathHandler.ODataPath); }
public void Match_DeterminesExpectedServiceRoot_ForMetadataWithEscapedSeparator(string prefixString) { // Arrange var originalRoot = "http://any/" + prefixString; var expectedRoot = originalRoot; if (!String.IsNullOrEmpty(prefixString)) { originalRoot += "%2F"; // Escaped '/' } var request = new HttpRequestMessage(HttpMethod.Get, originalRoot + "$metadata"); var httpRouteCollection = new HttpRouteCollection { { _routeName, new HttpRoute() }, }; request.SetConfiguration(new HttpConfiguration(httpRouteCollection)); var pathHandler = new TestPathHandler(); var constraint = new ODataPathRouteConstraint(pathHandler, _model, _routeName, _conventions); var values = new Dictionary<string, object> { { ODataRouteConstants.ODataPath, "$metadata" }, }; // Act var matched = constraint.Match(request, null, null, values, HttpRouteDirection.UriResolution); // Assert Assert.True(matched); Assert.NotNull(pathHandler.ServiceRoot); Assert.Equal(expectedRoot, pathHandler.ServiceRoot); Assert.NotNull(pathHandler.ODataPath); Assert.Equal("$metadata", pathHandler.ODataPath); }
public void Match_ReturnsTrue_IfODataPathCanBeParsed() { // Arrange var request = new HttpRequestMessage(HttpMethod.Get, "http://any/odata/$metadata"); HttpRouteCollection httpRouteCollection = new HttpRouteCollection(); httpRouteCollection.Add(_routeName, new HttpRoute()); request.SetConfiguration(new HttpConfiguration(httpRouteCollection)); var values = new Dictionary<string, object>() { { "odataPath", "$metadata" } }; var constraint = new ODataPathRouteConstraint(_pathHandler, _model, _routeName, _conventions); // Act & Assert Assert.True(constraint.Match(request, null, null, values, HttpRouteDirection.UriResolution)); Assert.Equal("Metadata", values["controller"]); Assert.Same(_model, request.ODataProperties().Model); Assert.Same(_routeName, request.ODataProperties().RouteName); Assert.Equal(_conventions, request.ODataProperties().RoutingConventions); Assert.Same(_pathHandler, request.ODataProperties().PathHandler); }
public DynamicODataRoute(string routePrefix, ODataPathRouteConstraint pathConstraint) : base(routePrefix, pathConstraint) { _canGenerateDirectLink = routePrefix != null && RoutePrefix.IndexOf('{') == -1; }
public void Match_ReturnsFalse_IfODataPathHasNotImplementedSegment() { // Arrange var request = new HttpRequestMessage(HttpMethod.Get, "http://any/Customers/$count"); HttpRouteCollection httpRouteCollection = new HttpRouteCollection(); httpRouteCollection.Add(_routeName, new HttpRoute()); request.SetConfiguration(new HttpConfiguration(httpRouteCollection)); var values = new Dictionary<string, object>() { { "odataPath", "Customers/$count" } }; ODataConventionModelBuilder builder = new ODataConventionModelBuilder(); builder.EntitySet<Customer>("Customers"); IEdmModel model = builder.GetEdmModel(); var constraint = new ODataPathRouteConstraint(_pathHandler, model, _routeName, _conventions); // Act & Assert Assert.False(constraint.Match(request, null, null, values, HttpRouteDirection.UriResolution)); }
public static ODataRoute MapODataServiceRoute(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); ODataRoute route = new ODataRoute(routePrefix, routeConstraint); routes.Add(routeName, route); return route; }
/// <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 void Match_ReturnsFalse_IfODataPathCannotBeParsed() { // Arrange var request = new HttpRequestMessage(HttpMethod.Get, "http://any/NotAnODataPath"); HttpRouteCollection httpRouteCollection = new HttpRouteCollection(); httpRouteCollection.Add(_routeName, new HttpRoute()); request.SetConfiguration(new HttpConfiguration(httpRouteCollection)); var values = new Dictionary<string, object>() { { "odataPath", "NotAnODataPath" } }; var constraint = new ODataPathRouteConstraint(_pathHandler, _model, _routeName, _conventions); // Act & Assert Assert.False(constraint.Match(request, null, null, values, HttpRouteDirection.UriResolution)); }