Beispiel #1
0
        /// <summary>
        /// Initializes a new instance of the <see cref="EdmActionImport"/> class.
        /// </summary>
        /// <param name="container">The container.</param>
        /// <param name="name">The name.</param>
        /// <param name="action">The action.</param>
        /// <param name="entitySetExpression">The entity set expression.</param>
        public EdmActionImport(IEdmEntityContainer container, string name, IEdmAction action, IEdmExpression entitySetExpression)
            : base(container, action, name, entitySetExpression)
        {
            EdmUtil.CheckArgumentNull(action, "action");

            this.Action = action;
        }
        public static void SetActionLinkBuilder(this IEdmModel model, IEdmAction action, ActionLinkBuilder actionLinkBuilder)
        {
            if (model == null)
            {
                throw Error.ArgumentNull("model");
            }

            model.SetAnnotationValue(action, actionLinkBuilder);
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="BoundActionPathSegment" /> class.
        /// </summary>
        /// <param name="action">The action being invoked.</param>
        public BoundActionPathSegment(IEdmAction action)
        {
            if (action == null)
            {
                throw Error.ArgumentNull("action");
            }

            Action = action;
            ActionName = Action.FullName();
        }
        internal BoundActionPathSegment(IEdmAction action, IEdmModel model)
        {
            if (action == null)
            {
                throw Error.ArgumentNull("action");
            }

            Action = action;
            ActionName = Action.FullName();
            _edmModel = model;
        }
        // Determine action from readContext
        // This function is copied from default ODataActionPayloadDeserializer because it cannot be inherited
        private static IEdmAction GetAction(ODataDeserializerContext readContext)
        {
            if (readContext == null)
            {
                throw new ArgumentNullException(nameof(readContext));
            }

            ODataPath path = readContext.Path;

            if (path == null || path.Segments.Count == 0)
            {
                throw new SerializationException("OData Path is missing");
            }

            IEdmAction action = null;

            if (path.PathTemplate == "~/unboundaction")
            {
                // only one segment, it may be an unbound action
                OperationImportSegment unboundActionSegment = path.Segments.Last() as OperationImportSegment;
                if (unboundActionSegment != null)
                {
                    IEdmActionImport actionImport = unboundActionSegment.OperationImports.First() as IEdmActionImport;
                    if (actionImport != null)
                    {
                        action = actionImport.Action;
                    }
                }
            }
            else
            {
                // otherwise, it may be a bound action
                OperationSegment actionSegment = path.Segments.Last() as OperationSegment;
                if (actionSegment != null)
                {
                    action = actionSegment.Operations.First() as IEdmAction;
                }
            }

            if (action == null)
            {
                throw new SerializationException("Request is not an action invocation");
            }

            return(action);
        }
        public void GenerateActionLinkForFeed_GeneratesLinkWithDownCast_IfElementTypeDerivesFromBindingParameterType()
        {
            // Arrange
            var        request = RequestFactory.CreateFromModel(_model.Model);
            IEdmAction action  = _model.Model.SchemaElements.OfType <IEdmAction>().First(a => a.Name == "UpgradeAll");

            Assert.NotNull(action); // Guard
            IEdmEntitySet specialCustomers = new EdmEntitySet(_model.Container, "SpecialCustomers", _model.SpecialCustomer);

            var context = ResourceSetContextFactory.Create(specialCustomers, request);

            // Act
            Uri link = context.GenerateActionLink(action);

            // Assert
            Assert.Equal("http://localhost/SpecialCustomers/NS.Customer/NS.UpgradeAll", link.AbsoluteUri);
        }
Beispiel #7
0
        internal static bool ShouldOmitAction(IEdmAction action, ActionLinkBuilder builder,
                                              ODataMetadataLevel metadataLevel)
        {
            Contract.Assert(builder != null);

            switch (metadataLevel)
            {
            case ODataMetadataLevel.MinimalMetadata:
            case ODataMetadataLevel.NoMetadata:
                return(action.IsBound && builder.FollowsConventions);

            case ODataMetadataLevel.Default:
            case ODataMetadataLevel.FullMetadata:
            default:     // All values already specified; just keeping the compiler happy.
                return(false);
            }
        }
Beispiel #8
0
        public void GenerateActionLinkForFeed_GeneratesLinkWithCast_IfEntitySetTypeDoesnotMatchActionEntityType()
        {
            // Arrange
            var        request = RequestFactory.Create(_model);
            IEdmAction action  = _model.SchemaElements.OfType <IEdmAction>().First(a => a.Name == "UpgradeSpecialAll");

            Assert.NotNull(action); // Guard
            ResourceSetContext context = new ResourceSetContext {
                EntitySetBase = _customers, Request = request
            };

            // Act
            Uri link = context.GenerateActionLink(action);

            // Assert
            Assert.Equal("http://localhost/Customers/NS.SpecialCustomer/NS.UpgradeSpecialAll", link.AbsoluteUri);
        }
Beispiel #9
0
        public void GenerateActionLink_GeneratesLinkWithCast_IfEntitySetTypeDoesnotMatchActionEntityType_ForSingleton()
        {
            // Arrange
            IEdmSingleton mary              = new EdmSingleton(_model.EntityContainer, "Mary", _customer);
            var           request           = RequestFactory.Create(_model);
            var           serializerContext = ODataSerializerContextFactory.Create(_model, mary, request);
            var           entityContext     = new ResourceContext(serializerContext, _specialCustomer.AsReference(), new { ID = 42 });
            IEdmAction    specialUpgrade    = _model.SchemaElements.OfType <IEdmAction>().FirstOrDefault(c => c.Name == "specialUpgrade");

            Assert.NotNull(specialUpgrade);

            // Act
            Uri link = entityContext.GenerateActionLink(specialUpgrade);

            // Assert
            Assert.Equal("http://localhost/Mary/NS.SpecialCustomer/NS.specialUpgrade", link.AbsoluteUri);
        }
Beispiel #10
0
        private void AddOperations(HashSet <IEdmAction> allActions, HashSet <IEdmFunction> allFunctions, OperationSegment operationSegment)
        {
            foreach (IEdmOperation operation in operationSegment.Operations)
            {
                IEdmAction action = operation as IEdmAction;
                if (action != null && allActions.Contains(action))
                {
                    SelectedActions.Add(action);
                }

                IEdmFunction function = operation as IEdmFunction;
                if (function != null && allFunctions.Contains(function))
                {
                    SelectedFunctions.Add(function);
                }
            }
        }
Beispiel #11
0
        public void GenerateActionLink_GeneratesLinkWithDownCast_IfElementTypeDerivesFromBindingParameterType_ForSingleton()
        {
            // Arrange
            IEdmSingleton me                = new EdmSingleton(_model.EntityContainer, "Me", _specialCustomer);
            var           request           = RequestFactory.Create(_model);
            var           serializerContext = ODataSerializerContextFactory.Create(_model, me, request);
            var           entityContext     = new ResourceContext(serializerContext, _specialCustomer.AsReference(), new { ID = 42 });
            IEdmAction    upgradeCustomer   = _model.SchemaElements.OfType <IEdmAction>().FirstOrDefault(c => c.Name == "upgrade");

            Assert.NotNull(upgradeCustomer);

            // Act
            Uri link = entityContext.GenerateActionLink(upgradeCustomer);

            // Assert
            Assert.Equal("http://localhost/Me/NS.Customer/NS.upgrade", link.AbsoluteUri);
        }
Beispiel #12
0
        private static void AddOperationLinkBuilder(IEdmModel model, IEdmOperation operation, OperationConfiguration operationConfiguration)
        {
            Contract.Assert(model != null);
            ActionConfiguration   actionConfiguration = operationConfiguration as ActionConfiguration;
            IEdmAction            action = operation as IEdmAction;
            FunctionConfiguration functionConfiguration = operationConfiguration as FunctionConfiguration;
            IEdmFunction          function = operation as IEdmFunction;

            if (operationConfiguration.BindingParameter.TypeConfiguration.Kind == EdmTypeKind.Entity)
            {
                //if (actionConfiguration != null && actionConfiguration.GetActionLink() != null && action != null)
                //{
                //    model.SetOperationLinkBuilder(
                //        action,
                //        new OperationLinkBuilder(actionConfiguration.GetActionLink(), actionConfiguration.FollowsConventions));
                //}
                //else if (functionConfiguration != null && functionConfiguration.GetFunctionLink() != null && function != null)
                //{
                //    model.SetOperationLinkBuilder(
                //        function,
                //        new OperationLinkBuilder(functionConfiguration.GetFunctionLink(), functionConfiguration.FollowsConventions));
                //}
            }
            else if (operationConfiguration.BindingParameter.TypeConfiguration.Kind == EdmTypeKind.Collection)
            {
                CollectionTypeConfiguration collectionTypeConfiguration =
                    (CollectionTypeConfiguration)operationConfiguration.BindingParameter.TypeConfiguration;

                if (collectionTypeConfiguration.ElementType.Kind == EdmTypeKind.Entity)
                {
                    //if (actionConfiguration != null && actionConfiguration.GetFeedActionLink() != null && action != null)
                    //{
                    //    model.SetOperationLinkBuilder(
                    //        action,
                    //        new OperationLinkBuilder(actionConfiguration.GetFeedActionLink(), actionConfiguration.FollowsConventions));
                    //}
                    //else if (functionConfiguration != null && functionConfiguration.GetFeedFunctionLink() != null && function != null)
                    //{
                    //    model.SetOperationLinkBuilder(
                    //        function,
                    //        new OperationLinkBuilder(functionConfiguration.GetFeedFunctionLink(), functionConfiguration.FollowsConventions));
                    //}
                }
            }
        }
        public async Task Can_DeserializePayload_WithPrimitiveCollectionParameters(string actionName, IEdmAction expectedAction, ODataPath path)
        {
            // Arrange
            const string Body =
                @"{ ""Name"": ""Avatar"", ""Ratings"": [ 5, 5, 3, 4, 5, 5, 4, 5, 5, 4 ], ""Time"": [""01:02:03.0040000"", ""12:13:14.1150000""], ""Colors"": [ ""Red"", null, ""Green""] }";

            int[] expectedRatings = new int[] { 5, 5, 3, 4, 5, 5, 4, 5, 5, 4 };

            ODataMessageWrapper message = new ODataMessageWrapper(await GetStringAsStreamAsync(Body));

            message.SetHeader("Content-Type", "application/json");
            ODataMessageReader reader = new ODataMessageReader(message as IODataRequestMessage, new ODataMessageReaderSettings(), _model);

            ODataDeserializerContext context = new ODataDeserializerContext {
                Path = path, Model = _model
            };

            // Act
            ODataActionParameters payload = await _deserializer.ReadAsync(reader, typeof(ODataActionParameters), context) as ODataActionParameters;

            IEdmAction action = ODataActionPayloadDeserializer.GetAction(context);

            // Assert
            Assert.NotNull(actionName);
            Assert.NotNull(payload);
            Assert.Same(expectedAction, action);
            Assert.True(payload.ContainsKey("Name"));
            Assert.Equal("Avatar", payload["Name"]);
            Assert.True(payload.ContainsKey("Ratings"));
            IEnumerable <int> ratings = payload["Ratings"] as IEnumerable <int>;

            Assert.Equal(10, ratings.Count());
            Assert.True(expectedRatings.Zip(ratings, (expected, actual) => expected - actual).All(diff => diff == 0));

            Assert.True(payload.ContainsKey("Time"));
            IEnumerable <TimeOfDay> times = payload["Time"] as IEnumerable <TimeOfDay>;

            Assert.Equal(2, times.Count());
            Assert.Equal(new[] { new TimeOfDay(1, 2, 3, 4), new TimeOfDay(12, 13, 14, 115) }, times.ToList());

            Assert.True(payload.ContainsKey("Colors"));
            IEnumerable <AColor?> colors = payload["Colors"] as IEnumerable <AColor?>;

            Assert.Equal("Red|null|Green", String.Join("|", colors.Select(e => e == null ? "null" : e.ToString())));
        }
Beispiel #14
0
        public void Can_Find_Customized_Namespace_Action(string url)
        {
            // Arrange
            IEdmModel model = GetModel();
            ODataPath path  = new DefaultODataPathHandler().Parse(model, _serviceRoot, url);

            Assert.NotNull(path); // Guard
            ODataDeserializerContext context = new ODataDeserializerContext {
                Path = path, Model = model
            };

            // Act
            IEdmAction action = ODataActionPayloadDeserializer.GetAction(context);

            // Assert
            Assert.NotNull(action);
            Assert.Equal("NSAction", action.Name);
        }
Beispiel #15
0
        public void Can_find_action_overload_using_bindingparameter_type(string url)
        {
            // Arrange
            IEdmModel model = GetModel();
            ODataPath path  = new DefaultODataPathHandler().Parse(model, _serviceRoot, url);

            Assert.NotNull(path); // Guard
            ODataDeserializerContext context = new ODataDeserializerContext {
                Path = path, Model = model
            };

            // Act
            IEdmAction action = ODataActionPayloadDeserializer.GetAction(context);

            // Assert
            Assert.NotNull(action);
            Assert.Equal("Wash", action.Name);
        }
Beispiel #16
0
        public void CanCreateEdmModel_WithTransientBindableAction()
        {
            // Arrange
            ODataModelBuilder builder = new ODataModelBuilder();
            EntityTypeConfiguration <Customer> customer = builder.EntityType <Customer>();

            customer.HasKey(c => c.CustomerId);
            customer.Property(c => c.Name);

            // Act
            ActionConfiguration sendEmail = customer.TransientAction("ActionName");
            IEdmModel           model     = builder.GetEdmModel();

            // Assert
            IEdmAction action = Assert.Single(model.SchemaElements.OfType <IEdmAction>());

            Assert.True(action.IsBound);
        }
        public void Throws_ODataException_When_Parameter_Notfound(string actionName, IEdmAction expectedAction, ODataPath path)
        {
            // Arrange
            const string        Body    = @"{ ""Quantity"": 1 , ""ProductCode"": ""PCode"", ""MissingParameter"": 1 }";
            ODataMessageWrapper message = new ODataMessageWrapper(GetStringAsStream(Body));

            message.SetHeader("Content-Type", "application/json");
            ODataMessageReader       reader  = new ODataMessageReader(message as IODataRequestMessage, new ODataMessageReaderSettings(), _model);
            ODataDeserializerContext context = new ODataDeserializerContext {
                Path = path, Model = _model
            };

            // Act & Assert
            Assert.Throws <ODataException>(() =>
            {
                ODataActionParameters payload = _deserializer.Read(reader, typeof(ODataActionParameters), context) as ODataActionParameters;
            }, "The parameter 'MissingParameter' in the request payload is not a valid parameter for the operation '" + actionName + "'.");
        }
Beispiel #18
0
        public void UnboundAction_ForEnumWithShortUnderlyingTypeInODataConventionModelBuilder()
        {
            // Arrange
            ODataConventionModelBuilder builder             = new ODataConventionModelBuilder();
            ActionConfiguration         actionConfiguration = builder.Action("UnboundAction");

            actionConfiguration.Returns <ShortEnum>();

            // Act & Assert
            IEdmModel  model  = builder.GetEdmModel();
            IEdmAction action = model.FindDeclaredOperations("Default.UnboundAction").Single() as IEdmAction;

            IEdmTypeReference returnType    = action.ReturnType;
            IEdmEnumType      shortEnumType = model.SchemaElements.OfType <IEdmEnumType>().Single(e => e.Name == "ShortEnum");

            Assert.Same(shortEnumType, returnType.Definition);
            Assert.Equal(EdmPrimitiveTypeKind.Int16, returnType.AsEnum().EnumDefinition().UnderlyingType.PrimitiveKind);
        }
Beispiel #19
0
        private static void AddProcedureLinkBuilder(IEdmModel model, IEdmOperation operation, ProcedureConfiguration procedure)
        {
            ActionConfiguration   actionConfiguration = procedure as ActionConfiguration;
            IEdmAction            action = operation as IEdmAction;
            FunctionConfiguration functionConfiguration = procedure as FunctionConfiguration;
            IEdmFunction          function = operation as IEdmFunction;

            if (procedure.BindingParameter.TypeConfiguration.Kind == EdmTypeKind.Entity)
            {
                if (actionConfiguration != null && actionConfiguration.GetActionLink() != null && action != null)
                {
                    model.SetActionLinkBuilder(
                        action,
                        new ActionLinkBuilder(actionConfiguration.GetActionLink(), actionConfiguration.FollowsConventions));
                }
                else if (functionConfiguration != null && functionConfiguration.GetFunctionLink() != null && function != null)
                {
                    model.SetFunctionLinkBuilder(
                        function,
                        new FunctionLinkBuilder(functionConfiguration.GetFunctionLink(), functionConfiguration.FollowsConventions));
                }
            }
            else if (procedure.BindingParameter.TypeConfiguration.Kind == EdmTypeKind.Collection)
            {
                CollectionTypeConfiguration collectionTypeConfiguration =
                    (CollectionTypeConfiguration)procedure.BindingParameter.TypeConfiguration;

                if (collectionTypeConfiguration.ElementType.Kind == EdmTypeKind.Entity)
                {
                    if (actionConfiguration != null && actionConfiguration.GetFeedActionLink() != null && action != null)
                    {
                        model.SetActionLinkBuilder(
                            action,
                            new ActionLinkBuilder(actionConfiguration.GetFeedActionLink(), actionConfiguration.FollowsConventions));
                    }
                    else if (functionConfiguration != null && functionConfiguration.GetFeedFunctionLink() != null && function != null)
                    {
                        model.SetFunctionLinkBuilder(
                            function,
                            new FunctionLinkBuilder(functionConfiguration.GetFeedFunctionLink(), functionConfiguration.FollowsConventions));
                    }
                }
            }
        }
        public async Task Can_DeserializePayload_WithPrimitiveParameters(string actionName, IEdmAction expectedAction, ODataPath path)
        {
            // Arrange
            const int    Quantity    = 1;
            const string ProductCode = "PCode";
            string       body        = "{" +
                                       string.Format(@" ""Quantity"": {0} , ""ProductCode"": ""{1}"" , ""Birthday"": ""2015-02-27"", ""BkgColor"": ""Red"", ""InnerColor"": null", Quantity, ProductCode) +
                                       "}";

            ODataMessageWrapper message = new ODataMessageWrapper(await GetStringAsStreamAsync(body));

            message.SetHeader("Content-Type", "application/json");
            ODataMessageReader       reader  = new ODataMessageReader(message as IODataRequestMessage, new ODataMessageReaderSettings(), _model);
            ODataDeserializerContext context = new ODataDeserializerContext()
            {
                Path = path, Model = _model
            };

            // Act
            ODataActionParameters payload = await _deserializer.ReadAsync(reader, typeof(ODataActionParameters), context) as ODataActionParameters;

            IEdmAction action = ODataActionPayloadDeserializer.GetAction(context);

            // Assert
            Assert.NotNull(actionName);
            Assert.Same(expectedAction, action);
            Assert.NotNull(payload);
            Assert.True(payload.ContainsKey("Quantity"));
            Assert.Equal(Quantity, payload["Quantity"]);
            Assert.True(payload.ContainsKey("ProductCode"));
            Assert.Equal(ProductCode, payload["ProductCode"]);

            Assert.True(payload.ContainsKey("Birthday"));
            Assert.Equal(new Date(2015, 2, 27), payload["Birthday"]);

            Assert.True(payload.ContainsKey("BkgColor"));
            AColor bkgColor = Assert.IsType <AColor>(payload["BkgColor"]);

            Assert.Equal(AColor.Red, bkgColor);

            Assert.True(payload.ContainsKey("InnerColor"));
            Assert.Null(payload["InnerColor"]);
        }
 /// <summary>
 /// Action payloads are not Edm types, so they cannot be translated like resources are translated.
 /// To translate the action payload, we walk through each property and compare it to its parameter.  For any properties
 /// that are V3 compatible only, we translate them.  If they are not simple values (e.g., entities or collections), we can
 /// translate them using the same method used for translating resources.
 /// </summary>
 /// <param name="payload">Request body as JSON</param>
 /// <param name="action">Matching OData action information</param>
 private static void TranslateActionPayload(JToken payload, IEdmAction action)
 {
     foreach (JProperty child in payload.Children <JProperty>().ToList())
     {
         string parameterName             = child.Name;
         IEdmOperationParameter parameter = action.Parameters.SingleOrDefault(p => p.Name == parameterName);
         if (parameter.Type.TypeKind() == EdmTypeKind.Primitive &&
             ((IEdmPrimitiveType)parameter.Type.Definition).PrimitiveKind == EdmPrimitiveTypeKind.Int64)
         {
             // Translate top level properties
             payload[parameterName] = Convert.ToInt64(payload[parameterName]);
         }
         else if (parameter.Type.TypeKind() == EdmTypeKind.Entity || parameter.Type.TypeKind() == EdmTypeKind.Collection)
         {
             // Translate nested resources and collections
             payload[parameterName].WalkTranslate(parameter.Type);
         }
     }
 }
        public override async Task <object> ReadAsync(ODataMessageReader messageReader, Type type, ODataDeserializerContext readContext)
        {
            if (messageReader == null)
            {
                throw Error.ArgumentNull("messageReader");
            }

            IEdmAction action = GetAction(readContext);

            Contract.Assert(action != null);

            // Create the correct resource type;
            Dictionary <string, object> payload = GetPayload(type, action);

            ODataParameterReader reader = await messageReader.CreateODataParameterReaderAsync(action);

            while (await reader.ReadAsync())
            {
                switch (reader.State)
                {
                case ODataParameterReaderState.Value:
                    ReadValue(action, reader, readContext, DeserializerProvider, payload);
                    break;

                case ODataParameterReaderState.Collection:
                    await ReadCollectionAsync(action, reader, readContext, DeserializerProvider, payload);

                    break;

                case ODataParameterReaderState.Resource:
                    await ReadResourceAsync(action, reader, readContext, DeserializerProvider, payload);

                    break;

                case ODataParameterReaderState.ResourceSet:
                    await ReadResourceSetAsync(action, reader, readContext, DeserializerProvider, payload);

                    break;
                }
            }

            return(payload);
        }
Beispiel #23
0
        /// <summary>
        /// Translate a OperationSegment
        /// </summary>
        /// <param name="segment">the segment to Translate</param>
        /// <returns>Translated WebApi path segment.</returns>
        public override IEnumerable <ODataPathSegment> Translate(OperationSegment segment)
        {
            IEdmAction action = segment.Operations.Single() as IEdmAction;

            if (action != null)
            {
                yield return(new BoundActionPathSegment(action, _model));
            }
            else
            {
                // Translate the nodes in ODL path to string literals as parameter of BoundFunctionPathSegment.
                Dictionary <string, string> parameterValues = segment.Parameters.ToDictionary(
                    parameterValue => parameterValue.Name,
                    parameterValue => TranslateNode(parameterValue.Value));
                IEdmFunction function = (IEdmFunction)segment.Operations.Single();

                yield return(new BoundFunctionPathSegment(function, _model, parameterValues));
            }
        }
        internal static IEdmAction GetAction(ODataDeserializerContext readContext)
        {
            if (readContext == null)
            {
                throw Error.ArgumentNull("readContext");
            }

            ODataPath path = readContext.Path;

            if (path == null || path.Segments.Count == 0)
            {
                throw new SerializationException(SRResources.ODataPathMissing);
            }

            IEdmAction action = null;

            if (path.PathTemplate == "~/unboundaction")
            {
                // only one segment, it may be an unbound action
                UnboundActionPathSegment unboundActionSegment = path.Segments.Last() as UnboundActionPathSegment;
                if (unboundActionSegment != null)
                {
                    action = unboundActionSegment.Action.Action;
                }
            }
            else
            {
                // otherwise, it may be a bound action
                BoundActionPathSegment actionSegment = path.Segments.Last() as BoundActionPathSegment;
                if (actionSegment != null)
                {
                    action = actionSegment.Action;
                }
            }

            if (action == null)
            {
                string message = Error.Format(SRResources.RequestNotActionInvocation, path.ToString());
                throw new SerializationException(message);
            }

            return(action);
        }
        public static ActionLinkBuilder GetActionLinkBuilder(this IEdmModel model, IEdmAction action)
        {
            if (model == null)
            {
                throw Error.ArgumentNull("model");
            }
            if (action == null)
            {
                throw Error.ArgumentNull("action");
            }

            ActionLinkBuilder actionLinkBuilder = model.GetAnnotationValue<ActionLinkBuilder>(action);
            if (actionLinkBuilder == null)
            {
                actionLinkBuilder = new ActionLinkBuilder(entityInstanceContext => entityInstanceContext.GenerateActionLink(action), followsConventions: true);
                model.SetActionLinkBuilder(action, actionLinkBuilder);
            }

            return actionLinkBuilder;
        }
Beispiel #26
0
        public void GenerateActionLinkForFeed_GeneratesLinkWithCast_IfEntitySetTypeDoesnotMatchActionEntityType()
        {
            // Arrange
            HttpRequestMessage request = GetODataRequest(_model.Model);
            IEdmAction         action  = _model.Model.SchemaElements.OfType <IEdmAction>().First(a => a.Name == "UpgradeSpecialAll");

            Assert.NotNull(action); // Guard
            var context = new FeedContext
            {
                Request       = request,
                EntitySetBase = _model.Customers,
                Url           = request.GetUrlHelper(),
            };

            // Act
            Uri link = context.GenerateActionLink(action);

            // Assert
            Assert.Equal("http://localhost/Customers/NS.SpecialCustomer/NS.UpgradeSpecialAll", link.AbsoluteUri);
        }
Beispiel #27
0
        /// <inheritdoc />
        public Type NewActionParameters(IServiceProvider services, IEdmAction action, ApiVersion apiVersion, string controllerName)
        {
            if (action == null)
            {
                throw new ArgumentNullException(nameof(action));
            }

            var paramTypes   = generatedActionParamsPerVersion.GetOrAdd(apiVersion, _ => new ConcurrentDictionary <EdmTypeKey, Type>());
            var fullTypeName = $"{controllerName}.{action.Namespace}.{controllerName}{action.Name}Parameters";
            var key          = new EdmTypeKey(fullTypeName, apiVersion);
            var type         = paramTypes.GetOrAdd(key, _ =>
            {
                var properties    = action.Parameters.Where(p => p.Name != "bindingParameter").Select(p => new ClassProperty(services, p, this));
                var signature     = new ClassSignature(fullTypeName, properties, apiVersion);
                var moduleBuilder = modules.GetOrAdd(apiVersion, CreateModuleForApiVersion);

                return(CreateTypeInfoFromSignature(moduleBuilder, signature));
            });

            return(type);
        }
        public static ActionLinkBuilder GetActionLinkBuilder(this IEdmModel model, IEdmAction action)
        {
            if (model == null)
            {
                throw Error.ArgumentNull("model");
            }
            if (action == null)
            {
                throw Error.ArgumentNull("action");
            }

            ActionLinkBuilder actionLinkBuilder = model.GetAnnotationValue <ActionLinkBuilder>(action);

            if (actionLinkBuilder == null)
            {
                actionLinkBuilder = new ActionLinkBuilder(entityInstanceContext => entityInstanceContext.GenerateActionLink(action), followsConventions: true);
                model.SetActionLinkBuilder(action, actionLinkBuilder);
            }

            return(actionLinkBuilder);
        }
Beispiel #29
0
        public virtual ODataAction CreateODataAction(IEdmAction action, EntityInstanceContext entityInstanceContext)
        {
            if (action == null)
            {
                throw Error.ArgumentNull("action");
            }

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

            IEdmModel         model   = entityInstanceContext.EdmModel;
            ActionLinkBuilder builder = model.GetActionLinkBuilder(action);

            if (builder == null)
            {
                return(null);
            }

            return(CreateODataOperation(action, builder, entityInstanceContext) as ODataAction);
        }
Beispiel #30
0
        public void BoundAction_ForEnumTypeInODataConventionModelBuilder()
        {
            // Arrange
            ODataConventionModelBuilder         builder = new ODataConventionModelBuilder();
            EntityTypeConfiguration <EnumModel> entityTypeConfiguration = builder.EntityType <EnumModel>();
            ActionConfiguration actionConfiguration = entityTypeConfiguration.Action("BoundAction");

            actionConfiguration.Parameter <Color>("Color");
            actionConfiguration.ReturnsCollection <Color>();

            // Act & Assert
            IEdmModel  model  = builder.GetEdmModel();
            IEdmAction action = model.FindDeclaredOperations("Default.BoundAction").Single() as IEdmAction;

            IEdmTypeReference color      = action.Parameters.Single(p => p.Name == "Color").Type;
            IEdmTypeReference returnType = action.ReturnType;
            IEdmEnumType      colorType  = model.SchemaElements.OfType <IEdmEnumType>().Single(e => e.Name == "Color");

            Assert.Same(colorType, color.Definition);
            Assert.True(returnType.IsCollection());
            Assert.Same(colorType, returnType.AsCollection().ElementType().Definition);
        }
Beispiel #31
0
        public void GenerateActionLinkForFeed_GeneratesLinkWithDownCast_IfElementTypeDerivesFromBindingParameterType()
        {
            // Arrange
            HttpRequestMessage request = GetODataRequest(_model.Model);
            IEdmAction         action  = _model.Model.SchemaElements.OfType <IEdmAction>().First(a => a.Name == "UpgradeAll");

            Assert.NotNull(action); // Guard
            IEdmEntitySet specialCustomers = new EdmEntitySet(_model.Container, "SpecialCustomers", _model.SpecialCustomer);

            var context = new FeedContext
            {
                Request       = request,
                EntitySetBase = specialCustomers,
                Url           = request.GetUrlHelper(),
            };

            // Act
            Uri link = context.GenerateActionLink(action);

            // Assert
            Assert.Equal("http://localhost/SpecialCustomers/NS.Customer/NS.UpgradeAll", link.AbsoluteUri);
        }
        public void Can_DeserializePayload_WithPrimitiveCollections_InUntypedMode(string actionName, IEdmAction expectedAction, ODataPath path)
        {
            // Arrange
            const string Body =
                @"{ ""Name"": ""Avatar"", ""Ratings"": [ 5, 5, 3, 4, 5, 5, 4, 5, 5, 4 ], ""Time"": [""01:02:03.0040000"", ""12:13:14.1150000""]}";

            int[] expectedRatings       = new int[] { 5, 5, 3, 4, 5, 5, 4, 5, 5, 4 };
            ODataMessageWrapper message = new ODataMessageWrapper(GetStringAsStream(Body));

            message.SetHeader("Content-Type", "application/json");

            ODataMessageReaderSettings settings = new ODataMessageReaderSettings();
            ODataMessageReader         reader   = new ODataMessageReader(message as IODataRequestMessage, settings, _model);
            ODataDeserializerContext   context  = new ODataDeserializerContext {
                Path = path, Model = _model, ResourceType = typeof(ODataUntypedActionParameters)
            };

            // Act
            ODataUntypedActionParameters payload = _deserializer.Read(reader, typeof(ODataUntypedActionParameters), context) as ODataUntypedActionParameters;
            IEdmAction action = ODataActionPayloadDeserializer.GetAction(context);

            //Assert
            Assert.NotNull(actionName);
            Assert.Same(expectedAction, action);
            Assert.NotNull(payload);
            Assert.True(payload.ContainsKey("Name"));
            Assert.Equal("Avatar", payload["Name"]);
            Assert.True(payload.ContainsKey("Ratings"));
            IEnumerable <int> ratings = payload["Ratings"] as IEnumerable <int>;

            Assert.Equal(10, ratings.Count());
            Assert.True(expectedRatings.Zip(ratings, (expected, actual) => expected - actual).All(diff => diff == 0));

            Assert.True(payload.ContainsKey("Time"));
            IEnumerable <TimeOfDay> times = payload["Time"] as IEnumerable <TimeOfDay>;

            Assert.Equal(2, times.Count());
            Assert.Equal(new[] { new TimeOfDay(1, 2, 3, 4), new TimeOfDay(12, 13, 14, 115) }, times.ToList());
        }
Beispiel #33
0
        public virtual ODataAction CreateODataAction(IEdmAction action, ResourceContext resourceContext)
        {
            if (action == null)
            {
                throw Error.ArgumentNull("action");
            }

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

            IEdmModel            model   = resourceContext.EdmModel;
            OperationLinkBuilder builder = model.GetOperationLinkBuilder(action);

            if (builder == null)
            {
                return(null);
            }

            return(CreateODataOperation(action, builder, resourceContext) as ODataAction);
        }
        public async Task Can_DeserializePayload_WithEntityCollectionParameters(IEdmAction expectedAction, ODataPath path)
        {
            // Arrange
            ODataMessageWrapper message = new ODataMessageWrapper(await GetStringAsStreamAsync(EntityCollectionPayload));

            message.SetHeader("Content-Type", "application/json");
            ODataMessageReader       reader  = new ODataMessageReader(message as IODataRequestMessage, new ODataMessageReaderSettings(), _model);
            ODataDeserializerContext context = new ODataDeserializerContext()
            {
                Path = path, Model = _model
            };

            // Act
            ODataActionParameters payload = await _deserializer.ReadAsync(reader, typeof(ODataActionParameters), context) as ODataActionParameters;

            IEdmAction action = ODataActionPayloadDeserializer.GetAction(context);

            // Assert
            Assert.Same(expectedAction, action);
            Assert.NotNull(payload);
            Assert.True(payload.ContainsKey("Id"));
            Assert.Equal(1, payload["Id"]);

            IList <Customer> customers = (payload["Customers"] as IEnumerable <Customer>).ToList();

            Assert.NotNull(customers);
            Assert.Equal(2, customers.Count);
            Customer customer = customers[0];

            Assert.NotNull(customer);
            Assert.Equal(109, customer.Id);
            Assert.Equal("Avatar", customer.Name);

            customer = customers[1];
            Assert.NotNull(customer);
            Assert.Equal(901, customer.Id);
            Assert.Equal("Robot", customer.Name);
        }
Beispiel #35
0
        public void WhenActionLinksNotManuallyConfigured_ConventionBasedBuilderUsesConventions()
        {
            // Arrange
            string            uriTemplate         = "http://server/Movies({0})/Default.Watch";
            Uri               expectedUri         = new Uri(string.Format(uriTemplate, 1));
            ODataModelBuilder builder             = new ODataConventionModelBuilder();
            EntityTypeConfiguration <Movie> movie = builder.EntitySet <Movie>("Movies").EntityType;
            ActionConfiguration             watch = movie.Action("Watch");
            IEdmModel model = builder.GetEdmModel();

            HttpRequestMessage request       = new HttpRequestMessage(HttpMethod.Get, "http://server/Movies");
            HttpConfiguration  configuration = new HttpConfiguration();
            string             routeName     = "Route";

            configuration.MapODataServiceRoute(routeName, null, model);
            request.SetConfiguration(configuration);
            request.ODataProperties().RouteName = routeName;
            UrlHelper urlHelper = new UrlHelper(request);

            // Act
            IEdmEntityType         movieType         = model.SchemaElements.OfType <IEdmEntityType>().SingleOrDefault();
            IEdmEntityContainer    container         = model.SchemaElements.OfType <IEdmEntityContainer>().SingleOrDefault();
            IEdmAction             watchAction       = Assert.Single(model.SchemaElements.OfType <IEdmAction>()); // Guard
            IEdmEntitySet          entitySet         = container.EntitySets().SingleOrDefault();
            ODataSerializerContext serializerContext = new ODataSerializerContext {
                Model = model, NavigationSource = entitySet, Url = urlHelper
            };

            EntityInstanceContext context = new EntityInstanceContext(serializerContext, movieType.AsReference(), new Movie {
                ID = 1, Name = "Avatar"
            });
            ActionLinkBuilder actionLinkBuilder = model.GetAnnotationValue <ActionLinkBuilder>(watchAction);

            //Assert
            Assert.Equal(expectedUri, watch.GetActionLink()(context));
            Assert.NotNull(actionLinkBuilder);
            Assert.Equal(expectedUri, actionLinkBuilder.BuildActionLink(context));
        }
        public static ActionLinkBuilder GetActionLinkBuilder(this IEdmModel model, IEdmAction action)
        {
            if (model == null)
            {
                throw Error.ArgumentNull("model");
            }
            if (action == null)
            {
                throw Error.ArgumentNull("action");
            }

            ActionLinkBuilder actionLinkBuilder = model.GetAnnotationValue<ActionLinkBuilder>(action);
            if (actionLinkBuilder == null)
            {
                // Let ODL to process the action link for entity
                if (action.Parameters != null)
                {
                    if (action.Parameters.First().Type.IsEntity())
                    {
                        actionLinkBuilder = new ActionLinkBuilder(
                            (EntityInstanceContext entityInstanceContext) =>
                                entityInstanceContext.GenerateActionLink(action),
                            followsConventions: true);
                    }
                    else if (action.Parameters.First().Type.IsCollection())
                    {
                        actionLinkBuilder =
                            new ActionLinkBuilder((FeedContext feedContext) => feedContext.GenerateActionLink(action),
                                followsConventions: true);
                    }
                }

                model.SetActionLinkBuilder(action, actionLinkBuilder);
            }

            return actionLinkBuilder;
        }
        public virtual ODataAction CreateODataAction(IEdmAction action, EntityInstanceContext entityInstanceContext)
        {
            if (action == null)
            {
                throw Error.ArgumentNull("action");
            }

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

            ODataMetadataLevel metadataLevel = entityInstanceContext.SerializerContext.MetadataLevel;
            IEdmModel model = entityInstanceContext.EdmModel;

            ActionLinkBuilder builder = model.GetActionLinkBuilder(action);

            if (builder == null)
            {
                return null;
            }

            if (ShouldOmitAction(action, builder, metadataLevel))
            {
                return null;
            }

            Uri target = builder.BuildActionLink(entityInstanceContext);

            if (target == null)
            {
                return null;
            }

            Uri baseUri = new Uri(entityInstanceContext.Url.CreateODataLink(new MetadataPathSegment()));
            Uri metadata = new Uri(baseUri, "#" + CreateMetadataFragment(action));

            ODataAction odataAction = new ODataAction
            {
                Metadata = metadata,
            };

            bool alwaysIncludeDetails = metadataLevel == ODataMetadataLevel.FullMetadata;

            // Always omit the title in minimal/no metadata modes.
            if (alwaysIncludeDetails)
            {
                EmitTitle(model, action, odataAction);
            }

            // Omit the target in minimal/no metadata modes unless it doesn't follow conventions.
            if (alwaysIncludeDetails || !builder.FollowsConventions)
            {
                odataAction.Target = target;
            }

            return odataAction;
        }
        public void Can_DeserializePayload_WithPrimitiveCollectionParameters(string actionName, IEdmAction expectedAction, ODataPath path)
        {
            // Arrange
            const string Body =
                @"{ ""Name"": ""Avatar"", ""Ratings"": [ 5, 5, 3, 4, 5, 5, 4, 5, 5, 4 ], ""Time"": [""01:02:03.0040000"", ""12:13:14.1150000""], ""Colors"": [ ""Red"", null, ""Green""] }";
            int[] expectedRatings = new int[] { 5, 5, 3, 4, 5, 5, 4, 5, 5, 4 };

            ODataMessageWrapper message = new ODataMessageWrapper(GetStringAsStream(Body));
            message.SetHeader("Content-Type", "application/json");
            ODataMessageReader reader = new ODataMessageReader(message as IODataRequestMessage, new ODataMessageReaderSettings(), _model);

            ODataDeserializerContext context = new ODataDeserializerContext { Path = path, Model = _model };

            // Act
            ODataActionParameters payload = _deserializer.Read(reader, typeof(ODataActionParameters), context) as ODataActionParameters;
            IEdmAction action = ODataActionPayloadDeserializer.GetAction(context);

            // Assert
            Assert.NotNull(payload);
            Assert.Same(expectedAction, action);
            Assert.True(payload.ContainsKey("Name"));
            Assert.Equal("Avatar", payload["Name"]);
            Assert.True(payload.ContainsKey("Ratings"));
            IEnumerable<int> ratings = payload["Ratings"] as IEnumerable<int>;
            Assert.Equal(10, ratings.Count());
            Assert.True(expectedRatings.Zip(ratings, (expected, actual) => expected - actual).All(diff => diff == 0));

            Assert.True(payload.ContainsKey("Time"));
            IEnumerable<TimeOfDay> times = payload["Time"] as IEnumerable<TimeOfDay>;
            Assert.Equal(2, times.Count());
            Assert.Equal(new[] {new TimeOfDay(1, 2, 3, 4), new TimeOfDay(12, 13, 14, 115) }, times.ToList());

            Assert.True(payload.ContainsKey("Colors"));
            IEnumerable<AColor?> colors = payload["Colors"] as IEnumerable<AColor?>;
            Assert.Equal("Red|null|Green", String.Join("|", colors.Select(e => e == null ? "null" : e.ToString())));
        }
 public CsdlSemanticsActionImport(CsdlSemanticsEntityContainer container, CsdlActionImport actionImport, IEdmAction backingAction)
     : base(container, actionImport, backingAction)
 {
 }
        /// <summary>
        /// Initializes a new <see cref="IEdmActionImport"/> instance.
        /// </summary>
        /// <param name="name">name of the service operation.</param>
        /// <param name="action">Action that the action import is importing into the container.</param>
        /// <param name="resultSet">EntitySet of the result expected from this operation.</param>
        /// <returns>An ActionImport</returns>
        public EdmActionImport AddActionImport(string name, IEdmAction action, IEdmEntitySet resultSet)
        {
            EdmActionImport actionImport = new EdmActionImport(this,
                name,
                action,
                resultSet == null ? null : new EdmEntitySetReferenceExpression(resultSet));

            this.AddOperationImport(name, actionImport);
            return actionImport;
        }
        public void Throws_ODataException_When_Parameter_Notfound(string actionName, IEdmAction expectedAction, ODataPath path)
        {
            // Arrange
            const string Body = @"{ ""Quantity"": 1 , ""ProductCode"": ""PCode"", ""MissingParameter"": 1 }";
            ODataMessageWrapper message = new ODataMessageWrapper(GetStringAsStream(Body));
            message.SetHeader("Content-Type", "application/json");
            ODataMessageReader reader = new ODataMessageReader(message as IODataRequestMessage, new ODataMessageReaderSettings(), _model);
            ODataDeserializerContext context = new ODataDeserializerContext { Path = path, Model = _model };

            // Act & Assert
            Assert.Throws<ODataException>(() =>
            {
                ODataActionParameters payload = _deserializer.Read(reader, typeof(ODataActionParameters), context) as ODataActionParameters;
            }, "The parameter 'MissingParameter' in the request payload is not a valid parameter for the operation '" + actionName + "'.");
        }
 /// <summary>
 /// Creates and adds an action import to this entity container.
 /// </summary>
 /// <param name="name">Name of the action import.</param>
 /// <param name="action">Action that the action import is importing to the container.</param>
 /// <param name="entitySet">An entity set containing entities returned by this action import. 
 /// The two expression kinds supported are <see cref="IEdmEntitySetReferenceExpression"/> and <see cref="IEdmPathExpression"/>.</param>
 /// <returns>Created action import.</returns>
 public virtual EdmActionImport AddActionImport(string name, IEdmAction action, IEdmExpression entitySet)
 {
     EdmActionImport actionImport = new EdmActionImport(this, name, action, entitySet);
     this.AddElement(actionImport);
     return actionImport;
 }
        public void Can_DeserializePayload_WithEnumParameters_InUntypedMode(string actionName, IEdmAction expectedAction, ODataPath path)
        {
            // Arrange
            const string Body = @"{ ""Color"": ""Red""}";
            ODataMessageWrapper message = new ODataMessageWrapper(GetStringAsStream(Body));
            message.SetHeader("Content-Type", "application/json");

            ODataMessageReaderSettings settings = new ODataMessageReaderSettings();
            ODataMessageReader reader = new ODataMessageReader(message as IODataRequestMessage, settings, _model);

            ODataDeserializerContext context = new ODataDeserializerContext { Path = path, Model = _model, ResourceType = typeof(ODataUntypedActionParameters) };

            // Act
            ODataUntypedActionParameters payload = _deserializer.Read(reader, typeof(ODataUntypedActionParameters), context) as ODataUntypedActionParameters;

            // Assert
            Assert.NotNull(payload);
            Assert.Same(expectedAction, payload.Action);
            Assert.True(payload.ContainsKey("Color"));
            EdmEnumObject color = payload["Color"] as EdmEnumObject;
            Assert.IsType<EdmEnumObject>(color);
            Assert.Equal("Red", color.Value);
        }
        public void Can_DeserializePayload_WithComplexParameters_InUntypedMode(string actionName, IEdmAction expectedAction, ODataPath path)
        {
            // Arrange
            const string Body = @"{ ""Quantity"": 1 , ""Address"": { ""StreetAddress"":""1 Microsoft Way"", ""City"": ""Redmond"", ""State"": ""WA"", ""ZipCode"": 98052 } }";
            ODataMessageWrapper message = new ODataMessageWrapper(GetStringAsStream(Body));
            message.SetHeader("Content-Type", "application/json");

            ODataMessageReaderSettings settings = new ODataMessageReaderSettings();
            ODataMessageReader reader = new ODataMessageReader(message as IODataRequestMessage, settings, _model);

            ODataDeserializerContext context = new ODataDeserializerContext { Path = path, Model = _model, ResourceType = typeof(ODataUntypedActionParameters) };

            // Act
            ODataUntypedActionParameters payload = _deserializer.Read(reader, typeof(ODataUntypedActionParameters), context) as ODataUntypedActionParameters;

            // Assert
            Assert.NotNull(payload);
            Assert.Same(expectedAction, payload.Action);
            Assert.True(payload.ContainsKey("Quantity"));
            Assert.Equal(1, payload["Quantity"]);
            Assert.True(payload.ContainsKey("Address"));
            dynamic address = payload["Address"] as EdmComplexObject;
            Assert.IsType<EdmComplexObject>(address);
            Assert.Equal("1 Microsoft Way", address.StreetAddress);
            Assert.Equal("Redmond", address.City);
            Assert.Equal("WA", address.State);
            Assert.Equal(98052, address.ZipCode);
        }
        public void Can_DeserializePayload_WithPrimitiveParameters(string actionName, IEdmAction expectedAction, ODataPath path)
        {
            // Arrange
            const int Quantity = 1;
            const string ProductCode = "PCode";
            string body = "{" + string.Format(@" ""Quantity"": {0} , ""ProductCode"": ""{1}"" ", Quantity, ProductCode) + "}";

            ODataMessageWrapper message = new ODataMessageWrapper(GetStringAsStream(body));
            message.SetHeader("Content-Type", "application/json");
            ODataMessageReader reader = new ODataMessageReader(message as IODataRequestMessage, new ODataMessageReaderSettings(), _model);
            ODataDeserializerContext context = new ODataDeserializerContext() { Path = path, Model = _model };

            // Act
            ODataActionParameters payload = _deserializer.Read(reader, typeof(ODataActionParameters), context) as ODataActionParameters;
            IEdmAction action = ODataActionPayloadDeserializer.GetAction(context);

            // Assert
            Assert.Same(expectedAction, action);
            Assert.NotNull(payload);
            Assert.True(payload.ContainsKey("Quantity"));
            Assert.Equal(Quantity, payload["Quantity"]);
            Assert.True(payload.ContainsKey("ProductCode"));
            Assert.Equal(ProductCode, payload["ProductCode"]);
        }
        public void Can_DeserializePayload_WithEntityCollectionParameters(IEdmAction expectedAction, ODataPath path)
        {
            // Arrange
            ODataMessageWrapper message = new ODataMessageWrapper(GetStringAsStream(EntityCollectionPayload));
            message.SetHeader("Content-Type", "application/json");
            ODataMessageReader reader = new ODataMessageReader(message as IODataRequestMessage, new ODataMessageReaderSettings(), _model);
            ODataDeserializerContext context = new ODataDeserializerContext() { Path = path, Model = _model };

            // Act
            ODataActionParameters payload = _deserializer.Read(reader, typeof(ODataActionParameters), context) as ODataActionParameters;
            IEdmAction action = ODataActionPayloadDeserializer.GetAction(context);

            // Assert
            Assert.Same(expectedAction, action);
            Assert.NotNull(payload);
            Assert.True(payload.ContainsKey("Id"));
            Assert.Equal(1, payload["Id"]);

            IList<Customer> customers = (payload["Customers"] as IEnumerable<Customer>).ToList();
            Assert.NotNull(customers);
            Assert.Equal(2, customers.Count);
            Customer customer = customers[0];
            Assert.NotNull(customer);
            Assert.Equal(109, customer.Id);
            Assert.Equal("Avatar", customer.Name);

            customer = customers[1];
            Assert.NotNull(customer);
            Assert.Equal(901, customer.Id);
            Assert.Equal("Robot", customer.Name);
        }
Beispiel #47
0
 /// <summary>
 /// Initializes a new instance of the <see cref="EdmActionImport"/> class.
 /// </summary>
 /// <param name="container">The container.</param>
 /// <param name="name">The name.</param>
 /// <param name="action">The action.</param>
 public EdmActionImport(IEdmEntityContainer container, string name, IEdmAction action)
     : this(container, name, action, null)
 {
 }
        static ODataAvroScenarioTests()
        {
            var type = new EdmEntityType("Microsoft.Test.OData.PluggableFormat.Avro.Test", "Product");
            type.AddStructuralProperty("Id", EdmPrimitiveTypeKind.Int32, false);
            type.AddStructuralProperty("Weight", EdmPrimitiveTypeKind.Single, false);

            EntryType = type;

            var cpx = new EdmComplexType("Microsoft.Test.OData.PluggableFormat.Avro.Test", "Address");
            cpx.AddStructuralProperty("Road", EdmPrimitiveTypeKind.String, false);
            cpx.AddStructuralProperty("ZipCode", EdmPrimitiveTypeKind.String, false);
            ComplexType = cpx;

            var action = new EdmAction("Microsoft.Test.OData.PluggableFormat.Avro.Test", "AddProduct", null);
            action.AddParameter("Product", new EdmEntityTypeReference(EntryType, false));
            action.AddParameter("Location", new EdmComplexTypeReference(ComplexType, false));
            AddProduct = action;

            action = new EdmAction("Microsoft.Test.OData.PluggableFormat.Avro.Test", "GetMaxId", EdmCoreModel.Instance.GetInt32(false));
            action.AddParameter("Products", new EdmCollectionTypeReference(new EdmCollectionType(new EdmEntityTypeReference(EntryType, false))));
            GetMaxId = action;
        }
        internal static string CreateMetadataFragment(IEdmAction action)
        {
            // There can only be one entity container in OData V4.
            string actionName = action.Name;
            string fragment = action.Namespace + "." + actionName;

            return fragment;
        }
        public void Can_DeserializePayload_WithPrimitiveCollectionParameters(string actionName, IEdmAction expectedAction, ODataPath path)
        {
            // Arrange
            const string Body = @"{ ""Name"": ""Avatar"", ""Ratings"": [ 5, 5, 3, 4, 5, 5, 4, 5, 5, 4 ] }";
            int[] expectedRatings = new int[] { 5, 5, 3, 4, 5, 5, 4, 5, 5, 4 };

            ODataMessageWrapper message = new ODataMessageWrapper(GetStringAsStream(Body));
            message.SetHeader("Content-Type", "application/json");
            ODataMessageReader reader = new ODataMessageReader(message as IODataRequestMessage, new ODataMessageReaderSettings(), _model);

            ODataDeserializerContext context = new ODataDeserializerContext { Path = path, Model = _model };

            // Act
            ODataActionParameters payload = _deserializer.Read(reader, typeof(ODataActionParameters), context) as ODataActionParameters;
            IEdmAction action = ODataActionPayloadDeserializer.GetAction(context);

            // Assert
            Assert.NotNull(payload);
            Assert.Same(expectedAction, action);
            Assert.True(payload.ContainsKey("Name"));
            Assert.Equal("Avatar", payload["Name"]);
            Assert.True(payload.ContainsKey("Ratings"));
            IEnumerable<int> ratings = payload["Ratings"] as IEnumerable<int>;
            Assert.Equal(10, ratings.Count());
            Assert.True(expectedRatings.Zip(ratings, (expected, actual) => expected - actual).All(diff => diff == 0));
        }
        internal static bool ShouldOmitAction(IEdmAction action, ActionLinkBuilder builder,
            ODataMetadataLevel metadataLevel)
        {
            Contract.Assert(builder != null);

            switch (metadataLevel)
            {
                case ODataMetadataLevel.MinimalMetadata:
                case ODataMetadataLevel.NoMetadata:
                    return action.IsBound && builder.FollowsConventions;

                case ODataMetadataLevel.FullMetadata:
                default: // All values already specified; just keeping the compiler happy.
                    return false;
            }
        }
        public void Can_DeserializePayload_WithComplexCollectionParameters(string actionName, IEdmAction expectedAction, ODataPath path)
        {
            // Arrange
            const string Body = @"{ ""Name"": ""Microsoft"", ""Addresses"": [ { ""StreetAddress"":""1 Microsoft Way"", ""City"": ""Redmond"", ""State"": ""WA"", ""ZipCode"": 98052 } ] }";
            ODataMessageWrapper message = new ODataMessageWrapper(GetStringAsStream(Body));
            message.SetHeader("Content-Type", "application/json");
            ODataMessageReader reader = new ODataMessageReader(message as IODataRequestMessage, new ODataMessageReaderSettings(), _model);
            ODataDeserializerContext context = new ODataDeserializerContext { Path = path, Model = _model };

            // Act
            ODataActionParameters payload = _deserializer.Read(reader, typeof(ODataActionParameters), context) as ODataActionParameters;

            // Assert
            Assert.NotNull(payload);
            Assert.True(payload.ContainsKey("Name"));
            Assert.Equal("Microsoft", payload["Name"]);
            Assert.True(payload.ContainsKey("Addresses"));
            IList<MyAddress> addresses = (payload["Addresses"] as IEnumerable<MyAddress>).ToList();
            Assert.NotNull(addresses);
            Assert.Equal(1, addresses.Count);
            MyAddress address = addresses[0];
            Assert.NotNull(address);
            Assert.Equal("1 Microsoft Way", address.StreetAddress);
            Assert.Equal("Redmond", address.City);
            Assert.Equal("WA", address.State);
            Assert.Equal(98052, address.ZipCode);
        }
        public void Can_DeserializePayload_WithEntityCollectionParameters_InUntypedMode(IEdmAction expectedAction, ODataPath path)
        {
            // Arrange
            ODataMessageWrapper message = new ODataMessageWrapper(GetStringAsStream(EntityCollectionPayload));
            message.SetHeader("Content-Type", "application/json");
            ODataMessageReader reader = new ODataMessageReader(message as IODataRequestMessage, new ODataMessageReaderSettings(), _model);
            ODataDeserializerContext context = new ODataDeserializerContext { Path = path, Model = _model, ResourceType = typeof(ODataUntypedActionParameters) };

            // Act
            ODataUntypedActionParameters payload = _deserializer.Read(reader, typeof(ODataUntypedActionParameters), context) as ODataUntypedActionParameters;

            // Assert
            Assert.Same(expectedAction, payload.Action);
            Assert.NotNull(payload);
            Assert.True(payload.ContainsKey("Id"));
            Assert.Equal(1, payload["Id"]);

            IEnumerable<IEdmObject> customers = payload["Customers"] as EdmEntityObjectCollection;
            Assert.Equal(2, customers.Count());
            dynamic customer = customers.First();
            Assert.NotNull(customer);
            Assert.Equal(109, customer.Id);
            Assert.Equal("Avatar", customer.Name);

            customer = customers.Last();
            Assert.NotNull(customer);
            Assert.Equal(901, customer.Id);
            Assert.Equal("Robot", customer.Name);
        }
 /// <summary>
 /// Creates and adds an action import to this entity container.
 /// </summary>
 /// <param name="name">Name of the action import.</param>
 /// <param name="action">Action that the action import is importing to the container.</param>
 /// <returns>Created action import.</returns>
 public virtual EdmActionImport AddActionImport(string name, IEdmAction action)
 {
     EdmActionImport actionImport = new EdmActionImport(this, name, action, null);
     this.AddElement(actionImport);
     return actionImport;
 }
        /// <summary>
        /// Creates a unique function name based on the type. Used to find duplicates of functions.
        /// - Bound actions support overloading (multiple actions having the same name within the same namespace) by binding parameter type. The combination of action name and the binding parameter type MUST be unique within a namespace.
        /// - Unbound actions do not support overloads. The names of all unbound actions MUST be unique within a namespace. An unbound action MAY have the same name as a bound action.
        /// </summary>
        /// <param name="action">action to build the hash from.</param>
        /// <returns>A unique string that identifies a function.</returns>
        private static string BuildInternalUniqueActionString(IEdmAction action)
        {
            StringBuilder builder = new StringBuilder();
            builder.Append(action.IsBound);
            builder.Append("-");
            builder.Append(action.Namespace);
            builder.Append("-");
            builder.Append(action.Name);
            builder.Append("-");
            if (!action.Parameters.Any())
            {
                return builder.ToString();
            }

            if (action.IsBound)
            {
                IEdmOperationParameter bindingParameter = action.Parameters.FirstOrDefault();
                builder.Append(bindingParameter.Type.FullName());
            }

            return builder.ToString();
        }
        public virtual ODataAction CreateODataAction(IEdmAction action, EntityInstanceContext entityInstanceContext)
        {
            if (action == null)
            {
                throw Error.ArgumentNull("action");
            }

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

            IEdmModel model = entityInstanceContext.EdmModel;
            ActionLinkBuilder builder = model.GetActionLinkBuilder(action);

            if (builder == null)
            {
                return null;
            }

            return CreateODataOperation(action, builder, entityInstanceContext) as ODataAction;
        }