/// <summary> /// Try to convert a value into an EDM primitive type, if template parsing enabled, the <paramref name="valueText"/> matching /// template would be converted into corresponding UriTemplateExpression. /// </summary> /// <param name="typeReference">the type to convert to (primitive or enum type)</param> /// <param name="valueText">the value to convert</param> /// <param name="convertedValue">The converted value, if conversion succeeded.</param> /// <returns>true if the conversion was successful.</returns> private bool TryConvertValue(IEdmTypeReference typeReference, string valueText, out object convertedValue) { UriTemplateExpression expression; if (this.enableUriTemplateParsing && UriTemplateParser.TryParseLiteral(valueText, typeReference, out expression)) { convertedValue = expression; return(true); } if (typeReference.IsEnum()) { QueryNode enumNode = null; if (EnumBinder.TryBindIdentifier(valueText, typeReference.AsEnum(), null, out enumNode)) { convertedValue = ((ConstantNode)enumNode).Value; return(true); } convertedValue = null; return(false); } IEdmPrimitiveTypeReference primitiveType = typeReference.AsPrimitive(); Type primitiveClrType = EdmLibraryExtensions.GetPrimitiveClrType((IEdmPrimitiveType)primitiveType.Definition, primitiveType.IsNullable); LiteralParser literalParser = LiteralParser.ForKeys(this.keysAsSegment); return(literalParser.TryParseLiteral(primitiveClrType, valueText, out convertedValue)); }
/// <summary> /// Binds a DottedIdentifierToken and it's parent node (if needed). /// </summary> /// <param name="dottedIdentifierToken">Token to bind to metadata.</param> /// <returns>A bound node representing the cast.</returns> internal QueryNode BindDottedIdentifier(DottedIdentifierToken dottedIdentifierToken) { ExceptionUtils.CheckArgumentNotNull(dottedIdentifierToken, "castToken"); ExceptionUtils.CheckArgumentNotNull(state, "state"); QueryNode parent = null; IEdmType parentType = null; if (state.ImplicitRangeVariable != null) { if (dottedIdentifierToken.NextToken == null) { parent = NodeFactory.CreateRangeVariableReferenceNode(state.ImplicitRangeVariable); parentType = state.ImplicitRangeVariable.TypeReference.Definition; } else { parent = this.bindMethod(dottedIdentifierToken.NextToken); parentType = parent.GetEdmType(); } } SingleResourceNode parentAsSingleResource = parent as SingleResourceNode; IEdmSchemaType childType = UriEdmHelpers.FindTypeFromModel(state.Model, dottedIdentifierToken.Identifier, this.Resolver); IEdmStructuredType childStructuredType = childType as IEdmStructuredType; if (childStructuredType == null) { SingleValueNode singleValueNode = parent as SingleValueNode; FunctionCallBinder functionCallBinder = new FunctionCallBinder(bindMethod, state); QueryNode functionCallNode; if (functionCallBinder.TryBindDottedIdentifierAsFunctionCall(dottedIdentifierToken, singleValueNode, out functionCallNode)) { return(functionCallNode); } else if ((!string.IsNullOrEmpty(dottedIdentifierToken.Identifier)) && (dottedIdentifierToken.Identifier[dottedIdentifierToken.Identifier.Length - 1] == '\'')) { // check if it is enum or not QueryNode enumNode; if (EnumBinder.TryBindDottedIdentifierAsEnum(dottedIdentifierToken, parentAsSingleResource, state, this.Resolver, out enumNode)) { return(enumNode); } else { throw new ODataException(ODataErrorStrings.Binder_IsNotValidEnumConstant(dottedIdentifierToken.Identifier)); } } else { IEdmTypeReference edmTypeReference = UriEdmHelpers.FindTypeFromModel(state.Model, dottedIdentifierToken.Identifier, this.Resolver).ToTypeReference(); if (edmTypeReference is IEdmPrimitiveTypeReference || edmTypeReference is IEdmEnumTypeReference) { IEdmPrimitiveType childPrimitiveType = childType as IEdmPrimitiveType; if (childPrimitiveType != null && dottedIdentifierToken.NextToken != null) { return(new SingleValueCastNode(singleValueNode, childPrimitiveType)); } else { return(new ConstantNode(dottedIdentifierToken.Identifier, dottedIdentifierToken.Identifier)); } } else { throw new ODataException(ODataErrorStrings.CastBinder_ChildTypeIsNotEntity(dottedIdentifierToken.Identifier)); } } } // Check whether childType is a derived type of the type of its parent node UriEdmHelpers.CheckRelatedTo(parentType, childType); this.state.ParsedSegments.Add(new TypeSegment(childType, parentType, null)); CollectionResourceNode parentAsCollection = parent as CollectionResourceNode; if (parentAsCollection != null) { return(new CollectionResourceCastNode(parentAsCollection, childStructuredType)); } return(new SingleResourceCastNode(parentAsSingleResource, childStructuredType)); }