public UnboundFunctionPathSegmentTest()
 {
     ODataModelBuilder builder = new ODataModelBuilder();
     builder.EntityType<MyCustomer>().HasKey(c => c.Id).Property(c => c.Name);
     builder.EntitySet<MyCustomer>("Customers");
     FunctionConfiguration function = builder.Function("TopCustomer");
     function.ReturnsFromEntitySet<MyCustomer>("Customers");
     builder.Function("MyFunction").Returns<string>();
     _model = builder.GetEdmModel();
     _container = _model.EntityContainers().Single();
 }
        public void CanCreateFunctionWithNoArguments()
        {
            // Arrange
            // Act
            ODataModelBuilder builder = new ODataModelBuilder();
            builder.Namespace = "MyNamespace";
            builder.ContainerName = "MyContainer";
            FunctionConfiguration function = builder.Function("Format");

            // Assert
            Assert.Equal("Format", function.Name);
            Assert.Equal(ProcedureKind.Function, function.Kind);
            Assert.NotNull(function.Parameters);
            Assert.Empty(function.Parameters);
            Assert.Null(function.ReturnType);
            Assert.False(function.IsSideEffecting);
            Assert.False(function.IsComposable);
            Assert.False(function.IsBindable);
            Assert.False(function.SupportedInFilter);
            Assert.False(function.SupportedInOrderBy);
            Assert.Equal("MyContainer.Format", function.ContainerQualifiedName);
            Assert.Equal("MyContainer.Format", function.FullName);
            Assert.Equal("MyNamespace.MyContainer.Format", function.FullyQualifiedName);
            Assert.NotNull(builder.Procedures);
            Assert.Equal(1, builder.Procedures.Count());
        }
        public void CanCreateFunctionWithReturnTypeAsNullableByOptionalReturn()
        {
            // Arrange & Act
            ODataModelBuilder     builder  = new ODataModelBuilder();
            FunctionConfiguration function = builder.Function("MyFunction").Returns <Address>();

            function.ReturnNullable = false;

            // Assert
            Assert.False(function.ReturnNullable);
        }
        public void CanCreateFunctionWithPrimitiveCollectionReturnType()
        {
            // Arrange
            // Act
            ODataModelBuilder builder = new ODataModelBuilder();
            FunctionConfiguration function = builder.Function("CreateMessages");
            function.ReturnsCollection<string>();

            // Assert
            Assert.NotNull(function.ReturnType);
            Assert.Equal("Collection(Edm.String)", function.ReturnType.FullName);
        }
Example #5
0
        private static IEdmModel GetModel(WebRouteConfiguration config)
        {
            ODataModelBuilder builder = config.CreateConventionModelBuilder();

            builder.EntitySet <DerivedTypeA>("SetA");
            builder.EntitySet <DerivedTypeB>("SetB");

            builder.EntityType <BaseType>(); // this line is necessary.
            builder.Function("ReturnAll").ReturnsCollection <BaseType>();

            return(builder.GetEdmModel());
        }
Example #6
0
        public void HasFeedFunctionLink_ThrowsException_OnNonBindableFunctions()
        {
            // Arrange
            ODataModelBuilder     builder  = new ODataModelBuilder();
            FunctionConfiguration function = builder.Function("NoBindableFunction");

            // Act & Assert
            ExceptionAssert.Throws <InvalidOperationException>(
                () => function.HasFeedFunctionLink(ctx => new Uri("http://any"), followsConventions: false),
                "To register a function link factory, functions must be bindable to the collection of entity. " +
                "Function 'NoBindableFunction' does not meet this requirement.");
        }
Example #7
0
        public void CanCreateFunctionWithPrimitiveReturnType()
        {
            // Arrange & Act
            ODataModelBuilder     builder  = new ODataModelBuilder();
            FunctionConfiguration function = builder.Function("CreateMessage");

            function.Returns <string>();

            // Assert
            Assert.NotNull(function.ReturnType);
            Assert.Equal("Edm.String", function.ReturnType.FullName);
        }
Example #8
0
        private static IEdmModel CreateModel()
        {
            var builder = new ODataModelBuilder();

            builder.Namespace = "HS";

            var personType = builder.EntityType <Person>()
                             .HasKey(p => p.Id);

            personType.Property(p => p.Name);
            personType.Property(p => p.Age);
            personType.OrderBy().Select().Filter().Expand().Count();

            personType.Action("Mark").Parameter <string>("comment");

            // Entity Function
            var function = personType
                           .Function("ToLongString");

            function.Parameter <string>("prefix");
            function.Returns <string>();

            // Collection Functions
            var allAdultsFunction = personType
                                    .Collection
                                    .Function("AllAdults");

            allAdultsFunction.ReturnsCollectionFromEntitySet <Person>("Persons");

            var allChildrenFunction = personType
                                      .Collection
                                      .Function("AllChildren");

            allChildrenFunction.ReturnsCollectionFromEntitySet <Person>("Persons");

            // Unbound Function
            var addFunction = builder.Function("Add");

            addFunction.Parameter <int>("z1");
            addFunction.Parameter <int>("z2");
            addFunction.Returns <int>();

            // Unbound Action
            var clearAction = builder.Action("ClearLoggingTable");

            clearAction.Parameter <int>("days");

            builder.EntitySet <Person>("Persons");

            return(builder.GetEdmModel());
        }
