/// <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); }
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); } }
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); }
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); }
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); } } }
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); }
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()))); }
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); }
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); }
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 + "'."); }
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); }
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); }
/// <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; }
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); }
/// <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); }
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); }
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); }
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()); }
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); }
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); }
/// <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; }