예제 #1
0
        private static FilterClause CreateFilterClause(IEdmEntitySet entitySet, IEnumerable <KeyValuePair <String, Object> > keys)
        {
            var entityTypeRef = (IEdmEntityTypeReference)((IEdmCollectionType)entitySet.Type).ElementType;
            var range         = new ResourceRangeVariable("", entityTypeRef, entitySet);
            var refNode       = new ResourceRangeVariableReferenceNode("$it", range);

            BinaryOperatorNode compositeNode = null;
            var entityType = (IEdmEntityType)entityTypeRef.Definition;

            foreach (KeyValuePair <String, Object> keyValue in keys)
            {
                IEdmProperty property = entityType.FindProperty(keyValue.Key);
                var          left     = new SingleValuePropertyAccessNode(refNode, property);
                var          right    = new ConstantNode(keyValue.Value, ODataUriUtils.ConvertToUriLiteral(keyValue.Value, ODataVersion.V4));
                var          node     = new BinaryOperatorNode(BinaryOperatorKind.Equal, left, right);

                if (compositeNode == null)
                {
                    compositeNode = node;
                }
                else
                {
                    compositeNode = new BinaryOperatorNode(BinaryOperatorKind.And, compositeNode, node);
                }
            }
            return(new FilterClause(compositeNode, range));
        }
예제 #2
0
        internal Uri GenerateLocationHeader()
        {
            Contract.Assert(_controller.ContainerMetadata != null);

            Type clrType  = Entity.GetType();
            Type baseType = clrType.BaseType;
            IEntitySetMetadata entitySetMetadata = _controller.ContainerMetadata.GetEntitySetFor(clrType);

            while (entitySetMetadata == null && baseType != null)
            {
                entitySetMetadata = _controller.ContainerMetadata.GetEntitySetFor(baseType);
                baseType          = baseType.BaseType;
            }

            if (entitySetMetadata == null)
            {
                throw new InvalidOperationException("IEntitySetMetadata not found for entity type " + clrType.FullName);
            }

            IEntityTypeMetadata entityTypeMetadata = _controller.ContainerMetadata.GetEntityType(clrType);

            if (entityTypeMetadata == null)
            {
                throw new InvalidOperationException("IEntityTypeMetadata not found for entity type " + clrType.FullName);
            }

            object keyValue  = entityTypeMetadata.SingleClrKeyProperty.GetValue(Entity);
            string keyString = ODataUriUtils.ConvertToUriLiteral(keyValue, ODataVersion.V3, Request.ODataProperties().Model);

            string oDataLink = _controller.Url.CreateODataLink(new EntitySetPathSegment(entitySetMetadata.Name), new KeyValuePathSegment(keyString));

            return(new Uri(oDataLink));
        }
        public void UpdateWithAttachAndPrefer()
        {
            using (TestUtil.RestoreStaticValueOnDispose(typeof(CustomDataContext), "PreserveChanges"))
            {
                CustomDataContext.PreserveChanges = true;
                RunClientIntegrationTestWithTrackingOnly(ctx =>
                {
                    var anonymousCustomer = ctx.CreateQuery <Customer>("Customers").Select(c => new { c.ID, c.GuidValue }).First();
                    var customer          = new Customer {
                        ID = anonymousCustomer.ID, Name = "this is the new name"
                    };

                    // resolver is still required for update case because this particular set has multiple types in it.
                    ctx.ResolveName = t => t == typeof(Customer) ? "AstoriaUnitTests.Stubs.Customer" : null;

                    ctx.AttachTo("Customers", customer, "W/\"" + ODataUriUtils.ConvertToUriLiteral(anonymousCustomer.GuidValue, ODataVersion.V4) + "\"");
                    ctx.UpdateObject(customer);
                    ctx.AddAndUpdateResponsePreference = DataServiceResponsePreference.IncludeContent;
                    ctx.SaveChanges();

                    // value should have changed in the response payload
                    Assert.AreNotEqual(customer.GuidValue, Guid.Empty);
                    Assert.AreNotEqual(customer.GuidValue, anonymousCustomer.GuidValue);
                });
            }
        }