Example #9
0
        private static void AddUnboundActionsAndFunctions(ODataModelBuilder odataModelBuilder)
        {
            var actionConfiguration = odataModelBuilder.Action("SetAccessLevel");
            actionConfiguration.Parameter<int>("ID");
            actionConfiguration.Parameter<AccessLevel>("accessLevel");
            actionConfiguration.Returns<AccessLevel>();

            var functionConfiguration = odataModelBuilder.Function("HasAccessLevel");
            functionConfiguration.Parameter<int>("ID");
            functionConfiguration.Parameter<AccessLevel>("AccessLevel");
            functionConfiguration.Returns<bool>();

            var actionConfiguration2 = odataModelBuilder.Action("ResetDataSource");
        }
        public void GetEdmModel_CreatesOperationImports_For_UnboundedOperations()
        {
            // Arrange
            ODataModelBuilder builder = new ODataModelBuilder();

            builder.Function("Function").Returns <bool>();
            builder.Action("Action").Returns <bool>();

            // Act
            IEdmModel model = builder.GetEdmModel();

            // Assert
            Assert.Equal(2, model.EntityContainer.OperationImports().Count());
        }
        public void Parameter_ThrowsInvalidOperationIfGenericArgumentIsDateTime(Type type)
        {
            // Arrange
            ODataModelBuilder builder = new ODataModelBuilder();
            FunctionConfiguration function = builder.Function("Format");
            MethodInfo method = typeof(FunctionConfiguration)
                .GetMethod("Parameter", new[] { typeof(string) })
                .MakeGenericMethod(type);

            // Act & Assert
            Assert.Throws<InvalidOperationException>(
                () => method.Invoke(function, new[] { "test" }),
                string.Format("The type '{0}' is not a supported parameter type for the parameter test.", type.FullName));
        }
        public void Returns_ThrowsInvalidOperationIfGenericArgumentIsDateTime(Type type)
        {
            // Arrange
            ODataModelBuilder builder = new ODataModelBuilder();
            FunctionConfiguration function = builder.Function("Format");
            MethodInfo method = typeof(FunctionConfiguration)
                .GetMethod("Returns")
                .MakeGenericMethod(type);

            // Act & Assert
            Assert.Throws<InvalidOperationException>(
                () => method.Invoke(function, new object[] { }),
                string.Format("The type '{0}' is not a supported return type.", type.FullName));
        }
        public void AttemptToRemoveNonExistentEntityReturnsFalse()
        {
            // Arrange
            ODataModelBuilder builder = new ODataModelBuilder();
            ODataModelBuilder builder2 = new ODataModelBuilder();
            ProcedureConfiguration toRemove = builder2.Function("ToRemove");

            // Act
            bool removedByName = builder.RemoveProcedure("ToRemove");
            bool removed = builder.RemoveProcedure(toRemove);

            //Assert
            Assert.False(removedByName);
            Assert.False(removed);
        }
        private static void BuildFunctions(ODataModelBuilder builder)
        {
            FunctionConfiguration function = builder.EntityType<DCustomer>().Function("BoundFunction")
                    .ReturnsCollectionViaEntitySetPath<DCustomer>("bindingParameter");
            function.Parameter<Date>("modifiedDate");
            function.Parameter<TimeOfDay>("modifiedTime");
            function.Parameter<Date?>("nullableModifiedDate");
            function.Parameter<TimeOfDay?>("nullableModifiedTime");

            function = builder.Function("UnboundFunction").ReturnsCollectionFromEntitySet<DCustomer>("DCustomers");
            function.Parameter<Date>("modifiedDate");
            function.Parameter<TimeOfDay>("modifiedTime");
            function.Parameter<Date?>("nullableModifiedDate");
            function.Parameter<TimeOfDay?>("nullableModifiedTime");
        }
Example #15
0
        public void CanCreateFunctionWithComplexReturnType()
        {
            // Arrange & Act
            ODataModelBuilder builder = new ODataModelBuilder();

            FunctionConfiguration createAddress   = builder.Function("CreateAddress").Returns <Address>();
            FunctionConfiguration createAddresses = builder.Function("CreateAddresses").ReturnsCollection <Address>();

            // Assert
            ComplexTypeConfiguration address = createAddress.ReturnType as ComplexTypeConfiguration;

            Assert.NotNull(address);
            Assert.Equal(typeof(Address).FullName, address.FullName);
            Assert.Null(createAddress.NavigationSource);

            CollectionTypeConfiguration addresses = createAddresses.ReturnType as CollectionTypeConfiguration;

            Assert.NotNull(addresses);
            Assert.Equal(string.Format("Collection({0})", typeof(Address).FullName), addresses.FullName);
            address = addresses.ElementType as ComplexTypeConfiguration;
            Assert.NotNull(address);
            Assert.Equal(typeof(Address).FullName, address.FullName);
            Assert.Null(createAddresses.NavigationSource);
        }
Example #16
0
        public void AttemptToRemoveNonExistentEntityReturnsFalse()
        {
            // Arrange
            ODataModelBuilder      builder  = new ODataModelBuilder();
            ODataModelBuilder      builder2 = new ODataModelBuilder();
            OperationConfiguration toRemove = builder2.Function("ToRemove");

            // Act
            bool removedByName = builder.RemoveOperation("ToRemove");
            bool removed       = builder.RemoveOperation(toRemove);

            //Assert
            Assert.False(removedByName);
            Assert.False(removed);
        }
        private static void BuildFunctions(ODataModelBuilder builder)
        {
            FunctionConfiguration function = builder.EntityType <DCustomer>().Function("BoundFunction")
                                             .ReturnsCollectionViaEntitySetPath <DCustomer>("bindingParameter");

            function.Parameter <Date>("modifiedDate");
            function.Parameter <TimeOfDay>("modifiedTime");
            function.Parameter <Date?>("nullableModifiedDate");
            function.Parameter <TimeOfDay?>("nullableModifiedTime");

            function = builder.Function("UnboundFunction").ReturnsCollectionFromEntitySet <DCustomer>("DCustomers");
            function.Parameter <Date>("modifiedDate");
            function.Parameter <TimeOfDay>("modifiedTime");
            function.Parameter <Date?>("nullableModifiedDate");
            function.Parameter <TimeOfDay?>("nullableModifiedTime");
        }
