internal ClientTypeAnnotation ResolveEdmTypeName(Type expectedType, string edmTypeName) { ClientTypeAnnotation clientTypeAnnotation; PrimitiveType type; string collectionItemWireTypeName = WebUtil.GetCollectionItemWireTypeName(edmTypeName); string str2 = collectionItemWireTypeName ?? edmTypeName; ClientEdmModel model = ClientEdmModel.GetModel(this.ResponseInfo.MaxProtocolVersion); if (PrimitiveType.TryGetPrimitiveType(str2, out type)) { clientTypeAnnotation = model.GetClientTypeAnnotation(type.ClrType); } else if (!this.edmTypeNameMap.TryGetValue(str2, out clientTypeAnnotation)) { clientTypeAnnotation = model.GetClientTypeAnnotation(str2); } if (collectionItemWireTypeName == null) { return(clientTypeAnnotation); } Type elementType = clientTypeAnnotation.ElementType; if (type != null) { elementType = ClientTypeUtil.GetImplementationType(expectedType, typeof(ICollection <>)).GetGenericArguments()[0]; } Type backingTypeForCollectionProperty = WebUtil.GetBackingTypeForCollectionProperty(expectedType, elementType); return(model.GetClientTypeAnnotation(backingTypeForCollectionProperty)); }
/// <summary> /// Get the client type annotation for the given name. /// </summary> /// <param name="edmTypeName">Name of the type.</param> /// <returns>An instance of ClientTypeAnnotation for the type with the given name.</returns> internal ClientTypeAnnotation GetClientTypeAnnotation(string edmTypeName) { Debug.Assert(WebUtil.GetCollectionItemWireTypeName(edmTypeName) == null, "This method must not be called for collections"); IEdmType result = this.clrToEdmTypeCache.Values.First(e => e.EdmType.FullName() == edmTypeName).EdmType; Debug.Assert(result != null, "result != null"); return(this.GetClientTypeAnnotation(result)); }
/// <summary> /// Resolves the client type that should be used for materialization. /// </summary> /// <param name="expectedType">Expected client clr type based on the API called.</param> /// <param name="readerTypeName"> /// The name surfaced by the ODataLib reader. /// If we have a server model, this will be a server type name that needs to be resolved. /// If not, then this will already be a client type name.</param> /// <returns>The resolved annotation for the client type to materialize into.</returns> internal ClientTypeAnnotation ResolveTypeForMaterialization(Type expectedType, string readerTypeName) { // If its a collection, get the collection item name string collectionItemTypeName = WebUtil.GetCollectionItemWireTypeName(readerTypeName); if (collectionItemTypeName == null) { // Resolve the primitive type first PrimitiveType primitiveType; if (PrimitiveType.TryGetPrimitiveType(readerTypeName, out primitiveType)) { return(this.clientEdmModel.GetClientTypeAnnotation(primitiveType.ClrType)); } ClientTypeAnnotation resultType; if (this.edmTypeNameMap.TryGetValue(readerTypeName, out resultType)) { return(resultType); } if (this.serviceModel != null) { var resolvedType = this.ResolveTypeFromName(readerTypeName, expectedType); return(this.clientEdmModel.GetClientTypeAnnotation(resolvedType)); } // If there was no type name specified in the payload, then the type resolver won't be invoked // and hence that edm type name might not be in the resolver cache. Hence look that up in the // ClientEdmModel cache. This lookup is more expensive and is unique across the app domain for the // given version. return(this.clientEdmModel.GetClientTypeAnnotation(readerTypeName)); } Type collectionImplementationType = ClientTypeUtil.GetImplementationType(expectedType, typeof(ICollection <>)); Type collectionElementType = collectionImplementationType.GetGenericArguments()[0]; // In case of collection, the expectedType might be collection of nullable types (for e.g. ICollection<int?>). // There is no way to know the nullability from the wireTypeName (For e.g. Collection(Edm.Int32)). // Hence in case of collections of primitives, we need to look at the element type of the expected type // and use that to create the instance otherwise we will not be able to assign the created ICollection<> // instance to the property on the user's entity (ICollection<int> cannot be assigned to ICollection<int?>). // There is also no need to invoke the resolver for primitives, so we just use the element type. if (!PrimitiveType.IsKnownType(collectionElementType)) { collectionElementType = this.ResolveTypeForMaterialization(collectionElementType, collectionItemTypeName).ElementType; } Type clrCollectionType = WebUtil.GetBackingTypeForCollectionProperty(expectedType, collectionElementType); return(this.clientEdmModel.GetClientTypeAnnotation(clrCollectionType)); }