예제 #4
0
        public EntityTagHeaderValue CreateETag(IDictionary <string, object> properties)
        {
            Debug.Assert(properties != null);

            if (properties.Count == 0)
            {
                return(null);
            }

            StringBuilder builder = new StringBuilder();

            builder.Append('\"');// necessary
            bool firstProperty = true;

            foreach (var property in properties)
            {
                if (firstProperty)
                {
                    firstProperty = false;
                }
                else
                {
                    builder.Append("/");
                }

                builder.Append(property.Key).Append(",");
                string value = ODataUriUtils.ConvertToUriLiteral(property.Value, ODataVersion.V4);
                builder.Append(value);
            }

            builder.Append('\"'); // necessary
            string tag = builder.ToString();

            return(new EntityTagHeaderValue(tag, isWeak: true));
        }
        /// <summary>
        /// Support for creating products
        /// </summary>
        public HttpResponseMessage Post(Product product)
        {
            product.Family = null;

            Product addedProduct = _db.Products.Add(product);

            _db.SaveChanges();
            var response  = Request.CreateResponse(HttpStatusCode.Created, addedProduct);
            var odataPath = Request.GetODataPath();

            if (odataPath == null)
            {
                throw new InvalidOperationException("There is no ODataPath in the request.");
            }
            var entitySetPathSegment = odataPath.Segments.FirstOrDefault() as EntitySetPathSegment;

            if (entitySetPathSegment == null)
            {
                throw new InvalidOperationException("ODataPath doesn't start with EntitySetPathSegment.");
            }

            response.Headers.Location = new Uri(Url.ODataLink(
                                                    entitySetPathSegment,
                                                    new KeyValuePathSegment(ODataUriUtils.ConvertToUriLiteral(addedProduct.ID, ODataVersion.V3))));

            return(response);
        }
예제 #6
0
        /// <summary>
        /// Converts a <see cref="UriOperationParameter"/> value to an escaped string for use in a Uri. Wraps the call to ODL's ConvertToUriLiteral and escapes the results.
        /// </summary>
        /// <param name="paramName">The name of the <see cref="UriOperationParameter"/>. Used for error reporting.</param>
        /// <param name="value">The value of the <see cref="UriOperationParameter"/>.</param>
        /// <param name="useEntityReference">If true, use entity reference, instead of entity to serialize the parameter.</param>
        /// <returns>A string representation of <paramref name="value"/> for use in a Url.</returns>
        private string ConvertToEscapedUriValue(string paramName, object value, bool useEntityReference = false)
        {
            Debug.Assert(!string.IsNullOrEmpty(paramName), "!string.IsNullOrEmpty(paramName)");

            // Literal values with single quotes need special escaping due to System.Uri changes in behavior between .NET 4.0 and 4.5.
            // We need to ensure that our escaped values do not change between those versions, so we need to escape values differently when they could contain single quotes.
            bool   needsSpecialEscaping = false;
            object valueInODataFormat   = ConvertToODataValue(paramName, value, ref needsSpecialEscaping, useEntityReference);

            // When calling Execute() to invoke an Action, the client doesn't support parsing the target url
            // to determine which IEdmOperationImport to pass to the ODL writer. So the ODL writer is
            // serializing the parameter payload without metadata. Setting the model to null so ODL doesn't
            // do unecessary validations when writing without metadata.
            string literal = ODataUriUtils.ConvertToUriLiteral(valueInODataFormat, CommonUtil.ConvertToODataVersion(this.requestInfo.MaxProtocolVersionAsVersion), null /* edmModel */);

            // The value from ConvertToUriValue will not be escaped, but will already contain literal delimiters like single quotes, so we
            // need to use our own escape method that will preserve those characters instead of directly calling Uri.EscapeDataString that may escape them.
            // This is only necessary for primitives and nulls because the other structures are serialized using the JSON format and it uses double quotes
            // which have always been escaped.
            if (needsSpecialEscaping)
            {
                return(DataStringEscapeBuilder.EscapeDataString(literal));
            }

            return(Uri.EscapeDataString(literal));
        }
