private static ODataQueryOptions GetQueryOptions(string queryOption) { string uri = "Http://localhost/RoutingCustomers?" + queryOption; HttpConfiguration configuration = new HttpConfiguration(); ODataUriResolver resolver = new ODataUriResolver { EnableCaseInsensitive = true }; HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, uri); request.SetConfiguration(configuration); request.EnableHttpDependencyInjectionSupport(b => b.AddService(ServiceLifetime.Singleton, sp => resolver)); IEdmModel model = ODataRoutingModel.GetModel(); IEdmEntitySet entityset = model.EntityContainer.FindEntitySet("RoutingCustomers"); IEdmEntityType entityType = model.SchemaElements.OfType <IEdmEntityType>().Single(e => e.Name == "RoutingCustomer"); ODataPath path = new ODataPath(new[] { new EntitySetSegment(entityset) }); ODataQueryContext context = new ODataQueryContext(model, entityType, path); return(new ODataQueryOptions(context, request)); }
public void GetETagTEntity_Returns_ETagInHeader() { // Arrange HttpRequestMessage request = new HttpRequestMessage(); HttpConfiguration cofiguration = new HttpConfiguration(); request.SetConfiguration(cofiguration); Dictionary <string, object> properties = new Dictionary <string, object> { { "City", "Foo" } }; EntityTagHeaderValue etagHeaderValue = new DefaultODataETagHandler().CreateETag(properties); CustomersModelWithInheritance model = new CustomersModelWithInheritance(); Mock <ODataPathSegment> mockSegment = new Mock <ODataPathSegment> { CallBase = true }; mockSegment.Setup(s => s.GetEdmType(null)).Returns(model.Customer); mockSegment.Setup(s => s.GetNavigationSource(null)).Returns((IEdmNavigationSource)model.Customers); ODataPath odataPath = new ODataPath(new[] { mockSegment.Object }); request.ODataProperties().Path = odataPath; request.ODataProperties().Model = model.Model; // Act ETag <Customer> result = request.GetETag <Customer>(etagHeaderValue); dynamic dynamicResult = result; // Assert Assert.Equal("Foo", result["City"]); Assert.Equal("Foo", dynamicResult.City); }
public void Property_EntityIdHeader_IsEvaluatedLazilyAndOnlyOnce() { // Arrange Uri idLink = new Uri("http://id-link"); Mock <NavigationSourceLinkBuilderAnnotation> linkBuilder = new Mock <NavigationSourceLinkBuilderAnnotation>(); linkBuilder.CallBase = true; linkBuilder.Setup(b => b.BuildIdLink(It.IsAny <ResourceContext>(), ODataMetadataLevel.FullMetadata)) .Returns(idLink); CustomersModelWithInheritance model = new CustomersModelWithInheritance(); model.Model.SetAnnotationValue(model.Customer, new ClrTypeAnnotation(typeof(TestEntity))); model.Model.SetNavigationSourceLinkBuilder(model.Customers, linkBuilder.Object); ODataPath path = new ODataPath(new EntitySetSegment(model.Customers)); HttpRequestMessage request = new HttpRequestMessage(); request.ODataProperties().Path = path; request.EnableHttpDependencyInjectionSupport(model.Model); TestController controller = new TestController { Configuration = request.GetConfiguration() }; CreatedODataResult <TestEntity> createdODataResult = new CreatedODataResult <TestEntity>(_entity, controller); // Act controller.Request = request; Uri entityIdHeader = createdODataResult.EntityId; // Assert Assert.Same(idLink, entityIdHeader); linkBuilder.Verify( b => b.BuildIdLink(It.IsAny <ResourceContext>(), ODataMetadataLevel.FullMetadata), Times.Once()); }
public ODataDeltaFeedSerializerTests() { _model = SerializationTestsHelpers.SimpleCustomerOrderModel(); _customerSet = _model.EntityContainer.FindEntitySet("Customers"); _model.SetAnnotationValue(_customerSet.EntityType(), new ClrTypeAnnotation(typeof(Customer))); _path = new ODataPath(new EntitySetPathSegment(_customerSet)); _customers = new[] { new Customer() { FirstName = "Foo", LastName = "Bar", ID = 10, }, new Customer() { FirstName = "Foo", LastName = "Bar", ID = 42, } }; _deltaFeedCustomers = new EdmChangedObjectCollection(_customerSet.EntityType()); EdmDeltaEntityObject newCustomer = new EdmDeltaEntityObject(_customerSet.EntityType()); newCustomer.TrySetPropertyValue("ID", 10); newCustomer.TrySetPropertyValue("FirstName", "Foo"); _deltaFeedCustomers.Add(newCustomer); _customersType = _model.GetEdmTypeReference(typeof(Customer[])).AsCollection(); _writeContext = new ODataSerializerContext() { NavigationSource = _customerSet, Model = _model, Path = _path }; }
/// <summary> /// Selects the appropriate action based on the parsed OData URI. /// </summary> /// <param name="odataPath">Parsed OData URI</param> /// <param name="controllerContext">Context for HttpController</param> /// <param name="actionMap">Mapping from action names to HttpActions</param> /// <returns>String corresponding to controller action name</returns> public string SelectAction( ODataPath odataPath, HttpControllerContext controllerContext, ILookup<string, HttpActionDescriptor> actionMap) { // TODO GitHubIssue#44 : implement action selection for $ref, navigation scenarios, etc. Ensure.NotNull(odataPath, "odataPath"); Ensure.NotNull(controllerContext, "controllerContext"); Ensure.NotNull(actionMap, "actionMap"); if (!(controllerContext.Controller is RestierController)) { // RESTier cannot select action on controller which is not RestierController. return null; } HttpMethod method = controllerContext.Request.Method; if (method == HttpMethod.Get && !IsMetadataPath(odataPath)) { return MethodNameOfGet; } ODataPathSegment lastSegment = odataPath.Segments.LastOrDefault(); if (lastSegment != null && lastSegment.SegmentKind == ODataSegmentKinds.UnboundAction) { return MethodNameOfPostAction; } // Let WebAPI select default action return null; }
public override string SelectAction(ODataPath odataPath, HttpControllerContext controllerContext, ILookup<string, HttpActionDescriptor> actionMap) { var action = base.SelectAction(odataPath, controllerContext, actionMap); if (action != null) { var routeValues = controllerContext.RouteData.Values; if (routeValues.ContainsKey(ODataRouteConstants.Key)) { var keyRaw = routeValues[ODataRouteConstants.Key] as string; IEnumerable<string> compoundKeyPairs = keyRaw.Split(','); if (compoundKeyPairs == null || !compoundKeyPairs.Any()) { return action; } foreach (var compoundKeyPair in compoundKeyPairs) { string[] pair = compoundKeyPair.Split('='); if (pair == null || pair.Length != 2) { continue; } var keyName = pair[0].Trim(); var keyValue = pair[1].Trim(); routeValues.Add(keyName, keyValue); } } } return action; }
public string SelectAction( ODataPath odataPath, HttpControllerContext controllerContext, ILookup<string, HttpActionDescriptor> actionMap) { return null; }
public override string SelectAction(ODataPath odataPath, HttpControllerContext controllerContext, ILookup <string, HttpActionDescriptor> actionMap) { if (odataPath == null) { throw new ArgumentNullException("odataPath"); } if (controllerContext == null) { throw new ArgumentNullException("controllerContext"); } if (actionMap == null) { throw new ArgumentNullException("actionMap"); } HttpMethod requestMethod = controllerContext.Request.Method; if (odataPath.PathTemplate == "~/entityset/key/navigation/$ref" && requestMethod == HttpMethod.Get) { KeySegment keyValueSegment = odataPath.Segments[1] as KeySegment; controllerContext.AddKeyValueToRouteData(keyValueSegment); NavigationPropertyLinkSegment navigationLinkSegment = odataPath.Segments[2] as NavigationPropertyLinkSegment; IEdmNavigationProperty navigationProperty = navigationLinkSegment.NavigationProperty; IEdmEntityType declaredType = navigationProperty.DeclaringType as IEdmEntityType; string action = requestMethod + "LinksFor" + navigationProperty.Name + "From" + declaredType.Name; return(actionMap.Contains(action) ? action : requestMethod + "LinksFor" + navigationProperty.Name); } return(base.SelectAction(odataPath, controllerContext, actionMap)); }
public void GenerateLocationHeader_UsesEntitySetLinkBuilder_ToGenerateLocationHeader() { // Arrange Uri editLink = new Uri("http://id-link"); Mock <NavigationSourceLinkBuilderAnnotation> linkBuilder = new Mock <NavigationSourceLinkBuilderAnnotation>(); linkBuilder.CallBase = true; linkBuilder.Setup( b => b.BuildEditLink(It.IsAny <ResourceContext>(), ODataMetadataLevel.FullMetadata, null)) .Returns(editLink); CustomersModelWithInheritance model = new CustomersModelWithInheritance(); model.Model.SetAnnotationValue(model.Customer, new ClrTypeAnnotation(typeof(TestEntity))); model.Model.SetNavigationSourceLinkBuilder(model.Customers, linkBuilder.Object); ODataPath path = new ODataPath(new EntitySetSegment(model.Customers)); HttpRequestMessage request = new HttpRequestMessage(); request.ODataProperties().Path = path; request.EnableHttpDependencyInjectionSupport(model.Model); CreatedODataResult <TestEntity> createdODataResult = GetCreatedODataResult(request); // Act var locationHeader = createdODataResult.GenerateLocationHeader(); // Assert Assert.Same(editLink, locationHeader); }
public override string SelectAction(ODataPath odataPath, HttpControllerContext controllerContext, ILookup<string, HttpActionDescriptor> actionMap) { var controllerType = controllerContext.ControllerDescriptor.ControllerType; if (typeof(CustomersController) == controllerType) { if (odataPath.PathTemplate.Equals("~/entityset/key/navigation")) //POST OR GET { controllerContext.RouteData.Values["orderID"] = (odataPath.Segments[1] as KeyValuePathSegment).Value; return controllerContext.Request.Method.ToString(); } } else if (typeof(OrdersController) == controllerType) { if (odataPath.PathTemplate.Equals("~/entityset/key/navigation")) //POST OR GET { controllerContext.RouteData.Values["customerID"] = (odataPath.Segments[1] as KeyValuePathSegment).Value; return controllerContext.Request.Method.ToString(); } if (odataPath.PathTemplate.Equals("~/entityset/key/navigation/key")) //PATCH OR DELETE { controllerContext.RouteData.Values["customerID"] = (odataPath.Segments[1] as KeyValuePathSegment).Value; controllerContext.RouteData.Values["key"] = (odataPath.Segments[3] as KeyValuePathSegment).Value; return controllerContext.Request.Method.ToString(); } } return base.SelectAction(odataPath, controllerContext, actionMap); }
public override string SelectAction(ODataPath odataPath, HttpControllerContext controllerContext, ILookup <string, HttpActionDescriptor> actionMap) { HttpMethod httpMethod = controllerContext.Request.Method; if (httpMethod != HttpMethod.Get) { return(null); } if (odataPath.PathTemplate == "~/entityset/key/navigation/key") { KeySegment segment = (KeySegment)odataPath.Segments[1]; // object value = ODataUriUtils.ConvertFromUriLiteral(segment.Keys, ODataVersion.V4); object value = segment.Keys.First().Value; // I don't check the keys number. controllerContext.RouteData.Values.Add("key", value); segment = (KeySegment)odataPath.Segments[3]; // value = ODataUriUtils.ConvertFromUriLiteral(segment.Value, ODataVersion.V4); value = segment.Keys.First().Value; controllerContext.RouteData.Values.Add("relatedKey", value); NavigationPropertySegment property = odataPath.Segments[2] as NavigationPropertySegment; // controllerContext.RouteData.Values.Add("propertyName", property.NavigationProperty.Name); return("Get" + property.NavigationProperty.Name); } return(null); }
/// <summary> /// Handles a GET request to query entities. /// </summary> /// <param name="cancellationToken">The cancellation token.</param> /// <returns>The task object that contains the response message.</returns> public async Task <HttpResponseMessage> Get( CancellationToken cancellationToken) { ODataPath path = this.GetPath(); ODataPathSegment lastSegment = path.Segments.LastOrDefault(); if (lastSegment == null) { throw new InvalidOperationException(Resources.ControllerRequiresPath); } IQueryable result = null; // Get queryable path builder to builder IQueryable queryable = this.GetQuery(path); ETag etag; // TODO #365 Do not support additional path segment after function call now if (lastSegment is OperationImportSegment) { var unboundSegment = (OperationImportSegment)lastSegment; var operation = unboundSegment.OperationImports.FirstOrDefault(); Func <string, object> getParaValueFunc = p => unboundSegment.GetParameterValue(p); result = await ExecuteOperationAsync( getParaValueFunc, operation.Name, true, null, cancellationToken); result = ApplyQueryOptions(result, path, true, out etag); } else { if (queryable == null) { throw new HttpResponseException( this.Request.CreateErrorResponse( HttpStatusCode.NotFound, Resources.ResourceNotFound)); } if (lastSegment is OperationSegment) { result = await ExecuteQuery(queryable, cancellationToken); var boundSeg = (OperationSegment)lastSegment; var operation = boundSeg.Operations.FirstOrDefault(); Func <string, object> getParaValueFunc = p => boundSeg.GetParameterValue(p); result = await ExecuteOperationAsync( getParaValueFunc, operation.Name, true, result, cancellationToken); result = ApplyQueryOptions(result, path, true, out etag); } else { queryable = ApplyQueryOptions(queryable, path, false, out etag); result = await ExecuteQuery(queryable, cancellationToken); } } return(this.CreateQueryResponse(result, path.EdmType, etag)); }
public void PathTemplateWithOneUnboundFunctionPathSegment() { // Arrange ODataPath path = new ODataPath(new UnboundFunctionPathSegment("TopFunction", null)); // Act & Assert Assert.Equal("~/unboundfunction", path.PathTemplate); }
private static IEdmNavigationProperty GetNavigationProperty(ODataPath path) { if (path == null) { throw new SerializationException(SRResources.ODataPathMissing); } return path.GetNavigationProperty(); }
public string SelectAction(ODataPath odataPath, HttpControllerContext controllerContext, ILookup<string, HttpActionDescriptor> actionMap) { if (odataPath != null && odataPath.PathTemplate == "~/$swagger") { return "GetSwagger"; } return null; }
public string SelectController(ODataPath odataPath, HttpRequestMessage request) { if (odataPath != null && odataPath.PathTemplate == "~/$swagger") { return "Swagger"; } return null; }
/// <summary> /// Converts an instance of <see cref="ODataPath" /> into an OData link. /// </summary> /// <param name="path">The OData path to convert into a link.</param> /// <returns> /// The generated OData link. /// </returns> public virtual string Link(ODataPath path) { if (path == null) { throw Error.ArgumentNull("path"); } return path.ToString(); }
/// <summary> /// Returns the controller names with the version suffix. /// For example: request from route V1 can be dispatched to ProductsV1Controller. /// </summary> public string SelectController(ODataPath odataPath, HttpRequestMessage request) { var baseControllerName = _innerRoutingConvention.SelectController(odataPath, request); if (baseControllerName != null) { return string.Concat(baseControllerName, _versionSuffix); } return null; }
public override string SelectAction(ODataPath odataPath, HttpControllerContext controllerContext, ILookup<string, HttpActionDescriptor> actionMap) { string result = base.SelectAction(odataPath, controllerContext, actionMap); IDictionary<string, object> conventionStore = controllerContext.Request.ODataProperties().RoutingConventionsStore; if (result != null && conventionStore != null) { conventionStore["keyAsCustomer"] = new BindCustomer { Id = (int)controllerContext.RouteData.Values["key"] }; } return result; }
/// <summary> /// Selects OData controller based on parsed OData URI /// </summary> /// <param name="odataPath">Parsed OData URI</param> /// <param name="request">Incoming HttpRequest</param> /// <returns>Prefix for controller name</returns> public string SelectController(ODataPath odataPath, HttpRequestMessage request) { string result = null; if (IsMediadataPath(odataPath)) { result = "Restier"; } return result; }
private IQueryable GetQuery(ODataPath path) { RestierQueryBuilder builder = new RestierQueryBuilder(this.Api, path); IQueryable queryable = builder.BuildQuery(); this.shouldReturnCount = builder.IsCountPathSegmentPresent; this.shouldWriteRawValue = builder.IsValuePathSegmentPresent; return(queryable); }
/// <summary> /// Returns the controller names with the version suffix. /// For example: request from route V1 can be dispatched to ProductsV1Controller. /// </summary> public string SelectController(System.Web.OData.Routing.ODataPath odataPath, System.Net.Http.HttpRequestMessage request) { var baseControllerName = _entitySetRoutingConvention.SelectController(odataPath, request); if (baseControllerName != null) { return(string.Concat(baseControllerName, _versionSuffix)); } return(null); }
private static void AddLinkInfoToRouteData(IHttpRouteData routeData, ODataPath odataPath) { KeyValuePathSegment keyValueSegment = odataPath.Segments.OfType<KeyValuePathSegment>().First(); routeData.Values[ODataRouteConstants.Key] = keyValueSegment.Value; KeyValuePathSegment relatedKeySegment = odataPath.Segments.Last() as KeyValuePathSegment; if (relatedKeySegment != null) { routeData.Values[ODataRouteConstants.RelatedKey] = relatedKeySegment.Value; } }
public override string SelectAction(ODataPath odataPath, HttpControllerContext controllerContext, ILookup<string, HttpActionDescriptor> actionMap) { if (odataPath == null) { throw new ArgumentNullException("odataPath"); } if (controllerContext == null) { throw new ArgumentNullException("controllerContext"); } if (actionMap == null) { throw new ArgumentNullException("actionMap"); } HttpMethod requestMethod = controllerContext.Request.Method; if (odataPath.PathTemplate == "~/entityset/key/navigation/$ref" || odataPath.PathTemplate == "~/entityset/key/cast/navigation/$ref" || odataPath.PathTemplate == "~/entityset/key/navigation/key/$ref" || odataPath.PathTemplate == "~/entityset/key/cast/navigation/key/$ref") { var actionName = string.Empty; if ((requestMethod == HttpMethod.Post) || (requestMethod == HttpMethod.Put)) { actionName += "CreateRefTo"; } else if (requestMethod == HttpMethod.Delete) { actionName += "DeleteRefTo"; } else { return null; } var navigationSegment = odataPath.Segments.OfType<NavigationPathSegment>().Last(); actionName += navigationSegment.NavigationPropertyName; var castSegment = odataPath.Segments[2] as CastPathSegment; if (castSegment != null) { var actionCastName = string.Format("{0}On{1}", actionName, castSegment.CastType.Name); if (actionMap.Contains(actionCastName)) { AddLinkInfoToRouteData(controllerContext.RouteData, odataPath); return actionCastName; } } if (actionMap.Contains(actionName)) { AddLinkInfoToRouteData(controllerContext.RouteData, odataPath); return actionName; } } return null; }
public void ToStringWithNoSegments() { // Arrange ODataPath path = new ODataPath(); // Act string value = path.ToString(); // Assert Assert.Empty(value); }
public void WriteObject_Throws_ObjectCannotBeWritten_IfGraphIsNotUri() { IEdmNavigationProperty navigationProperty = _customerSet.ElementType.NavigationProperties().First(); ODataEntityReferenceLinksSerializer serializer = new ODataEntityReferenceLinksSerializer(); ODataPath path = new ODataPath(new NavigationPathSegment(navigationProperty)); ODataSerializerContext writeContext = new ODataSerializerContext { EntitySet = _customerSet, Path = path }; Assert.Throws<SerializationException>( () => serializer.WriteObject(graph: "not uri", type: typeof(ODataEntityReferenceLinks), messageWriter: ODataTestUtil.GetMockODataMessageWriter(), writeContext: writeContext), "ODataEntityReferenceLinksSerializer cannot write an object of type 'System.String'."); }
public void ToStringWithOneSegment() { // Arrange string expectedValue = "Set"; ODataPath path = new ODataPath(new EntitySetPathSegment(expectedValue)); // Act string value = path.ToString(); // Assert Assert.Equal(expectedValue, value); }
public override string SelectController(ODataPath odataPath, HttpRequestMessage request) { // We use always use the last naviation as the controller vs. the initial entityset if (odataPath.PathTemplate.Contains("~/entityset/key/navigation")) { // Find controller. Controller should be last navigation property return ODataSegmentKinds.Navigation == odataPath.Segments[odataPath.Segments.Count - 1].SegmentKind ? odataPath.Segments[odataPath.Segments.Count - 1].ToString() : odataPath.Segments[odataPath.Segments.Count - 2].ToString(); } return base.SelectController(odataPath, request); }
public void GetETag_Returns_ETagInHeader_ForInteger(byte byteValue, short shortValue, long longValue) { // Arrange Dictionary <string, object> properties = new Dictionary <string, object> { { "ByteVal", byteValue }, { "LongVal", longValue }, { "ShortVal", shortValue } }; EntityTagHeaderValue etagHeaderValue = new DefaultODataETagHandler().CreateETag(properties); var builder = new ODataConventionModelBuilder(); builder.EntitySet <MyEtagOrder>("Orders"); IEdmModel model = builder.GetEdmModel(); IEdmEntityType order = model.SchemaElements.OfType <IEdmEntityType>().FirstOrDefault(e => e.Name == "MyEtagOrder"); IEdmEntitySet orders = model.FindDeclaredEntitySet("Orders"); Mock <ODataPathSegment> mockSegment = new Mock <ODataPathSegment> { CallBase = true }; mockSegment.Setup(s => s.GetEdmType(null)).Returns(order); mockSegment.Setup(s => s.GetNavigationSource(null)).Returns(orders); ODataPath odataPath = new ODataPath(new[] { mockSegment.Object }); HttpRequestMessage request = new HttpRequestMessage(); HttpConfiguration cofiguration = new HttpConfiguration(); request.SetConfiguration(cofiguration); request.ODataProperties().Path = odataPath; request.ODataProperties().Model = model; // Act ETag result = request.GetETag(etagHeaderValue); dynamic dynamicResult = result; // Assert byte actualByte = Assert.IsType <byte>(result["ByteVal"]); Assert.Equal(actualByte, dynamicResult.ByteVal); Assert.Equal(byteValue, actualByte); short actualShort = Assert.IsType <short>(result["ShortVal"]); Assert.Equal(actualShort, dynamicResult.ShortVal); Assert.Equal(shortValue, actualShort); long actualLong = Assert.IsType <long>(result["LongVal"]); Assert.Equal(actualLong, dynamicResult.LongVal); Assert.Equal(longValue, actualLong); }
public void ToStringWithKeyValueSegment() { // Arrange string segment = "1"; ODataPath path = new ODataPath(new KeyValuePathSegment(segment)); // Act string value = path.ToString(); // Assert string expectedValue = "(" + segment + ")"; Assert.Equal(expectedValue, value); }
public IHttpActionResult HandleUnmappedRequest(ODataPath path) { var functionSegment = path.Segments.ElementAt(1) as OperationSegment; if (functionSegment != null) { return(Ok(functionSegment.GetParameterValue("productName") as string)); } else { return(BadRequest()); } }
private static IEnumerable <KeyValuePair <string, object> > GetKeys(DefaultODataPathHandler pathHandler, string serviceRoot, Uri uri, IServiceProvider requestContainer) { ODataPath odataPath = pathHandler.Parse(serviceRoot, uri.ToString(), requestContainer); KeySegment segment = odataPath.Segments.OfType <KeySegment>().Last(); if (segment == null) { throw Error.InvalidOperation(SRResources.EntityReferenceMustHasKeySegment, uri); } return(segment.Keys); }
public override string SelectAction(ODataPath odataPath, HttpControllerContext controllerContext, ILookup <string, HttpActionDescriptor> actionMap) { string pathTemplate = odataPath.PathTemplate; if (controllerContext.Request.Method == HttpMethod.Get && pathTemplate.EndsWith("/dynamicproperty/$value")) { ODataPath newPath = new ODataPath(odataPath.Segments.TakeWhile(e => !(e is ValueSegment))); return(base.SelectAction(newPath, controllerContext, actionMap)); } return(null); }
public void TryMatchMediaType_WithNonRawvalueRequest_DoesntMatchRequest() { IEdmModel model = ODataTestUtil.GetEdmModel(); PropertyAccessPathSegment propertySegment = new PropertyAccessPathSegment((model.GetEdmType(typeof(FormatterPerson)) as IEdmEntityType).FindProperty("Age")); ODataPath path = new ODataPath(new EntitySetPathSegment("People"), new KeyValuePathSegment("1"), propertySegment); ODataPrimitiveValueMediaTypeMapping mapping = new ODataPrimitiveValueMediaTypeMapping(); HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, "http://localhost/People(1)/Age/"); request.ODataProperties().Model = model; request.ODataProperties().Path = path; double mapResult = mapping.TryMatchMediaType(request); Assert.Equal(0, mapResult); }
public override string SelectAction(System.Web.OData.Routing.ODataPath odataPath, HttpControllerContext context, ILookup <string, HttpActionDescriptor> actionMap) { if (context.Request.Method == HttpMethod.Delete && odataPath.PathTemplate == "~/entityset") { string actionName = "Delete"; if (actionMap.Contains(actionName)) { return(actionName); } } return(null); }
public void GenerateLocationHeader_ThrowsEntitySetMissingDuringSerialization_IfODataPathEntitySetIsNull() { // Arrange ODataPath path = new ODataPath(); HttpRequestMessage request = new HttpRequestMessage(); request.ODataProperties().Path = path; request.EnableHttpDependencyInjectionSupport(EdmCoreModel.Instance); CreatedODataResult <TestEntity> createdODataResult = GetCreatedODataResult(request); // Act & Assert Assert.Throws <InvalidOperationException>(() => createdODataResult.GenerateLocationHeader(), "The related entity set or singleton cannot be found from the OData path. The related entity set or singleton is required to serialize the payload."); }
public void GetETag_Returns_ETagInHeader_ForDouble(double value, bool isEqual) { // Arrange Dictionary <string, object> properties = new Dictionary <string, object> { { "Version", value } }; EntityTagHeaderValue etagHeaderValue = new DefaultODataETagHandler().CreateETag(properties); var builder = new ODataConventionModelBuilder(); builder.EntitySet <MyEtagCustomer>("Customers"); IEdmModel model = builder.GetEdmModel(); IEdmEntityType customer = model.SchemaElements.OfType <IEdmEntityType>().FirstOrDefault(e => e.Name == "MyEtagCustomer"); IEdmEntitySet customers = model.FindDeclaredEntitySet("Customers"); Mock <ODataPathSegment> mockSegment = new Mock <ODataPathSegment> { CallBase = true }; mockSegment.Setup(s => s.GetEdmType(null)).Returns(customer); mockSegment.Setup(s => s.GetNavigationSource(null)).Returns(customers); ODataPath odataPath = new ODataPath(new[] { mockSegment.Object }); HttpRequestMessage request = new HttpRequestMessage(); HttpConfiguration cofiguration = new HttpConfiguration(); request.SetConfiguration(cofiguration); request.ODataProperties().Path = odataPath; request.ODataProperties().Model = model; // Act ETag result = request.GetETag(etagHeaderValue); dynamic dynamicResult = result; // Assert double actual = Assert.IsType <double>(result["Version"]); Assert.Equal(actual, dynamicResult.Version); if (isEqual) { Assert.Equal(value, actual); } else { Assert.NotEqual(value, actual); Assert.True(actual - value < 0.0000001); } }
/// <summary> /// Constructs an instance of <see cref="ODataQueryContext"/> with <see cref="IEdmModel" />, element EDM type, /// and <see cref="ODataPath" />. /// </summary> /// <param name="model">The EDM model the given EDM type belongs to.</param> /// <param name="elementType">The EDM type of the element of the collection being queried.</param> /// <param name="path">The parsed <see cref="ODataPath"/>.</param> public ODataQueryContext(IEdmModel model, IEdmType elementType, ODataPath path) { if (model == null) { throw Error.ArgumentNull("model"); } if (elementType == null) { throw Error.ArgumentNull("elementType"); } Model = model; ElementType = elementType; NavigationSource = GetNavigationSource(Model, ElementType, path); }
public RestierQueryBuilder(IApi api, ODataPath path) { Ensure.NotNull(api, "api"); Ensure.NotNull(path, "path"); this.api = api; this.path = path; this.handlers[ODataSegmentKinds.EntitySet] = this.HandleEntitySetPathSegment; this.handlers[ODataSegmentKinds.UnboundFunction] = this.HandleUnboundFunctionPathSegment; this.handlers[ODataSegmentKinds.Count] = this.HandleCountPathSegment; this.handlers[ODataSegmentKinds.Value] = this.HandleValuePathSegment; this.handlers[ODataSegmentKinds.Key] = this.HandleKeyValuePathSegment; this.handlers[ODataSegmentKinds.Navigation] = this.HandleNavigationPathSegment; this.handlers[ODataSegmentKinds.Property] = this.HandlePropertyAccessPathSegment; }
public void GenerateLocationHeader_ThrowsEntityTypeNotInModel_IfContentTypeIsNotThereInModel() { // Arrange CustomersModelWithInheritance model = new CustomersModelWithInheritance(); ODataPath path = new ODataPath(new EntitySetSegment(model.Customers)); HttpRequestMessage request = new HttpRequestMessage(); request.ODataProperties().Path = path; request.EnableHttpDependencyInjectionSupport(model.Model); CreatedODataResult <TestEntity> createdODataResult = GetCreatedODataResult(request); // Act & Assert Assert.Throws <InvalidOperationException>(() => createdODataResult.GenerateLocationHeader(), "Cannot find the resource type 'System.Web.OData.Results.CreatedODataResultTest+TestEntity' in the model."); }
public void ToStringWithOneTwoSegments() { // Arrange string expectedFirstSegment = "Set"; string expectedSecondSegment = "Action"; ODataPath path = new ODataPath(new EntitySetPathSegment(expectedFirstSegment), new BoundActionPathSegment(expectedSecondSegment)); // Act string value = path.ToString(); // Assert string expectedValue = expectedFirstSegment + "/" + expectedSecondSegment; Assert.Equal(expectedValue, value); }
public void SwaggerPathHandlerWorksForSwaggerMetadataUri(string swaggerMetadataUri) { SwaggerPathHandler handler = new SwaggerPathHandler(); IEdmModel model = new EdmModel(); ODataPath path = handler.Parse(model, "http://any", swaggerMetadataUri); ODataPathSegment segment = path.Segments.Last(); Assert.NotNull(path); Assert.Null(path.NavigationSource); Assert.Null(path.EdmType); Assert.Equal("$swagger", segment.ToString()); Assert.IsType <SwaggerPathSegment>(segment); }
public void GenerateLocationHeader_ThrowsTypeMustBeEntity_IfMappingTypeIsNotEntity() { CustomersModelWithInheritance model = new CustomersModelWithInheritance(); ODataPath path = new ODataPath(new EntitySetSegment(model.Customers)); HttpRequestMessage request = new HttpRequestMessage(); request.ODataProperties().Path = path; request.EnableHttpDependencyInjectionSupport(model.Model); model.Model.SetAnnotationValue(model.Address, new ClrTypeAnnotation(typeof(TestEntity))); CreatedODataResult <TestEntity> createdODataResult = GetCreatedODataResult(request); // Act & Assert Assert.Throws <InvalidOperationException>(() => createdODataResult.GenerateLocationHeader(), "NS.Address is not an entity type. Only entity types are supported."); }
/// <summary> /// Handles a POST request to create an entity. /// </summary> /// <param name="edmEntityObject">The entity object to create.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <returns>The task object that contains the creation result.</returns> public async Task <IHttpActionResult> Post(EdmEntityObject edmEntityObject, CancellationToken cancellationToken) { CheckModelState(); ODataPath path = this.GetPath(); IEdmEntitySet entitySet = path.NavigationSource as IEdmEntitySet; if (entitySet == null) { throw new NotImplementedException(Resources.InsertOnlySupportedOnEntitySet); } // In case of type inheritance, the actual type will be different from entity type var expectedEntityType = path.EdmType; var actualEntityType = path.EdmType as IEdmStructuredType; if (edmEntityObject.ActualEdmType != null) { expectedEntityType = edmEntityObject.ExpectedEdmType; actualEntityType = edmEntityObject.ActualEdmType; } DataModificationItem postItem = new DataModificationItem( entitySet.Name, expectedEntityType.GetClrType(Api.ServiceProvider), actualEntityType.GetClrType(Api.ServiceProvider), DataModificationItemAction.Insert, null, null, edmEntityObject.CreatePropertyDictionary(actualEntityType, api, true)); RestierChangeSetProperty changeSetProperty = this.Request.GetChangeSet(); if (changeSetProperty == null) { ChangeSet changeSet = new ChangeSet(); changeSet.Entries.Add(postItem); SubmitResult result = await Api.SubmitAsync(changeSet, cancellationToken); } else { changeSetProperty.ChangeSet.Entries.Add(postItem); await changeSetProperty.OnChangeSetCompleted(this.Request); } return(this.CreateCreatedODataResult(postItem.Resource)); }
internal static IReadOnlyDictionary<string, object> GetPathKeyValues(ODataPath path) { if (path.PathTemplate == "~/entityset/key" || path.PathTemplate == "~/entityset/key/cast") { KeyValuePathSegment keySegment = (KeyValuePathSegment)path.Segments[1]; return GetPathKeyValues(keySegment, (IEdmEntityType)path.EdmType); } else { throw new InvalidOperationException(string.Format( CultureInfo.InvariantCulture, Resources.InvalidPathTemplateInRequest, "~/entityset/key")); } }
public virtual string SelectAction(ODataPath odataPath, HttpControllerContext controllerContext, ILookup<string, HttpActionDescriptor> actionMap) { try { var action = entityRoutingConvention.SelectAction(odataPath, controllerContext, actionMap); if (action == null) return null; var routeValues = controllerContext.RouteData.Values; object value; if (!routeValues.TryGetValue(ODataRouteConstants.Key, out value)) return action; var compoundKeyPairs = ((string) value).Split(','); if (compoundKeyPairs.Length <= 0) return null; if (compoundKeyPairs.Length == 1) return action; compoundKeyPairs .Select(kv => kv.Split('=')) .Select(kv => { var key = kv[0].Trim(); var valstr = kv[1].Trim(); if (string.IsNullOrWhiteSpace(key)) throw new ApplicationException("Missing key for value: " + valstr); if (string.IsNullOrWhiteSpace(valstr)) throw new ApplicationException("Missing value for key " + key + ": " + valstr); object val = null; if (valstr.StartsWith("'") && valstr.EndsWith("'")) { val = valstr; } else if (valstr.StartsWith("datetime'") && valstr.EndsWith("'")) { val = DateTime.Parse(valstr.Substring(9, valstr.Length - 10)); } else if (valstr.All(x => char.IsDigit(x))) { val = int.Parse(valstr); } else if (valstr.All(x => char.IsDigit(x) || x == '.') && valstr.Count(x => x == '.') == 1) { val = double.Parse(valstr); } else { val = valstr; } return new KeyValuePair<string, object>(key, val); }).ForEach(routeValues.Add); return action; } catch (Exception ex) { throw new HttpResponseException(new HttpResponseMessage(HttpStatusCode.BadRequest) { Content = new StringContent(ex.Message) }); } }
public void SelectExpandClause_Property_ParsesWithEdmTypeAndNavigationSource() { // Arrange IEdmModel model = _model.Model; _model.Model.SetAnnotationValue(_model.Customer, new ClrTypeAnnotation(typeof(Customer))); ODataPath odataPath = new ODataPath(new EntitySetPathSegment(_model.Customers)); ODataQueryContext context = new ODataQueryContext(model, _model.Customer, odataPath); SelectExpandQueryOption option = new SelectExpandQueryOption("ID,Name,SimpleEnum,Orders", "Orders", context); // Act SelectExpandClause selectExpandClause = option.SelectExpandClause; // Assert Assert.NotEmpty(selectExpandClause.SelectedItems.OfType <PathSelectItem>()); Assert.NotEmpty(selectExpandClause.SelectedItems.OfType <ExpandedNavigationSelectItem>()); }
/// <summary> /// Matches the current template with an OData path. /// </summary> /// <param name="path">The OData path to be matched against.</param> /// <param name="values">The dictionary of matches to be updated in case of a match.</param> /// <returns><see langword="true"/> in case of a match; otherwise, <see langword="false"/>.</returns> public bool TryMatch(ODataPath path, IDictionary<string, object> values) { if (path.Segments.Count != Segments.Count) { return false; } for (int index = 0; index < Segments.Count; index++) { if (!Segments[index].TryMatch(path.Segments[index], values)) { return false; } } return true; }
internal static ODataDeserializerContext BuildDeserializerContext(HttpActionContext actionContext, ModelBindingContext bindingContext, IEdmTypeReference edmTypeReference) { HttpRequestMessage request = actionContext.Request; ODataPath path = request.ODataProperties().Path; IEdmModel edmModel = request.GetModel(); return(new ODataDeserializerContext { Path = path, Model = edmModel, Request = request, ResourceType = bindingContext.ModelType, ResourceEdmType = edmTypeReference, RequestContext = request.GetRequestContext() }); }
public void GenerateODataLink_ThrowsIdLinkNullForEntityIdHeader_IfEntitySetLinkBuilderReturnsNull() { // Arrange var linkBuilder = new Mock<NavigationSourceLinkBuilderAnnotation>(); var model = new CustomersModelWithInheritance(); model.Model.SetAnnotationValue(model.Customer, new ClrTypeAnnotation(typeof(TestEntity))); model.Model.SetNavigationSourceLinkBuilder(model.Customers, linkBuilder.Object); var path = new ODataPath(new EntitySetPathSegment(model.Customers)); var request = new HttpRequestMessage(); request.ODataProperties().Model = model.Model; request.ODataProperties().Path = path; // Act & Assert Assert.Throws<InvalidOperationException>( () => ResultHelpers.GenerateODataLink(request, _entity, isEntityId: true), "The Id link builder for the entity set 'Customers' returned null. An Id link is required for the OData-EntityId header."); }
public void GetResponseStatusCode_ReturnsNoContentForProperties_AndNotFoundForEntities(string odataPath, HttpStatusCode?expected) { // Arrange IEdmModel model = BuildModel(); IODataPathHandler pathHandler = new DefaultODataPathHandler(); ODataPath path = pathHandler.Parse(model, "http://localhost/any", odataPath); // Guard Assert.NotNull(path); // Act HttpStatusCode?statusCode = ODataNullValueMessageHandler.GetUpdatedResponseStatusCodeOrNull(path); // Assert Assert.Equal(expected, statusCode); }
public override string Link(ODataPath path) { bool firstSegment = true; StringBuilder sb = new StringBuilder(); foreach (ODataPathSegment segment in path.Segments) { if (firstSegment) { firstSegment = false; } else { sb.Append('/'); } sb.Append(segment); } return sb.ToString(); }
public void OnActionExecuted_DoesntChangeTheResponse_IfResponseIsntSuccessful() { IEdmModel model = new Mock<IEdmModel>().Object; ODataPath path = new ODataPath(new EntitySetPathSegment("FakeEntitySet"), new KeyValuePathSegment("FakeKey"), new PropertyAccessPathSegment("FakeProperty"), new ValuePathSegment()); HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, "http://localhost/"); request.ODataProperties().Model = model; request.ODataProperties().Path = path; ODataNullValueAttribute odataNullValue = new ODataNullValueAttribute(); HttpResponseMessage response = SetUpResponse(HttpStatusCode.InternalServerError, null, typeof(object)); HttpActionExecutedContext context = SetUpContext(request, response); odataNullValue.OnActionExecuted(context); Assert.Equal(response, context.Response); }
private ODataPath GetPath() { HttpRequestMessageProperties properties = this.Request.ODataProperties(); if (properties == null) { throw new InvalidOperationException(Resources.InvalidODataInfoInRequest); } ODataPath path = properties.Path; if (path == null) { throw new InvalidOperationException(Resources.InvalidEmptyPathInRequest); } return(path); }
/// <summary> /// Handles a DELETE request to delete an entity. /// </summary> /// <param name="cancellationToken">The cancellation token.</param> /// <returns>The task object that contains the deletion result.</returns> public async Task <IHttpActionResult> Delete(CancellationToken cancellationToken) { ODataPath path = this.GetPath(); IEdmEntitySet entitySet = path.NavigationSource as IEdmEntitySet; if (entitySet == null) { throw new NotImplementedException(Resources.DeleteOnlySupportedOnEntitySet); } var propertiesInEtag = await this.GetOriginalValues(entitySet); if (propertiesInEtag == null) { throw new PreconditionRequiredException(Resources.PreconditionRequired); } DataModificationItem deleteItem = new DataModificationItem( entitySet.Name, path.EdmType.GetClrType(Api.ServiceProvider), null, DataModificationItemAction.Remove, RestierQueryBuilder.GetPathKeyValues(path), propertiesInEtag, null); RestierChangeSetProperty changeSetProperty = this.Request.GetChangeSet(); if (changeSetProperty == null) { ChangeSet changeSet = new ChangeSet(); changeSet.Entries.Add(deleteItem); SubmitResult result = await Api.SubmitAsync(changeSet, cancellationToken); } else { changeSetProperty.ChangeSet.Entries.Add(deleteItem); await changeSetProperty.OnChangeSetCompleted(this.Request); } return(this.StatusCode(HttpStatusCode.NoContent)); }
public void GenerateLocationHeader_ThrowsEditLinkNullForLocationHeader_IfEntitySetLinkBuilderReturnsNull() { // Arrange Mock <NavigationSourceLinkBuilderAnnotation> linkBuilder = new Mock <NavigationSourceLinkBuilderAnnotation>(); CustomersModelWithInheritance model = new CustomersModelWithInheritance(); model.Model.SetAnnotationValue(model.Customer, new ClrTypeAnnotation(typeof(TestEntity))); model.Model.SetNavigationSourceLinkBuilder(model.Customers, linkBuilder.Object); ODataPath path = new ODataPath(new EntitySetSegment(model.Customers)); HttpRequestMessage request = new HttpRequestMessage(); request.ODataProperties().Path = path; request.EnableHttpDependencyInjectionSupport(model.Model); CreatedODataResult <TestEntity> createdODataResult = GetCreatedODataResult(request); // Act Assert.Throws <InvalidOperationException>(() => createdODataResult.GenerateLocationHeader(), "The edit link builder for the entity set 'Customers' returned null. An edit link is required for the location header."); }
public string SelectAction(System.Web.OData.Routing.ODataPath odataPath, System.Web.Http.Controllers.HttpControllerContext controllerContext, ILookup <string, System.Web.Http.Controllers.HttpActionDescriptor> actionMap) { // stored procedure if (odataPath.PathTemplate == "~/unboundaction") { return("DoAction"); } if (odataPath.PathTemplate == "~/unboundfunction/$count") { return("GetFuncResultCount"); } if (odataPath.PathTemplate == "~/unboundfunction") { return("GetSimpleFunction"); } if (odataPath.PathTemplate == "~/entityset/$count") { return("GetCount"); } return(null); }
private static ODataQueryOptions GetQueryOptions(string queryOption) { string uri = "Http://localhost/RoutingCustomers?" + queryOption; HttpConfiguration configuration = new HttpConfiguration(); configuration.EnableCaseInsensitive(true); HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, uri); request.SetConfiguration(configuration); IEdmModel model = ODataRoutingModel.GetModel(); IEdmEntitySet entityset = model.EntityContainer.FindEntitySet("RoutingCustomers"); IEdmEntityType entityType = model.SchemaElements.OfType <IEdmEntityType>().Single(e => e.Name == "RoutingCustomer"); ODataPath path = new ODataPath(new[] { new EntitySetPathSegment(entityset) }); ODataQueryContext context = new ODataQueryContext(model, entityType, path); return(new ODataQueryOptions(context, request)); }
public void CanReadType_ForTypeless_ReturnsExpectedResult_DependingOnODataPathAndPayloadKind(ODataPath path, ODataPayloadKind payloadKind) { // Arrange IEnumerable <ODataPayloadKind> allPayloadKinds = Enum.GetValues(typeof(ODataPayloadKind)).Cast <ODataPayloadKind>(); var model = CreateModel(); var request = CreateFakeODataRequest(model); request.ODataProperties().Path = path; var formatterWithGivenPayload = new ODataMediaTypeFormatter(new[] { payloadKind }) { Request = request }; var formatterWithoutGivenPayload = new ODataMediaTypeFormatter(allPayloadKinds.Except(new[] { payloadKind })) { Request = request }; // Act & Assert Assert.True(formatterWithGivenPayload.CanReadType(typeof(IEdmObject))); Assert.False(formatterWithoutGivenPayload.CanReadType(typeof(IEdmObject))); }