Example #18
0
        private static void AddUnboundActionsAndFunctions(ODataModelBuilder odataModelBuilder)
        {
            var actionConfiguration = odataModelBuilder.Action("SetAccessLevel");

            actionConfiguration.Parameter <int>("ID");
            actionConfiguration.Parameter <AccessLevel>("accessLevel");
            actionConfiguration.Returns <AccessLevel>();

            var functionConfiguration = odataModelBuilder.Function("HasAccessLevel");

            functionConfiguration.Parameter <int>("ID");
            functionConfiguration.Parameter <AccessLevel>("AccessLevel");
            functionConfiguration.Returns <bool>();

            var actionConfiguration2 = odataModelBuilder.Action("ResetDataSource");
        }
Example #19
0
        public void CanCreateFunctionWithNonbindingParameters()
        {
            // Arrange & Act
            ODataModelBuilder     builder  = new ODataModelBuilder();
            FunctionConfiguration function = builder.Function("MyFunction");

            function.Parameter <string>("p0");
            function.Parameter <int>("p1");
            function.Parameter <Address>("p2");
            function.CollectionParameter <string>("p3");
            function.CollectionParameter <int>("p4");
            function.CollectionParameter <ZipCode>("p5");
            function.EntityParameter <Customer>("p6");
            function.CollectionEntityParameter <Employee>("p7");
            ParameterConfiguration[]   parameters   = function.Parameters.ToArray();
            ComplexTypeConfiguration[] complexTypes = builder.StructuralTypes.OfType <ComplexTypeConfiguration>().ToArray();
            EntityTypeConfiguration[]  entityTypes  = builder.StructuralTypes.OfType <EntityTypeConfiguration>().ToArray();

            // Assert
            Assert.Equal(2, complexTypes.Length);
            Assert.Equal(typeof(Address).FullName, complexTypes[0].FullName);
            Assert.Equal(typeof(ZipCode).FullName, complexTypes[1].FullName);

            Assert.Equal(2, entityTypes.Length);
            Assert.Equal(typeof(Customer).FullName, entityTypes[0].FullName);
            Assert.Equal(typeof(Employee).FullName, entityTypes[1].FullName);

            Assert.Equal(8, parameters.Length);
            Assert.Equal("p0", parameters[0].Name);
            Assert.Equal("Edm.String", parameters[0].TypeConfiguration.FullName);
            Assert.Equal("p1", parameters[1].Name);
            Assert.Equal("Edm.Int32", parameters[1].TypeConfiguration.FullName);
            Assert.Equal("p2", parameters[2].Name);
            Assert.Equal(typeof(Address).FullName, parameters[2].TypeConfiguration.FullName);
            Assert.Equal("p3", parameters[3].Name);
            Assert.Equal("Collection(Edm.String)", parameters[3].TypeConfiguration.FullName);
            Assert.Equal("p4", parameters[4].Name);
            Assert.Equal("Collection(Edm.Int32)", parameters[4].TypeConfiguration.FullName);
            Assert.Equal("p5", parameters[5].Name);
            Assert.Equal(string.Format("Collection({0})", typeof(ZipCode).FullName), parameters[5].TypeConfiguration.FullName);

            Assert.Equal("p6", parameters[6].Name);
            Assert.Equal(typeof(Customer).FullName, parameters[6].TypeConfiguration.FullName);

            Assert.Equal("p7", parameters[7].Name);
            Assert.Equal(string.Format("Collection({0})", typeof(Employee).FullName), parameters[7].TypeConfiguration.FullName);
        }
        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);
        }
Example #21
0
        public void Cant_SetFunctionTitle_OnNonBindableFunctions()
        {
            // Arrange
            ODataModelBuilder     builder  = new ODataModelBuilder();
            FunctionConfiguration function = builder.Function("MyFunction");

            function.Returns <int>();
            function.Title = "My Function";

            // Act
            IEdmModel           model          = builder.GetEdmModel();
            IEdmOperationImport functionImport = model.EntityContainer.OperationImports().OfType <IEdmFunctionImport>().Single();

            Assert.NotNull(functionImport);
            OperationTitleAnnotation functionTitleAnnotation = model.GetOperationTitleAnnotation(functionImport.Operation);

            // Assert
            Assert.Null(functionTitleAnnotation);
        }
Example #22
0
        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 builder = new ODataModelBuilder();

            builder.Function("Unbound").Returns <string>().Parameter <string>("p0");
            var model = builder.GetEdmModel();

            var pathHandler  = new TestPathHandler();
            var oDataPath    = String.Format("Unbound(p0='{0}')", oDataString);
            var routeRequest = new TestRouteRequest(HttpMethod.Get, originalRoot + oDataPath)
            {
                PathHandler = pathHandler,
                Model       = model,
            };

            var constraint = CreatePathRouteConstraint();
            var values     = new Dictionary <string, object>
            {
                { ODataRouteConstants.ODataPath, Uri.UnescapeDataString(oDataPath) },
            };

            // Act
            var matched = ConstraintMatch(constraint, routeRequest, values, RouteDirection.UriResolution);

            // Assert
            Assert.True(matched);
            Assert.NotNull(pathHandler.ServiceRoot);
            Assert.Equal(expectedRoot, pathHandler.ServiceRoot);
            Assert.NotNull(pathHandler.ODataPath);
            Assert.Equal(oDataPath, pathHandler.ODataPath);
        }