예제 #7
0
        private BinaryOperatorNode BuildFilterExpression(SingleResourceNode source, GraphQLFieldSelection selection)
        {
            BinaryOperatorNode compositeNode = null;
            IEdmEntityType     entityType    = source.NavigationSource.EntityType();

            foreach (GraphQLArgument argument in selection.Arguments)
            {
                IEdmProperty edmProperty = FindEdmProperty(entityType, argument.Name.Value);
                var          left        = new SingleValuePropertyAccessNode(source, edmProperty);

                Object value = GetArgumentValue(edmProperty.Type, argument.Value);
                var    right = new ConstantNode(value, ODataUriUtils.ConvertToUriLiteral(value, ODataVersion.V4));
                var    node  = new BinaryOperatorNode(BinaryOperatorKind.Equal, left, right);
                compositeNode = ComposeExpression(compositeNode, node);
            }

            //foreach (ASTNode astNode in selection.SelectionSet.Selections)
            //    if (astNode is GraphQLFieldSelection fieldSelection && fieldSelection.SelectionSet != null)
            //    {
            //        var navigationProperty = (IEdmNavigationProperty)FindEdmProperty(entityType, fieldSelection.Name.Value);
            //        if (navigationProperty.Type is IEdmCollectionTypeReference)
            //            continue;

            //        var parentSource = new SingleNavigationNode(source, navigationProperty, null);
            //        BinaryOperatorNode node = BuildFilterExpression(parentSource, fieldSelection);
            //        compositeNode = ComposeExpression(compositeNode, node);
            //    }

            return(compositeNode);
        }
예제 #8
0
 public override string ConvertValueToUriLiteral(object value)
 {
     return(value is ODataExpression
         ? (value as ODataExpression).AsString(_session)
         : ODataUriUtils.ConvertToUriLiteral(value,
                                             (ODataVersion)Enum.Parse(typeof(ODataVersion), this.GetODataVersionString(), false), this.Model));
 }
예제 #9
0
        // Translate the object of key in ODL path to string literal.
        private static string TranslateKeySegmentValue(object value)
        {
            if (value == null)
            {
                throw new ArgumentNullException(nameof(value));
            }

            UriTemplateExpression uriTemplateExpression = value as UriTemplateExpression;

            if (uriTemplateExpression != null)
            {
                return(uriTemplateExpression.LiteralText);
            }

            ConstantNode constantNode = value as ConstantNode;

            if (constantNode != null)
            {
                ODataEnumValue enumValue = constantNode.Value as ODataEnumValue;
                if (enumValue != null)
                {
                    return(ODataUriUtils.ConvertToUriLiteral(enumValue, ODataVersion.V4));
                }
            }

            return(ODataUriUtils.ConvertToUriLiteral(value, ODataVersion.V4));
        }
        /// <summary>
        /// Translate a KeySegment
        /// </summary>
        /// <param name="segment">the segment to Translate</param>
        /// <returns>Defined by the implementer.</returns>
        public override string Translate(KeySegment segment)
        {
            Debug.Assert(segment != null, "segment != null");
            List <KeyValuePair <string, object> > keys = segment.Keys.ToList();

            StringBuilder builder = new StringBuilder();

            builder.Append("(");

            for (int i = 0; i < keys.Count; i++)
            {
                if (i != 0)
                {
                    builder.Append(",");
                }

                if (keys.Count == 1)
                {
                    builder.Append(ODataUriUtils.ConvertToUriLiteral(keys[i].Value, ODataVersion.V4, DataSourceManager.GetCurrentDataSource().Model));
                }
                else
                {
                    builder.Append(string.Format("{0}={1}", keys[i].Key, ODataUriUtils.ConvertToUriLiteral(keys[i].Value, ODataVersion.V4, DataSourceManager.GetCurrentDataSource().Model)));
                }
            }

            builder.Append(")");

            return(builder.ToString());
        }
예제 #11
0
        public override string ConvertValueToUriLiteral(object value, bool escapeDataString)
        {
            var type = value?.GetType();

            if (type != null && _session.TypeCache.Converter.HasObjectConverter(type))
            {
                value = _session.TypeCache.Converter.Convert(value, type);
            }

            if (value != null && _session.TypeCache.IsEnumType(type))
            {
                value = Convert.ToInt32(value);
            }
            if (value is ODataExpression expression)
            {
                return(expression.AsString(_session));
            }

            var odataVersion = (ODataVersion)Enum.Parse(typeof(ODataVersion), _session.Adapter.GetODataVersionString(), false);

            string ConvertValue(object x) => ODataUriUtils.ConvertToUriLiteral(x, odataVersion, (_session.Adapter as ODataAdapter).Model);

            return(escapeDataString
                ? Uri.EscapeDataString(ConvertValue(value))
                : ConvertValue(value));
        }
