internal string GetEntryTypeNameForWriting(ODataEntry entry) { Debug.Assert(entry != null, "entry != null"); SerializationTypeNameAnnotation typeNameAnnotation = entry.GetAnnotation <SerializationTypeNameAnnotation>(); if (typeNameAnnotation != null) { return(typeNameAnnotation.TypeName); } return(entry.TypeName); }
internal string GetValueTypeNameForWriting( object value, IEdmTypeReference typeReferenceFromValue, SerializationTypeNameAnnotation typeNameAnnotation, CollectionWithoutExpectedTypeValidator collectionValidator, out string collectionItemTypeName) { Debug.Assert(value != null, "value != null"); collectionItemTypeName = null; // if no type name is specified we will use the type name inferred from metadata string typeName = GetTypeNameFromValue(value); if (typeName == null && typeReferenceFromValue != null) { typeName = typeReferenceFromValue.ODataFullName(); } if (typeName != null) { // If the type is the same as the one specified by the parent collection, omit the type name, since it's not needed. if (collectionValidator != null && string.CompareOrdinal(collectionValidator.ItemTypeNameFromCollection, typeName) == 0) { typeName = null; } // If value is a collection value, get the item type name. if (typeName != null && value is ODataCollectionValue) { collectionItemTypeName = ValidationUtils.ValidateCollectionTypeName(typeName); } } if (typeNameAnnotation != null) { // If the value of TypeName is null, we'll flow it through here, thereby instructing the caller to write no type name. typeName = typeNameAnnotation.TypeName; } return(typeName); }
internal string GetValueTypeNameForWriting( object value, IEdmTypeReference typeReferenceFromValue, SerializationTypeNameAnnotation typeNameAnnotation, CollectionWithoutExpectedTypeValidator collectionValidator, out string collectionItemTypeName) { Debug.Assert(value != null, "value != null"); collectionItemTypeName = null; // if no type name is specified we will use the type name inferred from metadata string typeName = GetTypeNameFromValue(value); if (typeName == null && typeReferenceFromValue != null) { typeName = typeReferenceFromValue.ODataFullName(); } if (typeName != null) { // If the type is the same as the one specified by the parent collection, omit the type name, since it's not needed. if (collectionValidator != null && string.CompareOrdinal(collectionValidator.ItemTypeNameFromCollection, typeName) == 0) { typeName = null; } // If value is a collection value, get the item type name. if (typeName != null && value is ODataCollectionValue) { collectionItemTypeName = ValidationUtils.ValidateCollectionTypeName(typeName); } } if (typeNameAnnotation != null) { // If the value of TypeName is null, we'll flow it through here, thereby instructing the caller to write no type name. typeName = typeNameAnnotation.TypeName; } return typeName; }
/// <summary> /// Resolves and validates the payload type against the expected type and returns the target type. /// </summary> /// <param name="expectedTypeKind">The expected type kind for the value.</param> /// <param name="defaultPrimitivePayloadType">The default payload type if none is specified in the payload; /// for ATOM this is Edm.String, for JSON it is null since there is no payload type name for primitive types in the payload.</param> /// <param name="expectedTypeReference">The expected type reference, or null if no expected type is available.</param> /// <param name="payloadTypeName">The payload type name, or null if no payload type was specified.</param> /// <param name="model">The model to use.</param> /// <param name="messageReaderSettings">The message reader settings to use.</param> /// <param name="typeKindFromPayloadFunc">A func to compute the type kind from the payload shape if it could not be determined from the expected type or the payload type.</param> /// <param name="targetTypeKind">The target type kind to be used to read the payload.</param> /// <param name="serializationTypeNameAnnotation">Potentially non-null instance of an annotation to put on the value reported from the reader.</param> /// <returns> /// The target type reference to use for parsing the value. /// If there is no user specified model, this will return null. /// If there is a user specified model, this method never returns null. /// </returns> /// <remarks> /// This method cannot be used for primitive type resolution. Primitive type resolution is format dependent and format specific methods should be used instead. /// </remarks> internal static IEdmTypeReference ResolvePayloadTypeNameAndComputeTargetType( EdmTypeKind expectedTypeKind, IEdmType defaultPrimitivePayloadType, IEdmTypeReference expectedTypeReference, string payloadTypeName, IEdmModel model, ODataMessageReaderSettings messageReaderSettings, Func<EdmTypeKind> typeKindFromPayloadFunc, out EdmTypeKind targetTypeKind, out SerializationTypeNameAnnotation serializationTypeNameAnnotation) { Debug.Assert(typeKindFromPayloadFunc != null, "typeKindFromPayloadFunc != null"); serializationTypeNameAnnotation = null; // What is the right behavior if both expected and actual types are specified for complex value? // We decided that they have to match exactly. // Resolve the type name and get the payload type kind; that is the type kind of the payload // type if available or the expected type kind if no payload type could be resolved. Since // we always detect primitive and collection types the expected type for unrecognized payload // types is EdmTypeKind.Complex. EdmTypeKind payloadTypeKind; IEdmType payloadType = ResolvePayloadTypeName( model, expectedTypeReference, payloadTypeName, EdmTypeKind.Complex, messageReaderSettings.ReaderBehavior, out payloadTypeKind); // Compute the target type kind based on the expected type, the payload type kind // and a function to detect the target type kind from the shape of the payload. targetTypeKind = ComputeTargetTypeKind( expectedTypeReference, /*forEntityValue*/ expectedTypeKind == EdmTypeKind.Entity, payloadTypeName, payloadTypeKind, messageReaderSettings, typeKindFromPayloadFunc); // Resolve potential conflicts between payload and expected types and apply all the various behavior changing flags from settings IEdmTypeReference targetTypeReference; if (targetTypeKind == EdmTypeKind.Primitive) { targetTypeReference = ReaderValidationUtils.ResolveAndValidatePrimitiveTargetType( expectedTypeReference, payloadTypeKind, payloadType, payloadTypeName, defaultPrimitivePayloadType, model, messageReaderSettings); } else { targetTypeReference = ReaderValidationUtils.ResolveAndValidateNonPrimitiveTargetType( targetTypeKind, expectedTypeReference, payloadTypeKind, payloadType, payloadTypeName, model, messageReaderSettings); if (targetTypeReference != null) { serializationTypeNameAnnotation = CreateSerializationTypeNameAnnotation(payloadTypeName, targetTypeReference); } } if (expectedTypeKind != EdmTypeKind.None && targetTypeReference != null) { ValidationUtils.ValidateTypeKind(targetTypeKind, expectedTypeKind, payloadTypeName); } return targetTypeReference; }
public void TypeNameShouldComeFromSerializationTypeNameAnnotationForCollectionValue() { var stna = new SerializationTypeNameAnnotation() {TypeName = "FromSTNA"}; var value = new ODataCollectionValue() {TypeName = "Collection(Edm.String)"}; value.SetAnnotation(stna); this.typeNameOracle.GetValueTypeNameForWriting(value, EdmCoreModel.GetCollection(EdmCoreModel.Instance.GetString(true)), EdmCoreModel.GetCollection(EdmCoreModel.Instance.GetString(false)), /* isOpenProperty*/ false).Should().Be("FromSTNA"); }
public void TypeNameShouldComeFromSerializationTypeNameAnnotationForComplexValue() { var stna = new SerializationTypeNameAnnotation() {TypeName = "FromSTNA"}; var value = new ODataComplexValue() {TypeName = "Model.Bla"}; value.SetAnnotation(stna); this.typeNameOracle.GetValueTypeNameForWriting(value, new EdmComplexTypeReference(new EdmComplexType("Model", "Bla"), true), new EdmComplexTypeReference(new EdmComplexType("Model", "Bla"), false), /* isOpenProperty*/ false).Should().Be("FromSTNA"); }
public void TypeNameShouldComeFromSerializationTypeNameAnnotationForPrimitiveValue() { var stna = new SerializationTypeNameAnnotation() {TypeName = "FromSTNA"}; var value = new ODataPrimitiveValue(42); value.SetAnnotation(stna); this.typeNameOracle.GetValueTypeNameForWriting(value, EdmCoreModel.Instance.GetInt32(true), EdmCoreModel.Instance.GetInt32(false), /* isOpenProperty*/ false).Should().Be("FromSTNA"); }