Example #23
0
        public void CanCreateFunctionWithNonbindingParameters_AddParameterNonGenericMethod()
        {
            // Arrange & Act
            ODataModelBuilder     builder  = new ODataModelBuilder();
            FunctionConfiguration function = builder.Function("MyFunction");

            function.Parameter(typeof(string), "p0");
            function.Parameter(typeof(int), "p1");
            function.Parameter(typeof(Address), "p2");
            ParameterConfiguration[] parameters = function.Parameters.ToArray();

            // Assert
            Assert.Equal(3, parameters.Length);
            Assert.Equal("p0", parameters[0].Name);
            Assert.Equal("Edm.String", parameters[0].TypeConfiguration.FullName);
            Assert.Equal("p1", parameters[1].Name);
            Assert.Equal("Edm.Int32", parameters[1].TypeConfiguration.FullName);
            Assert.Equal("p2", parameters[2].Name);
            Assert.Equal(typeof(Address).FullName, parameters[2].TypeConfiguration.FullName);
        }
Example #24
0
        /// <summary>
        /// Applies model configurations using the provided builder for the specified API version.
        /// </summary>
        /// <param name="builder"></param>
        /// <param name="apiVersion"></param>
        public void Apply(ODataModelBuilder builder, ApiVersion apiVersion)
        {
            var countries     = builder.EntitySet <Country>("Countries").EntityType.HasKey(k => k.Id);
            var countryByName = builder.Function("GetCountryByName")
                                .Returns <Country>()
                                .Parameter <string>("name");

            var merchants = builder.EntitySet <Merchant>("Merchants").EntityType.HasKey(k => k.Id);

            var locations         = builder.EntitySet <Location>("Locations").EntityType.HasKey(k => k.Id);
            var merchantLocations = builder.EntityType <Location>().Collection
                                    .Function("GetMerchantLocations")
                                    .ReturnsCollection <Location>();
            //.Parameter<int>("merchantId");

            var search = builder.EntitySet <GlobalSearch>("Search").EntityType.HasKey(k => k.Id);

            //var test = builder.Function("GetClaims")
            //          .ReturnsCollection<string>();

            //builder.Action("CreateLocations");
        }
        private EntityTypeConfiguration <FlightPlan> ConfigureCurrent(ODataModelBuilder builder)
        {
            //var flightplan = builder.EntitySet<FlightPlan>("FlightPlans").EntityType;
            builder.EntitySet <FlightPlan>("FlightPlans");
            var flightPlanType = builder.EntityType <FlightPlan>();

            //flightPlanType
            //   .Function("Current")
            //   .Returns<FlightPlan>()
            //   .Parameter<string>("flightNumber");
            flightPlanType
            .Function("Current")
            .ReturnsFromEntitySet <FlightPlan>("FlightPlan");

            var fnGetCurrent = builder.Function("GetCurrentFlightPlan");

            fnGetCurrent.Returns <FlightPlan>();
            fnGetCurrent.Parameter <string>("flightNumber");
            fnGetCurrent.Parameter <string>("iataAirlineCode");

            //var fnCurrent = builder.EntityType<FlightPlan>().Collection.Function("Current");
            //fnCurrent.Parameter<string>("flightNumber");
            //fnCurrent.ReturnsFromEntitySet<FlightPlan>("FlightPlan");
            //var functionFlightPlan = builder.Function("GetFlightPlansP");
            //functionFlightPlan.Returns<FlightPlan>();
            //functionFlightPlan.Parameter<string>("flightNumber");
            //functionFlightPlan.Parameter<string>("iataCode");
            //builder.Function("GetFlightPlans")
            //    .Returns<FlightPlan>()
            //    .Parameter(<string>("flightNumber")


            return(builder.EntityType <FlightPlan>());

            //var conventions = ODataRoutingConventions.CreateDefault();
            //conventions.Insert(0, new CompositeKeyRoutingConvention());

            // return flightplan;
        }