예제 #12
0
        // Translate the object of key in ODL path to string literal.
        private static string TranslateKeySegmentValue(object value, bool enableUriTemplateParsing)
        {
            if (value == null)
            {
                throw Error.ArgumentNull("value");
            }

            if (enableUriTemplateParsing)
            {
                UriTemplateExpression uriTemplateExpression = value as UriTemplateExpression;
                if (uriTemplateExpression != null)
                {
                    return(uriTemplateExpression.LiteralText);
                }
            }

            ConstantNode constantNode = value as ConstantNode;

            if (constantNode != null)
            {
                ODataEnumValue enumValue = constantNode.Value as ODataEnumValue;
                if (enumValue != null)
                {
                    return(ODataUriUtils.ConvertToUriLiteral(enumValue, ODataVersion.V4));
                }
            }

            return(ODataUriUtils.ConvertToUriLiteral(value, ODataVersion.V4));
        }
예제 #13
0
        public override string ConvertValueToUriLiteral(object value, bool escapeDataString)
        {
            if (value != null && value.GetType().IsEnumType())
            {
                value = new ODataEnumValue(value.ToString(), _session.Metadata.GetQualifiedTypeName(value.GetType().Name));
            }
            if (value is ODataExpression)
            {
                return((value as ODataExpression).AsString(_session));
            }

            var odataVersion = (ODataVersion)Enum.Parse(typeof(ODataVersion), _session.Adapter.GetODataVersionString(), false);
            Func <object, string> convertValue = x => ODataUriUtils.ConvertToUriLiteral(x, odataVersion, (_session.Adapter as ODataAdapter).Model);

            if (value is ODataEnumValue && _session.Settings.EnumPrefixFree)
            {
                value = (value as ODataEnumValue).Value;
            }
            else if (value is DateTime)
            {
                value = new DateTimeOffset((DateTime)value);
            }

            return(escapeDataString
                ? Uri.EscapeDataString(convertValue(value))
                : convertValue(value));
        }
예제 #14
0
        public void TestResourceValueWithInstanceAnnotationConvertToUriLiteral()
        {
            ODataResourceValue value = new ODataResourceValue
            {
                TypeName   = "Fully.Qualified.Namespace.Person",
                Properties = new[]
                {
                    new ODataProperty {
                        Name = "ID", Value = 42
                    }
                },
                InstanceAnnotations = new []
                {
                    new ODataInstanceAnnotation("Custom.Annotation", new ODataResourceValue
                    {
                        TypeName   = "Fully.Qualified.Namespace.Dog",
                        Properties = new []
                        {
                            new ODataProperty {
                                Name = "Color", Value = "Red"
                            }
                        }
                    })
                }
            };

            string actual = ODataUriUtils.ConvertToUriLiteral(value, ODataVersion.V4, HardCodedTestModel.TestModel);

            Assert.Equal(
                "{" +
                "\"@odata.type\":\"#Fully.Qualified.Namespace.Person\"," +
                "\"@Custom.Annotation\":{\"@odata.type\":\"#Fully.Qualified.Namespace.Dog\",\"Color\":\"Red\"}," +
                "\"ID\":42" +
                "}", actual);
        }
예제 #15
0
        private string ConvertValue(ExpressionContext context, object value, bool escapeDataString)
        {
            var type = value?.GetType();

            if (value != null && context.Session.TypeCache.IsEnumType(type))
            {
                value = new ODataEnumValue(value.ToString(), string.Join(".", type.Namespace, type.Name));
            }
            if (value is ODataExpression expression)
            {
                return(expression.AsString(context.Session));
            }

            var odataVersion = ODataVersion.V4;                                                        // (ODataVersion)Enum.Parse(typeof(ODataVersion), context.Session.Adapter.GetODataVersionString(), false);

            string ConvertValue(object x) => ODataUriUtils.ConvertToUriLiteral(x, odataVersion, null); // context.Session.Adapter.Model as IEdmModel);

            if (value is ODataEnumValue && context.Session.EnumPrefixFree)
            {
                value = ((ODataEnumValue)value).Value;
            }
            else if (value is DateTime)
            {
                value = new DateTimeOffset((DateTime)value);
            }

            return(escapeDataString
                ? Uri.EscapeDataString(ConvertValue(value))
                : ConvertValue(value));
        }
예제 #16
0
        /// <summary>
        /// Add a key value to the route data.
        /// </summary>

        public void AddKeyValueToRouteData(KeySegment segment, string keyName = "key")
        {
            foreach (var keyValuePair in segment.Keys)
            {
                object       value = keyValuePair.Value;
                ConstantNode node  = value as ConstantNode;
                if (node != null)
                {
                    ODataEnumValue enumValue = node.Value as ODataEnumValue;
                    if (enumValue != null)
                    {
                        value = ODataUriUtils.ConvertToUriLiteral(enumValue, ODataVersion.V4);
                    }
                }

                if (segment.Keys.Count() == 1)
                {
                    RouteData[keyName] = value;
                }
                else
                {
                    RouteData[keyValuePair.Key] = value;
                }
            }
        }
예제 #17
0
        private static string CreatePolygon()
        {
            /*
             * GeographyPolygon polygonValue =
             *  GeographyFactory.Polygon()
             *      .Ring(33.1, -110.0)
             *      .LineTo(35.97, -110.15)
             *      .LineTo(11.45, 87.75)
             *      .Ring(35.97, -110)
             *      .LineTo(36.97, -110.15)
             *      .LineTo(45.23, 23.18)
             *      .Build();*/

            GeographyPolygon polygonValue =
                GeographyFactory.Polygon()
                .Ring(0, 0)
                .LineTo(5, 0)
                .LineTo(5, 5)
                .LineTo(0, 5)
                .Build();

            string polygonString = ODataUriUtils.ConvertToUriLiteral(polygonValue, ODataVersion.V4);

            Console.WriteLine(polygonString);

            return(polygonString);
        }
예제 #18
0
        private void RunTestCase(ConvertToUriLiteralTestCase testCase, ODataVersion version = ODataVersion.V4, IEdmModel model = null)
        {
            // Negative Test
            if (testCase.ExpectedException != null)
            {
                TestExceptionUtils.ExpectedException(
                    this.Assert,
                    () =>
                {
                    ODataUriUtils.ConvertToUriLiteral(testCase.Parameter, version, model);
                },
                    testCase.ExpectedException,
                    this.ExceptionVerifier
                    );
            }
            else // Positive Test
            {
                string actualValue   = ODataUriUtils.ConvertToUriLiteral(testCase.Parameter, version, model);
                object expectedValue = testCase.ExpectedValues;
                if (expectedValue == null)
                {
                    expectedValue = testCase.ExpectedValue;
                }

                if (!expectedValue.Equals(actualValue))
                {
                    throw new ODataTestException(string.Format(
                                                     "Different JSON.{0}Expected:{0}{1}{0}Actual:{0}{2}{0}",
                                                     Environment.NewLine,
                                                     expectedValue,
                                                     actualValue));
                }
            }
        }
예제 #19
0
        public static void AddKeyValueToRouteData(this HttpControllerContext controllerContext, KeySegment segment, string keyName = "key")
        {
            Contract.Assert(controllerContext != null);
            Contract.Assert(segment != null);

            foreach (var keyValuePair in segment.Keys)
            {
                object       value = keyValuePair.Value;
                ConstantNode node  = value as ConstantNode;
                if (node != null)
                {
                    ODataEnumValue enumValue = node.Value as ODataEnumValue;
                    if (enumValue != null)
                    {
                        value = ODataUriUtils.ConvertToUriLiteral(enumValue, ODataVersion.V4);
                    }
                }

                if (segment.Keys.Count() == 1)
                {
                    controllerContext.RouteData.Values[keyName] = value;
                }
                else
                {
                    controllerContext.RouteData.Values[keyValuePair.Key] = value;
                }
            }
        }