Example #26
0
        public static IEdmModel GetEdmModel2()
        {
            var builder = new ODataModelBuilder();

            // enum type
            var color = builder.EnumType <Color>();

            color.Member(Color.Red);
            color.Member(Color.Blue);
            color.Member(Color.Green);

            // complex type
            // var address = builder.ComplexType<Address>().Abstract();
            var address = builder.ComplexType <Address>();

            address.Property(a => a.Country);
            address.Property(a => a.City);
            // address.HasDynamicProperties(a => a.Dynamics);

            var subAddress = builder.ComplexType <SubAddress>().DerivesFrom <Address>();

            subAddress.Property(s => s.Street);

            // entity type
            // var customer = builder.EntityType<Customer>().Abstract();
            var customer = builder.EntityType <Customer>();

            customer.HasKey(c => c.CustomerId);
            customer.ComplexProperty(c => c.Location);
            customer.HasMany(c => c.Orders);
            // customer.HasDynamicProperties(c => c.Dynamics);

            var order = builder.EntityType <Order>();

            order.HasKey(o => o.OrderId);
            order.Property(o => o.Token);

            // entity set
            builder.EntitySet <Customer>("Customers");
            builder.EntitySet <Order>("Orders");

            // function
            var function = customer.Function("BoundFunction").Returns <string>();

            function.Parameter <int>("value");
            function.Parameter <Address>("address");

            function = builder.Function("UnBoundFunction").Returns <int>();
            function.Parameter <Color>("color");
            function.EntityParameter <Order>("order");

            // action
            var action = customer.Collection.Action("BoundAction");

            action.Parameter <int>("value");
            action.CollectionParameter <Address>("addresses");

            action = builder.Action("UnBoundAction").Returns <int>();
            action.Parameter <Color>("color");
            action.CollectionEntityParameter <Order>("orders");

            return(builder.GetEdmModel());
        }
        public static IEdmModel GetEdmModel()
        {
            if (_model == null)
            {
                ODataModelBuilder model = new ODataModelBuilder();

                var color = model.EnumType<Color>();
                color.Member(Color.Red);
                color.Member(Color.Green);
                color.Member(Color.Blue);

                var people = model.EntitySet<FormatterPerson>("People");
                people.HasFeedSelfLink(context => new Uri(context.Url.CreateODataLink(new EntitySetPathSegment(
                    context.EntitySetBase))));
                people.HasIdLink(context =>
                    {
                        return new Uri(context.Url.CreateODataLink(
                            new EntitySetPathSegment(context.NavigationSource as IEdmEntitySet),
                            new KeyValuePathSegment(context.GetPropertyValue("PerId").ToString())));
                    },
                    followsConventions: false);

                var person = people.EntityType;
                person.HasKey(p => p.PerId);
                person.Property(p => p.Age);
                person.Property(p => p.MyGuid);
                person.Property(p => p.Name);
                person.EnumProperty(p => p.FavoriteColor);
                person.ComplexProperty<FormatterOrder>(p => p.Order);

                var order = model.ComplexType<FormatterOrder>();
                order.Property(o => o.OrderAmount);
                order.Property(o => o.OrderName);

                // Add a top level function without parameter and the "IncludeInServiceDocument = true"
                var getPerson = model.Function("GetPerson");
                getPerson.ReturnsFromEntitySet<FormatterPerson>("People");
                getPerson.IncludeInServiceDocument = true;

                // Add a top level function without parameter and the "IncludeInServiceDocument = false"
                var getAddress = model.Function("GetAddress");
                getAddress.Returns<string>();
                getAddress.IncludeInServiceDocument = false;

                // Add an overload top level function with parameters and the "IncludeInServiceDocument = true"
                getPerson = model.Function("GetPerson");
                getPerson.Parameter<int>("PerId");
                getPerson.ReturnsFromEntitySet<FormatterPerson>("People");
                getPerson.IncludeInServiceDocument = true;

                // Add an overload top level function with parameters and the "IncludeInServiceDocument = false"
                getAddress = model.Function("GetAddress");
                getAddress.Parameter<int>("AddressId");
                getAddress.Returns<string>();
                getAddress.IncludeInServiceDocument = false;

                // Add an overload top level function
                var getVipPerson = model.Function("GetVipPerson");
                getVipPerson.Parameter<string>("name");
                getVipPerson.ReturnsFromEntitySet<FormatterPerson>("People");
                getVipPerson.IncludeInServiceDocument = true;

                // Add a top level function which is included in service document
                getVipPerson = model.Function("GetVipPerson");
                getVipPerson.ReturnsFromEntitySet<FormatterPerson>("People");
                getVipPerson.IncludeInServiceDocument = true;

                // Add an overload top level function
                getVipPerson = model.Function("GetVipPerson");
                getVipPerson.Parameter<int>("PerId");
                getVipPerson.Parameter<string>("name");
                getVipPerson.ReturnsFromEntitySet<FormatterPerson>("People");
                getVipPerson.IncludeInServiceDocument = true;

                // Add a top level function with parameters and without any overload
                var getSalary = model.Function("GetSalary");
                getSalary.Parameter<int>("PerId");
                getSalary.Parameter<string>("month");
                getSalary.Returns<int>();
                getSalary.IncludeInServiceDocument = true;

                // Add Singleton
                var president = model.Singleton<FormatterPerson>("President");
                president.HasIdLink(context =>
                    {
                        return new Uri(context.Url.CreateODataLink(new SingletonPathSegment((IEdmSingleton)context.NavigationSource)));
                    },
                    followsConventions: false);

                _model = model.GetEdmModel();
            }

            return _model;
        }
Example #28
0
        public void UnboundFunction_ForEnumTypeInODataModelBuilder()
        {
            // Arrange
            ODataModelBuilder builder = new ODataModelBuilder();
            FunctionConfiguration functionConfiguration = builder.Function("UnboundFunction");
            functionConfiguration.CollectionParameter<Color>("Colors");
            functionConfiguration.ReturnsCollection<Color>();
            builder.Add_Color_EnumType();

            // Act & Assert
            IEdmModel model = builder.GetEdmModel();
            IEdmFunctionImport functionImport = model.EntityContainer.OperationImports().Single(o => o.Name == "UnboundFunction") as IEdmFunctionImport;

            IEdmTypeReference colors = functionImport.Function.Parameters.Single(p => p.Name == "Colors").Type;
            IEdmTypeReference returnType = functionImport.Function.ReturnType;
            IEdmEnumType colorType = model.SchemaElements.OfType<IEdmEnumType>().Single(e => e.Name == "Color");

            Assert.True(colors.IsCollection());
            Assert.Same(colorType, colors.AsCollection().ElementType().Definition);
            Assert.True(returnType.IsCollection());
            Assert.False(returnType.AsCollection().ElementType().IsNullable);
            Assert.Same(colorType, returnType.AsCollection().ElementType().Definition);
        }