예제 #20
0
        public void TestResourceValueWithNestedResourceValueConvertToUriLiteral()
        {
            ODataResourceValue value = new ODataResourceValue
            {
                TypeName   = "Fully.Qualified.Namespace.Person",
                Properties = new[]
                {
                    new ODataProperty {
                        Name = "ID", Value = 42
                    },
                    new ODataProperty {
                        Name = "SSN", Value = "777-42-9001"
                    },
                    new ODataProperty
                    {
                        Name  = "MyDog",
                        Value = new ODataResourceValue
                        {
                            TypeName   = "Fully.Qualified.Namespace.Dog",
                            Properties = new []
                            {
                                new ODataProperty {
                                    Name = "Color", Value = "Red"
                                }
                            }
                        }
                    }
                }
            };

            string actual = ODataUriUtils.ConvertToUriLiteral(value, ODataVersion.V4, HardCodedTestModel.TestModel);

            Assert.Equal(@"{""@odata.type"":""#Fully.Qualified.Namespace.Person"",""ID"":42,""SSN"":""777-42-9001"",""MyDog"":{""Color"":""Red""}}", actual);
        }
        public static HttpResponseMessage PostResponse <TEntity, TKey>(ApiController controller, TEntity createdEntity, TKey entityKey)
        {
            HttpResponseMessage response = null;
            HttpRequestMessage  request  = controller.Request;

            if (RequestPrefersReturnNoContent(request))
            {
                response = request.CreateResponse(HttpStatusCode.NoContent);
                response.Headers.Add(PreferenceAppliedHeaderName, ReturnNoContentHeaderValue);
            }
            else
            {
                response = request.CreateResponse(HttpStatusCode.Created, createdEntity);
            }

            ODataPath odataPath = request.GetODataPath();

            if (odataPath == null)
            {
                throw Error.InvalidOperation(SRResources.LocationHeaderMissingODataPath);
            }

            EntitySetPathSegment entitySetSegment = odataPath.Segments.FirstOrDefault() as EntitySetPathSegment;

            if (entitySetSegment == null)
            {
                throw Error.InvalidOperation(SRResources.LocationHeaderDoesNotStartWithEntitySet);
            }

            response.Headers.Location = new Uri(controller.Url.ODataLink(
                                                    entitySetSegment,
                                                    new KeyValuePathSegment(ODataUriUtils.ConvertToUriLiteral(entityKey, ODataVersion.V3))));
            return(response);
        }
        public override string ConvertValueToUriLiteral(object value, bool escapeDataString)
        {
            var type = value?.GetType();

            if (type != null && _session.TypeCache.Converter.HasObjectConverter(type))
            {
                value = _session.TypeCache.Converter.Convert(value, type);
            }

            if (value != null && _session.TypeCache.IsEnumType(type))
            {
                value = new ODataEnumValue(value.ToString(), _session.Metadata.GetQualifiedTypeName(type.Name));
            }
            if (value is ODataExpression expression)
            {
                return(expression.AsString(_session));
            }

            var odataVersion = (ODataVersion)Enum.Parse(typeof(ODataVersion), _session.Adapter.GetODataVersionString(), false);

            string ConvertValue(object x) => ODataUriUtils.ConvertToUriLiteral(x, odataVersion, (_session.Adapter as ODataAdapter).Model);

            if (value is ODataEnumValue && _session.Settings.EnumPrefixFree)
            {
                value = ((ODataEnumValue)value).Value;
            }
            else if (value is DateTime)
            {
                value = new DateTimeOffset((DateTime)value);
            }

            return(escapeDataString
                ? Uri.EscapeDataString(ConvertValue(value))
                : ConvertValue(value));
        }
예제 #23
0
        /// <summary>
        /// Generates a string to be used as the skip token value within the next link.
        /// </summary>
        /// <param name="lastMember"> Object based on which SkipToken value will be generated.</param>
        /// <param name="model">The edm model.</param>
        /// <param name="orderByNodes">List of orderByNodes used to generate the skiptoken value.</param>
        /// <returns>Value for the skiptoken to be used in the next link.</returns>
        private static string GenerateSkipTokenValue(Object lastMember, IEdmModel model, IList <OrderByNode> orderByNodes)
        {
            if (lastMember == null)
            {
                return(String.Empty);
            }

            IEnumerable <IEdmProperty> propertiesForSkipToken = GetPropertiesForSkipToken(lastMember, model, orderByNodes);
            StringBuilder skipTokenBuilder = new StringBuilder(String.Empty);

            if (propertiesForSkipToken == null)
            {
                return(skipTokenBuilder.ToString());
            }

            int    count = 0;
            string uriLiteral;
            object value;
            int    lastIndex         = propertiesForSkipToken.Count() - 1;
            IEdmStructuredObject obj = lastMember as IEdmStructuredObject;

            foreach (IEdmProperty edmProperty in propertiesForSkipToken)
            {
                bool   islast          = count == lastIndex;
                string clrPropertyName = EdmLibHelpers.GetClrPropertyName(edmProperty, model);
                if (obj != null)
                {
                    obj.TryGetPropertyValue(clrPropertyName, out value);
                }
                else
                {
                    value = lastMember.GetType().GetProperty(clrPropertyName).GetValue(lastMember);
                }

                if (value == null)
                {
                    uriLiteral = ODataUriUtils.ConvertToUriLiteral(value, ODataVersion.V401);
                }
                else if (edmProperty.Type.IsEnum())
                {
                    ODataEnumValue enumValue = new ODataEnumValue(value.ToString(), value.GetType().FullName);
                    uriLiteral = ODataUriUtils.ConvertToUriLiteral(enumValue, ODataVersion.V401, model);
                }
                else if (edmProperty.Type.IsDateTimeOffset() && value is DateTime)
                {
                    var dateTime            = (DateTime)value;
                    var dateTimeOffsetValue = TimeZoneInfoHelper.ConvertToDateTimeOffset(dateTime);
                    uriLiteral = ODataUriUtils.ConvertToUriLiteral(dateTimeOffsetValue, ODataVersion.V401, model);
                }
                else
                {
                    uriLiteral = ODataUriUtils.ConvertToUriLiteral(value, ODataVersion.V401, model);
                }

                skipTokenBuilder.Append(edmProperty.Name).Append(propertyDelimiter).Append(uriLiteral).Append(islast ? String.Empty : CommaDelimiter.ToString());
                count++;
            }

            return(skipTokenBuilder.ToString());
        }
예제 #24
0
        public void TestEnumConvertToUriLiteral_EnumValue()
        {
            var    val        = new ODataEnumValue(11L + "", "Fully.Qualified.Namespace.ColorPattern");
            string enumValStr = ODataUriUtils.ConvertToUriLiteral(val, ODataVersion.V4);

            Assert.Equal("Fully.Qualified.Namespace.ColorPattern'11'", enumValStr);
        }
예제 #25
0
        public static string EntitySetLink(this IODataPathHandler parser, string entitySet, object id)
        {
            ODataPath path = new ODataPath(
                new EntitySetPathSegment(entitySet),
                new KeyValuePathSegment(ODataUriUtils.ConvertToUriLiteral(id, Microsoft.Data.OData.ODataVersion.V3)));

            return(parser.Link(path));
        }
예제 #26
0
        /// <summary>
        /// If the source node is not of the specified type, then we check if type promotion is possible and inject a convert node.
        /// If the source node is the same type as the target type (or if the target type is null), we just return the source node as is.
        /// </summary>
        /// <param name="source">The source node to apply the convertion to.</param>
        /// <param name="targetTypeReference">The target primitive type. May be null - this method will do nothing in that case.</param>
        /// <returns>The converted query node, or the original source node unchanged.</returns>
        internal static SingleValueNode ConvertToTypeIfNeeded(SingleValueNode source, IEdmTypeReference targetTypeReference)
        {
            Debug.Assert(source != null, "source != null");

            if (targetTypeReference == null)
            {
                return(source);
            }

            if (source.TypeReference != null)
            {
                if (source.TypeReference.IsEquivalentTo(targetTypeReference))
                {
                    return(source);
                }

                if (!TypePromotionUtils.CanConvertTo(source, source.TypeReference, targetTypeReference))
                {
                    throw new ODataException(ODataErrorStrings.MetadataBinder_CannotConvertToType(source.TypeReference.ODataFullName(), targetTypeReference.ODataFullName()));
                }
                else
                {
                    ConstantNode constantNode = source as ConstantNode;

                    if (source.TypeReference.IsEnum() && constantNode != null)
                    {
                        return(new ConstantNode(constantNode.Value, ODataUriUtils.ConvertToUriLiteral(constantNode.Value, ODataVersion.V4), targetTypeReference));
                    }

                    object primitiveValue;
                    if (MetadataUtilsCommon.TryGetConstantNodePrimitiveLDMF(source, out primitiveValue) && (primitiveValue != null))
                    {
                        // L F D M types : directly create a ConvertNode.
                        // 1. NodeToExpressionTranslator.cs won't allow implicitly converting single/double to decimal, which should be done here at Node tree level.
                        // 2. And prevent losing precision in float -> double, e.g. (double)1.234f => 1.2339999675750732d not 1.234d
                        object primitiveValue2 = ODataUriConversionUtils.CoerceNumericType(primitiveValue, targetTypeReference.AsPrimitive().Definition as IEdmPrimitiveType);

                        if (string.IsNullOrEmpty(constantNode.LiteralText))
                        {
                            return(new ConstantNode(primitiveValue2));
                        }

                        return(new ConstantNode(primitiveValue2, constantNode.LiteralText));
                    }
                    else
                    {
                        // other type conversion : ConvertNode
                        return(new ConvertNode(source, targetTypeReference));
                    }
                }
            }
            else
            {
                // If the source doesn't have a type (possibly an open property), then it's possible to convert it
                // cause we don't know for sure.
                return(new ConvertNode(source, targetTypeReference));
            }
        }