Example #29
0
        public static IEdmModel GetEdmModel()
        {
            if (_model == null)
            {
                ODataModelBuilder model = new ODataModelBuilder();

                var color = model.EnumType <Color>();
                color.Member(Color.Red);
                color.Member(Color.Green);
                color.Member(Color.Blue);

                var people = model.EntitySet <FormatterPerson>("People");

                people.HasFeedSelfLink(context => new Uri(context.InternalUrlHelper.CreateODataLink(new EntitySetSegment(
                                                                                                        context.EntitySetBase as IEdmEntitySet))));
                people.HasIdLink(context =>
                {
                    var keys = new[] { new KeyValuePair <string, object>("PerId", context.GetPropertyValue("PerId")) };
                    return(new Uri(context.InternalUrlHelper.CreateODataLink(
                                       new EntitySetSegment(context.NavigationSource as IEdmEntitySet),
                                       new KeySegment(keys, context.StructuredType as IEdmEntityType, context.NavigationSource))));
                },
                                 followsConventions: false);

                var person = people.EntityType;
                person.HasKey(p => p.PerId);
                person.Property(p => p.Age);
                person.Property(p => p.MyGuid);
                person.Property(p => p.Name);
                person.EnumProperty(p => p.FavoriteColor);
                person.ComplexProperty <FormatterOrder>(p => p.Order);

                var order = model.ComplexType <FormatterOrder>();
                order.Property(o => o.OrderAmount);
                order.Property(o => o.OrderName);

                // Add a top level function without parameter and the "IncludeInServiceDocument = true"
                var getPerson = model.Function("GetPerson");
                getPerson.ReturnsFromEntitySet <FormatterPerson>("People");
                getPerson.IncludeInServiceDocument = true;

                // Add a top level function without parameter and the "IncludeInServiceDocument = false"
                var getAddress = model.Function("GetAddress");
                getAddress.Returns <string>();
                getAddress.IncludeInServiceDocument = false;

                // Add an overload top level function with parameters and the "IncludeInServiceDocument = true"
                getPerson = model.Function("GetPerson");
                getPerson.Parameter <int>("PerId");
                getPerson.ReturnsFromEntitySet <FormatterPerson>("People");
                getPerson.IncludeInServiceDocument = true;

                // Add an overload top level function with parameters and the "IncludeInServiceDocument = false"
                getAddress = model.Function("GetAddress");
                getAddress.Parameter <int>("AddressId");
                getAddress.Returns <string>();
                getAddress.IncludeInServiceDocument = false;

                // Add an overload top level function
                var getVipPerson = model.Function("GetVipPerson");
                getVipPerson.Parameter <string>("name");
                getVipPerson.ReturnsFromEntitySet <FormatterPerson>("People");
                getVipPerson.IncludeInServiceDocument = true;

                // Add a top level function which is included in service document
                getVipPerson = model.Function("GetVipPerson");
                getVipPerson.ReturnsFromEntitySet <FormatterPerson>("People");
                getVipPerson.IncludeInServiceDocument = true;

                // Add an overload top level function
                getVipPerson = model.Function("GetVipPerson");
                getVipPerson.Parameter <int>("PerId");
                getVipPerson.Parameter <string>("name");
                getVipPerson.ReturnsFromEntitySet <FormatterPerson>("People");
                getVipPerson.IncludeInServiceDocument = true;

                // Add a top level function with parameters and without any overload
                var getSalary = model.Function("GetSalary");
                getSalary.Parameter <int>("PerId");
                getSalary.Parameter <string>("month");
                getSalary.Returns <int>();
                getSalary.IncludeInServiceDocument = true;

                // Add a function to test namespace configuration
                var getNSFunction = model.Function("GetNS");
                getNSFunction.Returns <int>();
                getNSFunction.Namespace = "CustomizeNamepace";

                // Add Singleton
                var president = model.Singleton <FormatterPerson>("President");
                president.HasIdLink(context =>
                {
                    return(new Uri(context.InternalUrlHelper.CreateODataLink(new SingletonSegment((IEdmSingleton)context.NavigationSource))));
                },
                                    followsConventions: false);

                _model = model.GetEdmModel();
            }

            return(_model);
        }
        public void Cant_SetFunctionTitle_OnNonBindableFunctions()
        {
            // Arrange
            ODataModelBuilder builder = new ODataModelBuilder();
            FunctionConfiguration function = builder.Function("MyFunction");
            function.Returns<int>();
            function.Title = "My Function";

            // Act
            IEdmModel model = builder.GetEdmModel();
            IEdmOperationImport functionImport = model.EntityContainer.OperationImports().OfType<IEdmFunctionImport>().Single();
            Assert.NotNull(functionImport);
            OperationTitleAnnotation functionTitleAnnotation = model.GetOperationTitleAnnotation(functionImport.Operation);

            // Assert
            Assert.Null(functionTitleAnnotation);
        }
 /// <summary>
 /// Applies model configurations using the provided builder for the specified API version.
 /// </summary>
 /// <param name="builder">The <see cref="ODataModelBuilder">builder</see> used to apply configurations.</param>
 /// <param name="apiVersion">The <see cref="ApiVersion">API version</see> associated with the <paramref name="builder"/>.</param>
 public void Apply(ODataModelBuilder builder, ApiVersion apiVersion)
 {
     builder.Function("GetSalesTaxRate").Returns <double>().Parameter <int>("PostalCode");
 }
        public void CanCreateFunctionWithReturnTypeAsNullableByOptionalReturn()
        {
            // Arrange & Act
            ODataModelBuilder builder = new ODataModelBuilder();
            FunctionConfiguration function = builder.Function("MyFunction").Returns<Address>();
            function.OptionalReturn = false;

            // Assert
            Assert.False(function.OptionalReturn);
        }
        public void CanCreateFunctionWithNonbindingParameters_AddParameterNonGenericMethod()
        {
            // Arrange
            // Act
            ODataModelBuilder builder = new ODataModelBuilder();
            FunctionConfiguration function = builder.Function("MyFunction");
            function.Parameter(typeof(string), "p0");
            function.Parameter(typeof(int), "p1");
            function.Parameter(typeof(Address), "p2");
            ParameterConfiguration[] parameters = function.Parameters.ToArray();

            // Assert
            Assert.Equal(3, parameters.Length);
            Assert.Equal("p0", parameters[0].Name);
            Assert.Equal("Edm.String", parameters[0].TypeConfiguration.FullName);
            Assert.Equal("p1", parameters[1].Name);
            Assert.Equal("Edm.Int32", parameters[1].TypeConfiguration.FullName);
            Assert.Equal("p2", parameters[2].Name);
            Assert.Equal(typeof(Address).FullName, parameters[2].TypeConfiguration.FullName);
        }
        public void CanCreateEdmModel_WithNonBindableFunction()
        {
            // Arrange
            ODataModelBuilder builder = new ODataModelBuilder();

            // Act
            FunctionConfiguration functionConfiguration = builder.Function("FunctionName");
            functionConfiguration.ReturnsFromEntitySet<Customer>("Customers");

            IEdmModel model = builder.GetEdmModel();

            // Assert
            IEdmEntityContainer container = model.EntityContainers().SingleOrDefault();
            Assert.NotNull(container);
            Assert.Equal(1, container.Elements.OfType<IEdmFunctionImport>().Count());
            Assert.Equal(1, container.Elements.OfType<IEdmEntitySet>().Count());
            IEdmFunctionImport functionImport = container.Elements.OfType<IEdmFunctionImport>().Single();
            IEdmFunction function = functionImport.Function;
            Assert.False(function.IsComposable);
            Assert.False(function.IsBound);
            Assert.False(model.IsAlwaysBindable(function));
            Assert.Equal("FunctionName", function.Name);
            Assert.NotNull(function.ReturnType);
            Assert.NotNull(functionImport.EntitySet);
            Assert.Equal("Customers", (functionImport.EntitySet as IEdmEntitySetReferenceExpression).ReferencedEntitySet.Name);
            Assert.Equal(typeof(Customer).FullName, (functionImport.EntitySet as IEdmEntitySetReferenceExpression).ReferencedEntitySet.ElementType.FullName());
            Assert.Empty(function.Parameters);
        }
        public void CanCreateFunctionWithNonbindingParameters()
        {
            // Arrange
            // Act
            ODataModelBuilder builder = new ODataModelBuilder();
            FunctionConfiguration function = builder.Function("MyFunction");
            function.Parameter<string>("p0");
            function.Parameter<int>("p1");
            function.Parameter<Address>("p2");
            function.CollectionParameter<string>("p3");
            function.CollectionParameter<int>("p4");
            function.CollectionParameter<ZipCode>("p5");
            ParameterConfiguration[] parameters = function.Parameters.ToArray();
            ComplexTypeConfiguration[] complexTypes = builder.StructuralTypes.OfType<ComplexTypeConfiguration>().ToArray();

            // Assert
            Assert.Equal(2, complexTypes.Length);
            Assert.Equal(typeof(Address).FullName, complexTypes[0].FullName);
            Assert.Equal(typeof(ZipCode).FullName, complexTypes[1].FullName);
            Assert.Equal(6, parameters.Length);
            Assert.Equal("p0", parameters[0].Name);
            Assert.Equal("Edm.String", parameters[0].TypeConfiguration.FullName);
            Assert.Equal("p1", parameters[1].Name);
            Assert.Equal("Edm.Int32", parameters[1].TypeConfiguration.FullName);
            Assert.Equal("p2", parameters[2].Name);
            Assert.Equal(typeof(Address).FullName, parameters[2].TypeConfiguration.FullName);
            Assert.Equal("p3", parameters[3].Name);
            Assert.Equal("Collection(Edm.String)", parameters[3].TypeConfiguration.FullName);
            Assert.Equal("p4", parameters[4].Name);
            Assert.Equal("Collection(Edm.Int32)", parameters[4].TypeConfiguration.FullName);
            Assert.Equal("p5", parameters[5].Name);
            Assert.Equal(string.Format("Collection({0})", typeof(ZipCode).FullName), parameters[5].TypeConfiguration.FullName);
        }
        public void CanCreateFunctionWithEntityReturnType()
        {
            // Arrange
            // Act
            ODataModelBuilder builder = new ODataModelBuilder();

            FunctionConfiguration createGoodCustomer = builder.Function("CreateGoodCustomer").ReturnsFromEntitySet<Customer>("GoodCustomers");
            FunctionConfiguration createBadCustomers = builder.Function("CreateBadCustomers").ReturnsCollectionFromEntitySet<Customer>("BadCustomers");

            // Assert
            EntityTypeConfiguration customer = createGoodCustomer.ReturnType as EntityTypeConfiguration;
            Assert.NotNull(customer);
            Assert.Equal(typeof(Customer).FullName, customer.FullName);
            EntitySetConfiguration goodCustomers = builder.EntitySets.SingleOrDefault(s => s.Name == "GoodCustomers");
            Assert.NotNull(goodCustomers);
            Assert.Same(createGoodCustomer.EntitySet, goodCustomers);

            CollectionTypeConfiguration customers = createBadCustomers.ReturnType as CollectionTypeConfiguration;
            Assert.NotNull(customers);
            customer = customers.ElementType as EntityTypeConfiguration;
            Assert.NotNull(customer);
            EntitySetConfiguration badCustomers = builder.EntitySets.SingleOrDefault(s => s.Name == "BadCustomers");
            Assert.NotNull(badCustomers);
            Assert.Same(createBadCustomers.EntitySet, badCustomers);
        }
        public void CanCreateFunctionWithNonbindingParametersAsNullable()
        {
            // Arrange & Act
            ODataModelBuilder builder = new ODataModelBuilder();
            FunctionConfiguration function = builder.Function("MyFunction");
            function.Parameter<string>("p0");
            function.Parameter<string>("p1").OptionalParameter = false;
            function.Parameter<int>("p2").OptionalParameter = true;
            function.Parameter<int>("p3");
            function.Parameter<Address>("p4");
            function.Parameter<Address>("p5").OptionalParameter = false;

            function.CollectionParameter<ZipCode>("p6");
            function.CollectionParameter<ZipCode>("p7").OptionalParameter = false;

            Dictionary<string, ParameterConfiguration> parameters = function.Parameters.ToDictionary(e => e.Name, e => e);

            // Assert
            Assert.True(parameters["p0"].OptionalParameter);
            Assert.False(parameters["p1"].OptionalParameter);

            Assert.True(parameters["p2"].OptionalParameter);
            Assert.False(parameters["p3"].OptionalParameter);

            Assert.True(parameters["p4"].OptionalParameter);
            Assert.False(parameters["p5"].OptionalParameter);

            Assert.True(parameters["p6"].OptionalParameter);
            Assert.False(parameters["p7"].OptionalParameter);
        }
        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 HasFeedFunctionLink_ThrowsException_OnNonBindableFunctions()
        {
            // Arrange
            ODataModelBuilder builder = new ODataModelBuilder();
            FunctionConfiguration function = builder.Function("NoBindableFunction");

            // Act & Assert
            Assert.Throws<InvalidOperationException>(
                () => function.HasFeedFunctionLink(ctx => new Uri("http://any"), followsConventions: false),
                "To register a function link factory, functions must be bindable to the collection of entity. " +
                "Function 'NoBindableFunction' does not meet this requirement.");
        }
        public void CanCreateFunctionWithComplexReturnType()
        {
            // Arrange
            // Act
            ODataModelBuilder builder = new ODataModelBuilder();

            FunctionConfiguration createAddress = builder.Function("CreateAddress").Returns<Address>();
            FunctionConfiguration createAddresses = builder.Function("CreateAddresses").ReturnsCollection<Address>();

            // Assert
            ComplexTypeConfiguration address = createAddress.ReturnType as ComplexTypeConfiguration;
            Assert.NotNull(address);
            Assert.Equal(typeof(Address).FullName, address.FullName);
            Assert.Null(createAddress.EntitySet);

            CollectionTypeConfiguration addresses = createAddresses.ReturnType as CollectionTypeConfiguration;
            Assert.NotNull(addresses);
            Assert.Equal(string.Format("Collection({0})", typeof(Address).FullName), addresses.FullName);
            address = addresses.ElementType as ComplexTypeConfiguration;
            Assert.NotNull(address);
            Assert.Equal(typeof(Address).FullName, address.FullName);
            Assert.Null(createAddresses.EntitySet);
        }
        public static IEdmModel GetEdmModel()
        {
            if (_model == null)
            {
                ODataModelBuilder model = new ODataModelBuilder();

                var color = model.EnumType<Color>();
                color.Member(Color.Red);
                color.Member(Color.Green);
                color.Member(Color.Blue);

                var people = model.EntitySet<FormatterPerson>("People");
                people.HasFeedSelfLink(context => new Uri(context.Url.CreateODataLink(new EntitySetPathSegment(
                    context.EntitySet))));
                people.HasIdLink(context =>
                    {
                        return context.Url.CreateODataLink(
                            new EntitySetPathSegment(context.EntitySet),
                            new KeyValuePathSegment(context.GetPropertyValue("PerId").ToString()));
                    },
                    followsConventions: false);

                var person = people.EntityType;
                person.HasKey(p => p.PerId);
                person.Property(p => p.Age);
                person.Property(p => p.MyGuid);
                person.Property(p => p.Name);
                person.EnumProperty(p => p.FavoriteColor);
                person.ComplexProperty<FormatterOrder>(p => p.Order);

                var order = model.ComplexType<FormatterOrder>();
                order.Property(o => o.OrderAmount);
                order.Property(o => o.OrderName);

                // Add a top level function 
                var getPersons = model.Function("GetPerson");
                getPersons.Parameter<Int32>("PerId");
                getPersons.ReturnsFromEntitySet<FormatterPerson>("People");

                // Add a top level function which is not included in service document
                var getVipPerson = model.Function("GetVipPerson");
                getVipPerson.ReturnsFromEntitySet<FormatterPerson>("People");
                getVipPerson.IncludeInServiceDocument = false;

                _model = model.GetEdmModel();
            }

            return _model;
        }
        public void GetEdmModel_CreatesOperationImports_For_UnboundedOperations()
        {
            // Arrange
            ODataModelBuilder builder = new ODataModelBuilder();
            builder.Function("Function").Returns<bool>();
            builder.Action("Action").Returns<bool>();

            // Act
            IEdmModel model = builder.GetEdmModel();

            // Assert
            Assert.Equal(2, model.EntityContainer.OperationImports().Count());
        }