예제 #27
0
        public static string NavigationLink(this IODataPathHandler parser, string entitySet, object key, IEdmNavigationProperty navigationProperty)
        {
            ODataPath path = new ODataPath(
                new EntitySetPathSegment(entitySet),
                new KeyValuePathSegment(ODataUriUtils.ConvertToUriLiteral(key, Microsoft.Data.OData.ODataVersion.V3)),
                new NavigationPathSegment(navigationProperty));

            return(parser.Link(path));
        }
예제 #28
0
        // gets the primitive odata uri representation.
        public static string GetUriRepresentationForValue(object value)
        {
            Contract.Assert(value != null);
            Contract.Assert(EdmLibHelpers.GetEdmPrimitiveTypeOrNull(value.GetType()) != null);

            value = ODataPrimitiveSerializer.ConvertUnsupportedPrimitives(value);

            return(ODataUriUtils.ConvertToUriLiteral(value, ODataVersion.V3));
        }
예제 #29
0
        public void TestCollectionResourceValueWithInstanceAnnotationConvertToUriLiteral()
        {
            ODataResourceValue person = new ODataResourceValue
            {
                TypeName   = "Fully.Qualified.Namespace.Person",
                Properties = new[]
                {
                    new ODataProperty {
                        Name = "ID", Value = 42
                    }
                },
                InstanceAnnotations = new[]
                {
                    new ODataInstanceAnnotation("Custom.Annotation", new ODataResourceValue
                    {
                        TypeName   = "Fully.Qualified.Namespace.Dog",
                        Properties = new []
                        {
                            new ODataProperty {
                                Name = "Color", Value = "Red"
                            }
                        }
                    })
                }
            };
            ODataResourceValue employee = new ODataResourceValue
            {
                TypeName   = "Fully.Qualified.Namespace.Employee",
                Properties = new[]
                {
                    new ODataProperty {
                        Name = "ID", Value = 42
                    },
                    new ODataProperty {
                        Name = "WorkEmail", Value = "*****@*****.**"
                    }
                }
            };
            ODataCollectionValue collection = new ODataCollectionValue
            {
                TypeName = "Collection(Fully.Qualified.Namespace.Person)",
                Items    = new[]
                {
                    person,
                    employee
                }
            };

            string actual = ODataUriUtils.ConvertToUriLiteral(collection, ODataVersion.V4, HardCodedTestModel.TestModel);

            Assert.Equal(
                "[" +
                "{\"@Custom.Annotation\":{\"@odata.type\":\"#Fully.Qualified.Namespace.Dog\",\"Color\":\"Red\"},\"ID\":42}," +
                "{\"@odata.type\":\"#Fully.Qualified.Namespace.Employee\",\"ID\":42,\"WorkEmail\":\"[email protected]\"}" +
                "]", actual);
        }
예제 #30
0
        public async Task ODataModelBinderProvider_Throws(object value, string action)
        {
            string url = String.Format(
                "http://localhost/ODataModelBinderProviderThrowsTest/{0}({1})",
                action,
                Uri.EscapeDataString(ODataUriUtils.ConvertToUriLiteral(value, ODataVersion.V4)));
            HttpResponseMessage response = await _client.GetAsync(url);

            Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);
        }