Пример #1
0
 static ClientEdmModel()
 {
     foreach (DataServiceProtocolVersion version in Enum.GetValues(typeof(DataServiceProtocolVersion)).Cast<DataServiceProtocolVersion>())
     {
         ClientEdmModel model = new ClientEdmModel(version);
         model.SetEdmVersion(version.ToVersion());
         modelCache.Add(version, model);
     }
 }
Пример #2
0
        /// <summary>
        /// Get or create a client EDM type instance.
        /// </summary>
        /// <param name="type">type to wrap</param>
        /// <returns>client type</returns>
        private EdmTypeCacheValue GetOrCreateEdmTypeInternal(Type type)
        {
            Debug.Assert(type != null, "type != null");

            EdmTypeCacheValue cachedEdmType;

            lock (this.clrToEdmTypeCache)
            {
                this.clrToEdmTypeCache.TryGetValue(type, out cachedEdmType);
            }

            if (cachedEdmType == null)
            {
                if (PrimitiveType.IsKnownNullableType(type))
                {
                    cachedEdmType = this.GetOrCreateEdmTypeInternal(null /*baseType*/, type, ClientTypeUtil.EmptyPropertyInfoArray, false /*isEntity*/, false /*hasProperties*/);
                }
                else
                {
                    PropertyInfo[] keyProperties;
                    bool           hasProperties;
                    Type[]         hierarchy = ClientEdmModel.GetTypeHierarchy(type, out keyProperties, out hasProperties);

                    Debug.Assert(keyProperties == null || keyProperties.Length == 0 || keyProperties.All(p => p.DeclaringType == keyProperties[0].DeclaringType), "All key properties must be declared on the same type.");

                    bool isEntity = keyProperties != null;
                    keyProperties = keyProperties ?? ClientTypeUtil.EmptyPropertyInfoArray;
                    foreach (Type t in hierarchy)
                    {
                        // Pass in the full list of key properties for the most base type to be added there.  We only allow key properties to be
                        // declared on the same type.
                        IEdmStructuredType edmBaseType = cachedEdmType == null ? null : cachedEdmType.EdmType as IEdmStructuredType;
                        cachedEdmType = this.GetOrCreateEdmTypeInternal(edmBaseType, t, keyProperties, isEntity, t == type ? hasProperties : (bool?)null);

                        // Pass in an empty PropertyInfo array on subsequent derived types.
                        keyProperties = ClientTypeUtil.EmptyPropertyInfoArray;
                    }
                }
            }

            Debug.Assert(cachedEdmType != null, "cachedEdmType != null");
            return(cachedEdmType);
        }
Пример #3
0
        internal IEdmType ResolveWireTypeName(IEdmType expectedEdmType, string wireName)
        {
            Type           elementType;
            ClientEdmModel model = ClientEdmModel.GetModel(this.ResponseInfo.MaxProtocolVersion);

            if (expectedEdmType != null)
            {
                ClientTypeAnnotation annotation = model.GetClientTypeAnnotation(expectedEdmType);
                elementType = annotation.ElementType;
                if (annotation.EdmType.TypeKind == EdmTypeKind.Primitive)
                {
                    return(expectedEdmType);
                }
            }
            else
            {
                elementType = typeof(object);
            }
            Type type2 = this.ResolveTypeFromName(wireName, elementType);
            ClientTypeAnnotation clientTypeAnnotation = model.GetClientTypeAnnotation(model.GetOrCreateEdmType(type2));

            if (clientTypeAnnotation.IsEntityType)
            {
                clientTypeAnnotation.EnsureEPMLoaded();
            }
            switch (clientTypeAnnotation.EdmType.TypeKind)
            {
            case EdmTypeKind.Entity:
            case EdmTypeKind.Complex:
            {
                string key = clientTypeAnnotation.EdmType.FullName();
                if (!this.edmTypeNameMap.ContainsKey(key))
                {
                    this.edmTypeNameMap.Add(key, clientTypeAnnotation);
                }
                break;
            }
            }
            return(clientTypeAnnotation.EdmType);
        }
Пример #4
0
        internal QueryOperationResponse LoadProperty()
        {
            MaterializeAtom        results = null;
            QueryOperationResponse responseWithType;
            DataServiceContext     source = (DataServiceContext)base.Source;
            ClientEdmModel         model  = ClientEdmModel.GetModel(source.MaxProtocolVersion);
            ClientTypeAnnotation   clientTypeAnnotation = model.GetClientTypeAnnotation(model.GetOrCreateEdmType(this.entity.GetType()));
            EntityDescriptor       entityDescriptor     = source.GetEntityDescriptor(this.entity);

            if (EntityStates.Added == entityDescriptor.State)
            {
                throw System.Data.Services.Client.Error.InvalidOperation(System.Data.Services.Client.Strings.Context_NoLoadWithInsertEnd);
            }
            ClientPropertyAnnotation property = clientTypeAnnotation.GetProperty(this.propertyName, false);
            Type elementType = property.EntityCollectionItemType ?? property.NullablePropertyType;

            try
            {
                if (clientTypeAnnotation.MediaDataMember == property)
                {
                    results = this.ReadPropertyFromRawData(property);
                }
                else
                {
                    results = this.ReadPropertyFromAtom(entityDescriptor, property);
                }
                responseWithType = base.GetResponseWithType(results, elementType);
            }
            catch (InvalidOperationException exception)
            {
                QueryOperationResponse response = base.GetResponseWithType(results, elementType);
                if (response != null)
                {
                    response.Error = exception;
                    throw new DataServiceQueryException(System.Data.Services.Client.Strings.DataServiceException_GeneralError, exception, response);
                }
                throw;
            }
            return(responseWithType);
        }
Пример #5
0
        internal void WriteEntry(EntityDescriptor entityDescriptor, IEnumerable <LinkDescriptor> relatedLinks, ODataRequestMessageWrapper requestMessage)
        {
            ClientEdmModel       model = ClientEdmModel.GetModel(this.requestInfo.MaxProtocolVersion);
            ClientTypeAnnotation clientTypeAnnotation = model.GetClientTypeAnnotation(model.GetOrCreateEdmType(entityDescriptor.Entity.GetType()));

            using (ODataMessageWriter writer = CreateMessageWriter(requestMessage, this.requestInfo))
            {
                ODataWriter odataWriter = writer.CreateODataEntryWriter();
                ODataEntry  entry       = new ODataEntry();
                if (this.requestInfo.HasWritingEventHandlers)
                {
                    entry.SetAnnotation <WritingEntityInfo>(new WritingEntityInfo(entityDescriptor.Entity, this.requestInfo));
                }
                string serverTypeName = this.requestInfo.GetServerTypeName(entityDescriptor);
                if (clientTypeAnnotation.ElementTypeName != serverTypeName)
                {
                    SerializationTypeNameAnnotation annotation = new SerializationTypeNameAnnotation {
                        TypeName = serverTypeName
                    };
                    entry.SetAnnotation <SerializationTypeNameAnnotation>(annotation);
                }
                entry.TypeName = clientTypeAnnotation.ElementTypeName;
                if (EntityStates.Modified == entityDescriptor.State)
                {
                    entry.Id = entityDescriptor.GetLatestIdentity();
                }
                if (entityDescriptor.IsMediaLinkEntry || clientTypeAnnotation.IsMediaLinkEntry)
                {
                    entry.MediaResource = new ODataStreamReferenceValue();
                }
                odataWriter.WriteStart(entry);
                if (EntityStates.Added == entityDescriptor.State)
                {
                    this.WriteNavigationLink(entityDescriptor, relatedLinks, odataWriter);
                }
                entry.Properties = this.PopulateProperties(clientTypeAnnotation, entityDescriptor.Entity, null);
                odataWriter.WriteEnd();
            }
        }
Пример #6
0
        internal void AttachLink(object source, string sourceProperty, object target, MergeOption linkMerge)
        {
            LinkDescriptor linkDescriptor = new LinkDescriptor(source, sourceProperty, target, this.maxProtocolVersion);
            LinkDescriptor descriptor2    = this.TryGetLinkDescriptor(source, sourceProperty, target);

            if (descriptor2 != null)
            {
                switch (linkMerge)
                {
                case MergeOption.OverwriteChanges:
                    linkDescriptor = descriptor2;
                    break;

                case MergeOption.PreserveChanges:
                    if (((EntityStates.Added == descriptor2.State) || (EntityStates.Unchanged == descriptor2.State)) || ((EntityStates.Modified == descriptor2.State) && (descriptor2.Target != null)))
                    {
                        linkDescriptor = descriptor2;
                    }
                    break;

                case MergeOption.NoTracking:
                    throw System.Data.Services.Client.Error.InvalidOperation(System.Data.Services.Client.Strings.Context_RelationAlreadyContained);
                }
            }
            else
            {
                ClientEdmModel model = ClientEdmModel.GetModel(this.maxProtocolVersion);
                if (model.GetClientTypeAnnotation(model.GetOrCreateEdmType(source.GetType())).GetProperty(sourceProperty, false).IsEntityCollection || ((descriptor2 = this.DetachReferenceLink(source, sourceProperty, target, linkMerge)) == null))
                {
                    this.AddLink(linkDescriptor);
                    this.IncrementChange(linkDescriptor);
                }
                else if ((linkMerge != MergeOption.AppendOnly) && ((MergeOption.PreserveChanges != linkMerge) || (EntityStates.Modified != descriptor2.State)))
                {
                    linkDescriptor = descriptor2;
                }
            }
            linkDescriptor.State = EntityStates.Unchanged;
        }
Пример #7
0
        /// <summary>
        /// Write the entry element.
        /// </summary>
        /// <param name="entityDescriptor">The entity.</param>
        /// <param name="relatedLinks">Collection of links related to the entity.</param>
        /// <param name="requestMessage">The OData request message.</param>
        internal void WriteEntry(EntityDescriptor entityDescriptor, IEnumerable <LinkDescriptor> relatedLinks, ODataRequestMessageWrapper requestMessage)
        {
            ClientEdmModel       model      = this.requestInfo.Model;
            ClientTypeAnnotation entityType = model.GetClientTypeAnnotation(model.GetOrCreateEdmType(entityDescriptor.Entity.GetType()));

            using (ODataMessageWriter messageWriter = Serializer.CreateMessageWriter(requestMessage, this.requestInfo, false /*isParameterPayload*/))
            {
                ODataWriterWrapper entryWriter = ODataWriterWrapper.CreateForEntry(messageWriter, this.requestInfo.Configurations.RequestPipeline);

                // Get the server type name using the type resolver or from the entity descriptor
                string serverTypeName = this.requestInfo.GetServerTypeName(entityDescriptor);

                var entry = CreateODataEntry(entityDescriptor, serverTypeName, entityType, this.requestInfo.Format);

                // Add the annotation required for writing the payload into an XElement
                // for firing WritingEntity events
                if (this.requestInfo.HasWritingEventHandlers)
                {
                    entry.SetAnnotation(new WritingEntityInfo(entityDescriptor.Entity, this.requestInfo));
                }

                if (serverTypeName == null)
                {
                    serverTypeName = this.requestInfo.InferServerTypeNameFromServerModel(entityDescriptor);
                }

                entry.Properties = this.propertyConverter.PopulateProperties(entityDescriptor.Entity, serverTypeName, entityType.PropertiesToSerialize());

                entryWriter.WriteStart(entry, entityDescriptor.Entity);

                if (EntityStates.Added == entityDescriptor.State)
                {
                    this.WriteNavigationLink(entityDescriptor, relatedLinks, entryWriter);
                }

                entryWriter.WriteEnd(entry, entityDescriptor.Entity);
            }
        }
Пример #8
0
        /// <summary>
        /// Initializes a new instance of the <see cref="ClientEdmStructuredValue"/> class.
        /// </summary>
        /// <param name="structuredValue">The structured value.</param>
        /// <param name="model">The model.</param>
        /// <param name="clientTypeAnnotation">The client type annotation.</param>
        public ClientEdmStructuredValue(object structuredValue, ClientEdmModel model, ClientTypeAnnotation clientTypeAnnotation)
        {
            Debug.Assert(structuredValue != null, "entity != null");
            Debug.Assert(model != null, "model != null");
            Debug.Assert(clientTypeAnnotation != null, "clientTypeAnnotation != null");

            if (clientTypeAnnotation.EdmType.TypeKind == EdmTypeKind.Complex)
            {
                // TODO: nullable?
                this.Type = new EdmComplexTypeReference((IEdmComplexType)clientTypeAnnotation.EdmType, true);
            }
            else
            {
                Debug.Assert(clientTypeAnnotation.EdmType.TypeKind == EdmTypeKind.Entity, "Only complex and entity values supported");

                // TODO: nullable?
                this.Type = new EdmEntityTypeReference((IEdmEntityType)clientTypeAnnotation.EdmType, true);
            }

            this.structuredValue = structuredValue;
            this.typeAnnotation  = clientTypeAnnotation;
            this.model           = model;
        }
Пример #9
0
        /// <summary>
        /// Get the entity set name for the target entity object.
        /// </summary>
        /// <param name="target">An entity object.</param>
        /// <param name="targetEntitySet">The 'currently known' entity set name for the target object.</param>
        /// <param name="model">The client model.</param>
        /// <returns>The entity set name for the target object.</returns>
        /// <remarks>
        /// Allow user code to provide the entity set name. If user code does not provide the entity set name, then
        /// this method will get the entity set name from the value of the EntitySetAttribute.
        /// The 'currently known' entity set name for top level collections can be provided through OEC constructor
        /// </remarks>
        internal static string GetEntitySet(
            object target,
            string targetEntitySet,
            ClientEdmModel model)
        {
            Debug.Assert(target != null, "Argument 'target' cannot be null.");
            Debug.Assert(BindingEntityInfo.IsEntityType(target.GetType(), model), "Argument 'target' must be an entity type.");

            // Here's the rules in order of priority for resolving entity set name
            // 1. EntitySet name passed in the constructor or extension methods of DataServiceCollection
            // 2. EntitySet name specified in the EntitySet attribute by the code gen. {Remember this attribute is
            //    not generated in case of MEST)
            if (!String.IsNullOrEmpty(targetEntitySet))
            {
                return(targetEntitySet);
            }
            else
            {
                // If there is not a 'currently known' entity set name to validate against, then there must be
                // EntitySet attribute on the entity type
                return(BindingEntityInfo.GetEntitySetAttribute(target.GetType(), model));
            }
        }
Пример #10
0
        /// <summary>
        /// Checks if the provided type is a collection type (i.e. it implements ICollection and the collection item type is not an entity).
        /// </summary>
        /// <param name="type">Type being checked.</param>
        /// <param name="model">The client model.</param>
        /// <returns>True if the CLR type is a collection compatible type. False otherwise.</returns>
        internal static bool IsCLRTypeCollection(Type type, ClientEdmModel model)
        {
            // char[] and byte[] implements ICollection<> but we should not threat them as collections since they are primitive types for us.
            if (!PrimitiveType.IsKnownNullableType(type))
            {
                Type collectionType = ClientTypeUtil.GetImplementationType(type, typeof(ICollection <>));
                if (collectionType != null)
                {
                    // collectionType is ICollection so we know that the first generic parameter
                    // is the collection item type
                    if (!ClientTypeUtil.TypeIsEntity(collectionType.GetGenericArguments()[0], model))
                    {
                        if (model.MaxProtocolVersion <= DataServiceProtocolVersion.V2)
                        {
                            throw new InvalidOperationException(Strings.WebUtil_CollectionTypeNotSupportedInV2OrBelow(type.FullName));
                        }

                        return(true);
                    }
                }
            }

            return(false);
        }
Пример #11
0
        private ODataRequestMessageWrapper CheckAndProcessMediaEntryPost(EntityDescriptor entityDescriptor)
        {
            ClientEdmModel       model = ClientEdmModel.GetModel(base.RequestInfo.MaxProtocolVersion);
            ClientTypeAnnotation clientTypeAnnotation = model.GetClientTypeAnnotation(model.GetOrCreateEdmType(entityDescriptor.Entity.GetType()));

            if (!clientTypeAnnotation.IsMediaLinkEntry && !entityDescriptor.IsMediaLinkEntry)
            {
                return(null);
            }
            if ((clientTypeAnnotation.MediaDataMember == null) && (entityDescriptor.SaveStream == null))
            {
                throw System.Data.Services.Client.Error.InvalidOperation(System.Data.Services.Client.Strings.Context_MLEWithoutSaveStream(clientTypeAnnotation.ElementTypeName));
            }
            ODataRequestMessageWrapper mediaResourceRequest = null;

            if (clientTypeAnnotation.MediaDataMember != null)
            {
                string contentType = null;
                int    length      = 0;
                if (clientTypeAnnotation.MediaDataMember.MimeTypeProperty == null)
                {
                    contentType = "application/octet-stream";
                }
                else
                {
                    object obj2 = clientTypeAnnotation.MediaDataMember.MimeTypeProperty.GetValue(entityDescriptor.Entity);
                    string str2 = (obj2 != null) ? obj2.ToString() : null;
                    if (string.IsNullOrEmpty(str2))
                    {
                        throw System.Data.Services.Client.Error.InvalidOperation(System.Data.Services.Client.Strings.Context_NoContentTypeForMediaLink(clientTypeAnnotation.ElementTypeName, clientTypeAnnotation.MediaDataMember.MimeTypeProperty.PropertyName));
                    }
                    contentType = str2;
                }
                object propertyValue = clientTypeAnnotation.MediaDataMember.GetValue(entityDescriptor.Entity);
                if (propertyValue == null)
                {
                    base.mediaResourceRequestStream = null;
                }
                else
                {
                    byte[] bytes = propertyValue as byte[];
                    if (bytes == null)
                    {
                        string   str3;
                        Encoding encoding;
                        HttpProcessUtility.ReadContentType(contentType, out str3, out encoding);
                        if (encoding == null)
                        {
                            encoding    = Encoding.UTF8;
                            contentType = contentType + ";charset=UTF-8";
                        }
                        bytes = encoding.GetBytes(ClientConvert.ToString(propertyValue));
                    }
                    length = bytes.Length;
                    base.mediaResourceRequestStream = new MemoryStream(bytes, 0, bytes.Length, false, true);
                }
                mediaResourceRequest = this.CreateMediaResourceRequest(entityDescriptor.GetResourceUri(base.RequestInfo.BaseUriResolver, false), "POST", Util.DataServiceVersion1, clientTypeAnnotation.MediaDataMember == null, true);
                mediaResourceRequest.SetHeader("Content-Length", length.ToString(CultureInfo.InvariantCulture));
                mediaResourceRequest.SetHeader("Content-Type", contentType);
                mediaResourceRequest.AddHeadersToReset("Content-Length");
                mediaResourceRequest.AddHeadersToReset("Content-Type");
            }
            else
            {
                mediaResourceRequest = this.CreateMediaResourceRequest(entityDescriptor.GetResourceUri(base.RequestInfo.BaseUriResolver, false), "POST", Util.DataServiceVersion1, clientTypeAnnotation.MediaDataMember == null, true);
                this.SetupMediaResourceRequest(mediaResourceRequest, entityDescriptor.SaveStream, null);
            }
            entityDescriptor.State = EntityStates.Modified;
            return(mediaResourceRequest);
        }
Пример #12
0
        private static BindingEntityInfoPerType GetBindingEntityInfoFor(Type entityType, DataServiceProtocolVersion maxProtocolVersion)
        {
            BindingEntityInfoPerType type;

            metadataCacheLock.EnterReadLock();
            try
            {
                if (bindingEntityInfos.TryGetValue(entityType, out type))
                {
                    return(type);
                }
            }
            finally
            {
                metadataCacheLock.ExitReadLock();
            }
            type = new BindingEntityInfoPerType();
            EntitySetAttribute attribute = (EntitySetAttribute)entityType.GetCustomAttributes(typeof(EntitySetAttribute), true).SingleOrDefault <object>();
            ClientEdmModel     model     = ClientEdmModel.GetModel(maxProtocolVersion);

            type.EntitySet  = (attribute != null) ? attribute.EntitySet : null;
            type.ClientType = model.GetClientTypeAnnotation(model.GetOrCreateEdmType(entityType));
            foreach (ClientPropertyAnnotation annotation in type.ClientType.Properties())
            {
                BindingPropertyInfo item = null;
                Type propertyType        = annotation.PropertyType;
                if (!annotation.IsStreamLinkProperty)
                {
                    if (annotation.IsPrimitiveOrComplexCollection)
                    {
                        item = new BindingPropertyInfo {
                            PropertyKind = BindingPropertyKind.BindingPropertyKindPrimitiveOrComplexCollection
                        };
                    }
                    else if (annotation.IsEntityCollection)
                    {
                        if (IsDataServiceCollection(propertyType, maxProtocolVersion))
                        {
                            item = new BindingPropertyInfo {
                                PropertyKind = BindingPropertyKind.BindingPropertyKindDataServiceCollection
                            };
                        }
                    }
                    else if (IsEntityType(propertyType, maxProtocolVersion))
                    {
                        item = new BindingPropertyInfo {
                            PropertyKind = BindingPropertyKind.BindingPropertyKindEntity
                        };
                    }
                    else if (CanBeComplexType(propertyType))
                    {
                        item = new BindingPropertyInfo {
                            PropertyKind = BindingPropertyKind.BindingPropertyKindComplex
                        };
                    }
                    if (item != null)
                    {
                        item.PropertyInfo = annotation;
                        if ((type.ClientType.IsEntityType || (item.PropertyKind == BindingPropertyKind.BindingPropertyKindComplex)) || (item.PropertyKind == BindingPropertyKind.BindingPropertyKindPrimitiveOrComplexCollection))
                        {
                            type.ObservableProperties.Add(item);
                        }
                    }
                }
            }
            metadataCacheLock.EnterWriteLock();
            try
            {
                if (!bindingEntityInfos.ContainsKey(entityType))
                {
                    bindingEntityInfos[entityType] = type;
                }
            }
            finally
            {
                metadataCacheLock.ExitWriteLock();
            }
            return(type);
        }
 internal ODataMessageWriter CreateWriter(ODataMessageWriterSettings writerSettings)
 {
     return(new ODataMessageWriter(this.requestMessage, writerSettings, ClientEdmModel.GetModel(this.requestInfo.MaxProtocolVersion)));
 }
Пример #14
0
        private string ConvertToEscapedUriValue(string paramName, object value)
        {
            object obj2 = null;
            string str;
            bool   flag = false;

            if (value == null)
            {
                flag = true;
            }
            else if (value.GetType() == typeof(ODataUriNullValue))
            {
                obj2 = value;
                flag = true;
            }
            else
            {
                ClientTypeAnnotation annotation3;
                ClientEdmModel       model           = ClientEdmModel.GetModel(this.requestInfo.MaxProtocolVersion);
                IEdmType             orCreateEdmType = model.GetOrCreateEdmType(value.GetType());
                switch (orCreateEdmType.TypeKind)
                {
                case EdmTypeKind.Primitive:
                    obj2 = value;
                    flag = true;
                    goto Label_0155;

                case EdmTypeKind.Complex:
                {
                    ClientTypeAnnotation clientTypeAnnotation = model.GetClientTypeAnnotation(orCreateEdmType);
                    obj2 = this.CreateODataComplexValue(clientTypeAnnotation.ElementType, value, null, false, null);
                    SerializationTypeNameAnnotation annotation = ((ODataComplexValue)obj2).GetAnnotation <SerializationTypeNameAnnotation>();
                    if ((annotation == null) || string.IsNullOrEmpty(annotation.TypeName))
                    {
                        throw System.Data.Services.Client.Error.InvalidOperation(System.Data.Services.Client.Strings.DataServiceException_GeneralError);
                    }
                    goto Label_0155;
                }

                case EdmTypeKind.Collection:
                {
                    IEdmCollectionType type2       = orCreateEdmType as IEdmCollectionType;
                    IEdmTypeReference  elementType = type2.ElementType;
                    annotation3 = model.GetClientTypeAnnotation(elementType.Definition);
                    switch (annotation3.EdmType.TypeKind)
                    {
                    case EdmTypeKind.Primitive:
                    case EdmTypeKind.Complex:
                        obj2 = this.CreateODataCollection(annotation3.ElementType, null, value, null);
                        goto Label_0155;
                    }
                    break;
                }

                default:
                    throw new NotSupportedException(System.Data.Services.Client.Strings.Serializer_InvalidParameterType(paramName, orCreateEdmType.TypeKind));
                }
                throw new NotSupportedException(System.Data.Services.Client.Strings.Serializer_InvalidCollectionParamterItemType(paramName, annotation3.EdmType.TypeKind));
            }
Label_0155:
            str = ODataUriUtils.ConvertToUriLiteral(obj2, CommonUtil.ConvertToODataVersion(this.requestInfo.MaxProtocolVersionAsVersion));
            if (flag)
            {
                return(DataStringEscapeBuilder.EscapeDataString(str));
            }
            return(Uri.EscapeDataString(str));
        }
Пример #15
0
        /// <summary>
        /// Writes the body operation parameters associated with a ServiceAction.
        /// </summary>
        /// <param name="operationParameters">The list of operation parameters to write.</param>
        /// <param name="requestMessage">The OData request message used to write the operation parameters.</param>
        internal void WriteBodyOperationParameters(List <BodyOperationParameter> operationParameters, ODataRequestMessageWrapper requestMessage)
        {
            Debug.Assert(requestMessage != null, "requestMessage != null");
            Debug.Assert(operationParameters != null, "operationParameters != null");
            Debug.Assert(operationParameters.Any(), "operationParameters.Any()");

            using (ODataMessageWriter messageWriter = Serializer.CreateMessageWriter(requestMessage, this.requestInfo, true /*isParameterPayload*/))
            {
                ODataParameterWriter parameterWriter = messageWriter.CreateODataParameterWriter(null);
                parameterWriter.WriteStart();

                foreach (OperationParameter operationParameter in operationParameters)
                {
                    if (operationParameter.Value == null)
                    {
                        parameterWriter.WriteValue(operationParameter.Name, operationParameter.Value);
                    }
                    else
                    {
                        ClientEdmModel model   = this.requestInfo.Model;
                        IEdmType       edmType = model.GetOrCreateEdmType(operationParameter.Value.GetType());
                        Debug.Assert(edmType != null, "edmType != null");

                        switch (edmType.TypeKind)
                        {
                        case EdmTypeKind.Collection:
                        {
                            Collections.IEnumerator enumerator           = ((ICollection)operationParameter.Value).GetEnumerator();
                            ODataCollectionWriter   collectionWriter     = parameterWriter.CreateCollectionWriter(operationParameter.Name);
                            ODataCollectionStart    odataCollectionStart = new ODataCollectionStart();
                            collectionWriter.WriteStart(odataCollectionStart);

                            while (enumerator.MoveNext())
                            {
                                Object collectionItem = enumerator.Current;
                                if (collectionItem == null)
                                {
                                    throw new NotSupportedException(Strings.Serializer_NullCollectionParamterItemValue(operationParameter.Name));
                                }

                                IEdmType edmItemType = model.GetOrCreateEdmType(collectionItem.GetType());
                                Debug.Assert(edmItemType != null, "edmItemType != null");

                                switch (edmItemType.TypeKind)
                                {
                                case EdmTypeKind.Complex:
                                {
                                    Debug.Assert(model.GetClientTypeAnnotation(edmItemType).ElementType != null, "edmItemType.GetClientTypeAnnotation().ElementType != null");
                                    ODataComplexValue complexValue = this.propertyConverter.CreateODataComplexValue(
                                        model.GetClientTypeAnnotation(edmItemType).ElementType,
                                        collectionItem,
                                        null /*propertyName*/,
                                        false /*isCollectionItem*/,
                                        null /*visitedComplexTypeObjects*/);

                                    Debug.Assert(complexValue != null, "complexValue != null");
                                    collectionWriter.WriteItem(complexValue);
                                    break;
                                }

                                case EdmTypeKind.Primitive:
                                {
                                    collectionWriter.WriteItem(collectionItem);
                                    break;
                                }

                                default:

                                    // EdmTypeKind.Entity
                                    // EdmTypeKind.Row
                                    // EdmTypeKind.EntityReference
                                    // EdmTypeKind.Enum.
                                    throw new NotSupportedException(Strings.Serializer_InvalidCollectionParamterItemType(operationParameter.Name, edmItemType.TypeKind));
                                }
                            }

                            collectionWriter.WriteEnd();
                            collectionWriter.Flush();
                            break;
                        }

                        case EdmTypeKind.Complex:
                        {
                            Debug.Assert(model.GetClientTypeAnnotation(edmType).ElementType != null, "model.GetClientTypeAnnotation(edmType).ElementType != null");
                            ODataComplexValue complexValue = this.propertyConverter.CreateODataComplexValue(
                                model.GetClientTypeAnnotation(edmType).ElementType,
                                operationParameter.Value,
                                null /*propertyName*/,
                                false /*isCollectionItemType*/,
                                null /*visitedComplexTypeObjects*/);

                            Debug.Assert(complexValue != null, "complexValue != null");
                            parameterWriter.WriteValue(operationParameter.Name, complexValue);
                            break;
                        }

                        case EdmTypeKind.Primitive:
                            parameterWriter.WriteValue(operationParameter.Name, operationParameter.Value);
                            break;

                        default:
                            // EdmTypeKind.Entity
                            // EdmTypeKind.Row
                            // EdmTypeKind.EntityReference
                            // EdmTypeKind.Enum.
                            throw new NotSupportedException(Strings.Serializer_InvalidParameterType(operationParameter.Name, edmType.TypeKind));
                        }
                    } // else
                }     // foreach

                parameterWriter.WriteEnd();
                parameterWriter.Flush();
            }
        }
Пример #16
0
 /// <summary>Obtain binding info corresponding to a given type</summary>
 /// <param name="entityType">Type for which to obtain information</param>
 /// <param name="model">the client model.</param>
 /// <returns>Info about the <paramref name="entityType"/></returns>
 internal static IList <BindingPropertyInfo> GetObservableProperties(Type entityType, ClientEdmModel model)
 {
     return(GetBindingEntityInfoFor(entityType, model).ObservableProperties);
 }
Пример #17
0
        /// <summary>
        /// Writes a navigation link.
        /// </summary>
        /// <param name="entityDescriptor">The entity</param>
        /// <param name="relatedLinks">The links related to the entity</param>
        /// <param name="odataWriter">The ODataWriter used to write the navigation link.</param>
        internal void WriteNavigationLink(EntityDescriptor entityDescriptor, IEnumerable <LinkDescriptor> relatedLinks, ODataWriterWrapper odataWriter)
        {
            // TODO:: create instance of odatawriter.
            // TODO:: send clientType once, so that we dont need entity descriptor
            Debug.Assert(EntityStates.Added == entityDescriptor.State, "entity not added state");

            Dictionary <string, List <LinkDescriptor> > groupRelatedLinks = new Dictionary <string, List <LinkDescriptor> >(EqualityComparer <string> .Default);

            foreach (LinkDescriptor end in relatedLinks)
            {
                List <LinkDescriptor> linkDescriptorsList = null;
                if (!groupRelatedLinks.TryGetValue(end.SourceProperty, out linkDescriptorsList))
                {
                    linkDescriptorsList = new List <LinkDescriptor>();
                    groupRelatedLinks.Add(end.SourceProperty, linkDescriptorsList);
                }

                linkDescriptorsList.Add(end);
            }

            ClientTypeAnnotation clientType = null;

            foreach (var grlinks in groupRelatedLinks)
            {
                if (null == clientType)
                {
                    ClientEdmModel model = this.requestInfo.Model;
                    clientType = model.GetClientTypeAnnotation(model.GetOrCreateEdmType(entityDescriptor.Entity.GetType()));
                }

                bool isCollection = clientType.GetProperty(grlinks.Key, false).IsEntityCollection;
                bool started      = false;

                foreach (LinkDescriptor end in grlinks.Value)
                {
                    Debug.Assert(!end.ContentGeneratedForSave, "already saved link");
                    end.ContentGeneratedForSave = true;
                    Debug.Assert(null != end.Target, "null is DELETE");

                    ODataNavigationLink navigationLink = new ODataNavigationLink();
                    navigationLink.Url = this.requestInfo.EntityTracker.GetEntityDescriptor(end.Target).GetLatestEditLink();
                    Debug.Assert(Uri.IsWellFormedUriString(UriUtil.UriToString(navigationLink.Url), UriKind.Absolute), "Uri.IsWellFormedUriString(targetEditLink, UriKind.Absolute)");

                    navigationLink.IsCollection = isCollection;
                    navigationLink.Name         = grlinks.Key;

                    if (!started)
                    {
                        odataWriter.WriteNavigationLinksStart(navigationLink);
                        started = true;
                    }

                    odataWriter.WriteNavigationLinkStart(navigationLink, end.Source, end.Target);
                    odataWriter.WriteEntityReferenceLink(new ODataEntityReferenceLink()
                    {
                        Url = navigationLink.Url
                    }, end.Source, end.Target);
                    odataWriter.WriteNavigationLinkEnd(navigationLink, end.Source, end.Target);
                }

                odataWriter.WriteNavigationLinksEnd();
            }
        }
Пример #18
0
        /// <summary>
        /// Gets the type that of the instances that will be returned by materializer.
        /// </summary>
        /// <param name="expectingPrimitiveValue">Whether the expected is a primitive type.</param>
        /// <param name="elementType">Actual type on the client.</param>
        /// <param name="model">The client model used.</param>
        /// <param name="implementationType">The actual type that implements ICollection&lt;&gt;</param>
        /// <returns>Type of the instances that will be returned by materializer.</returns>
        /// <remarks>
        /// For collection navigation properties (i.e. ICollection&lt;T&gt; where T is an entity the method returns T. Materializer will
        /// return single entity each time MoveNext() is called. However for collection properties we need the whole property instead of just a
        /// single collection item.
        /// </remarks>
        private static Type GetTypeForMaterializer(bool expectingPrimitiveValue, Type elementType, ClientEdmModel model, out Type implementationType)
        {
            if (!expectingPrimitiveValue && typeof(IEnumerable).IsAssignableFrom(elementType))
            {
                implementationType = ClientTypeUtil.GetImplementationType(elementType, typeof(ICollection <>));
                if (implementationType != null)
                {
                    Type expectedType = implementationType.GetGenericArguments()[0]; // already know its ICollection<>

                    // We should use the inner type only if this is a collection of entities (as opposed to a collection of primitive or complex types)
                    if (ClientTypeUtil.TypeIsEntity(expectedType, model))
                    {
                        return(expectedType);
                    }
                }
            }

            implementationType = null;
            return(elementType);
        }
Пример #19
0
        private string ConvertToEscapedUriValue(string paramName, object value)
        {
            Debug.Assert(!string.IsNullOrEmpty(paramName), "!string.IsNullOrEmpty(paramName)");
            Object valueInODataFormat = null;

            // 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;

            if (value == null)
            {
                needsSpecialEscaping = true;
            }
            else
            {
                if (value.GetType() == typeof(ODataUriNullValue))
                {
                    valueInODataFormat   = value;
                    needsSpecialEscaping = true;
                }
                else
                {
                    ClientEdmModel model   = this.requestInfo.Model;
                    IEdmType       edmType = model.GetOrCreateEdmType(value.GetType());
                    Debug.Assert(edmType != null, "edmType != null");

                    switch (edmType.TypeKind)
                    {
                    case EdmTypeKind.Primitive:
                        valueInODataFormat   = value;
                        needsSpecialEscaping = true;
                        break;

                    case EdmTypeKind.Complex:
                        ClientTypeAnnotation typeAnnotation = model.GetClientTypeAnnotation(edmType);
                        Debug.Assert(typeAnnotation != null, "typeAnnotation != null");
                        valueInODataFormat = this.propertyConverter.CreateODataComplexValue(
                            typeAnnotation.ElementType,
                            value,
                            null /*propertyName*/,
                            false /*isCollectionItemType*/,
                            null /*visitedComplexTypeObjects*/);

                        // When using JsonVerbose to format query string parameters for Actions,
                        // we cannot write out Complex values in the URI without the type name of the complex type in the JSON payload.
                        // If this value is null, the client has to set the ResolveName property on the DataServiceContext instance.
                        ODataComplexValue complexValue = (ODataComplexValue)valueInODataFormat;
                        SerializationTypeNameAnnotation serializedTypeNameAnnotation = complexValue.GetAnnotation <SerializationTypeNameAnnotation>();
                        if (serializedTypeNameAnnotation == null || string.IsNullOrEmpty(serializedTypeNameAnnotation.TypeName))
                        {
                            throw Error.InvalidOperation(Strings.DataServiceException_GeneralError);
                        }

                        break;

                    case EdmTypeKind.Collection:
                        IEdmCollectionType edmCollectionType = edmType as IEdmCollectionType;
                        Debug.Assert(edmCollectionType != null, "edmCollectionType != null");
                        IEdmTypeReference itemTypeReference = edmCollectionType.ElementType;
                        Debug.Assert(itemTypeReference != null, "itemTypeReference != null");
                        ClientTypeAnnotation itemTypeAnnotation = model.GetClientTypeAnnotation(itemTypeReference.Definition);
                        Debug.Assert(itemTypeAnnotation != null, "itemTypeAnnotation != null");

                        switch (itemTypeAnnotation.EdmType.TypeKind)
                        {
                        // We only support primitive or complex type as a collection item type.
                        case EdmTypeKind.Primitive:
                        case EdmTypeKind.Complex:
                            break;

                        default:
                            throw new NotSupportedException(Strings.Serializer_InvalidCollectionParamterItemType(paramName, itemTypeAnnotation.EdmType.TypeKind));
                        }

                        valueInODataFormat = this.propertyConverter.CreateODataCollection(
                            itemTypeAnnotation.ElementType,
                            null /*propertyName*/,
                            value,
                            null /*visitedComplexTypeObjects*/);
                        break;

                    default:
                        // EdmTypeKind.Entity
                        // EdmTypeKind.Row
                        // EdmTypeKind.EntityReference
                        // EdmTypeKind.Enum.
                        throw new NotSupportedException(Strings.Serializer_InvalidParameterType(paramName, edmType.TypeKind));
                    }
                }

                Debug.Assert(valueInODataFormat != null, "valueInODataFormat != null");
            }

            // In the released WCF Data Services 5.0, we didn't pass the model for JSON Verbose literals, so continuing that behavior for backward compatibility
            ODataFormat literalFormat = this.requestInfo.Format.UriLiteralFormat;
            IEdmModel   edmModel      = literalFormat == ODataFormat.VerboseJson ? null : this.requestInfo.Model;

            // ODL can handle null values so we can send null values here.
            string literal = ODataUriUtils.ConvertToUriLiteral(valueInODataFormat, CommonUtil.ConvertToODataVersion(this.requestInfo.MaxProtocolVersionAsVersion), edmModel, literalFormat);

            // 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));
        }
Пример #20
0
 /// <summary>
 /// gets the UriTranslateResult for a the query
 /// </summary>
 /// <param name="model">The client model.</param>
 /// <returns>an instance of QueryComponents.</returns>
 internal override QueryComponents QueryComponents(ClientEdmModel model)
 {
     return(this.Translate());
 }
Пример #21
0
        /// <summary>Obtain binding info corresponding to a given type</summary>
        /// <param name="entityType">Type for which to obtain information</param>
        /// <param name="model">The client model.</param>
        /// <returns>Info about the <paramref name="entityType"/></returns>
        private static BindingEntityInfoPerType GetBindingEntityInfoFor(Type entityType, ClientEdmModel model)
        {
            BindingEntityInfoPerType bindingEntityInfo;

            metadataCacheLock.EnterReadLock();
            try
            {
                if (bindingEntityInfos.TryGetValue(entityType, out bindingEntityInfo))
                {
                    return(bindingEntityInfo);
                }
            }
            finally
            {
                metadataCacheLock.ExitReadLock();
            }

            bindingEntityInfo = new BindingEntityInfoPerType();

            // Try to get the entity set name from the EntitySetAttribute attributes. In order to make the
            // inheritance work, we need to look at the attributes declared in the base types also.
            // EntitySetAttribute does not allow multiples, so there can be at most 1 instance on the type.
            EntitySetAttribute entitySetAttribute = (EntitySetAttribute)entityType.GetCustomAttributes(typeof(EntitySetAttribute), true).SingleOrDefault();

            // There must be exactly one (unambiguous) EntitySetAttribute attribute.
            bindingEntityInfo.EntitySet  = entitySetAttribute != null ? entitySetAttribute.EntitySet : null;
            bindingEntityInfo.ClientType = model.GetClientTypeAnnotation(model.GetOrCreateEdmType(entityType));

            foreach (ClientPropertyAnnotation p in bindingEntityInfo.ClientType.Properties())
            {
                BindingPropertyInfo bpi = null;
                Type propertyType       = p.PropertyType;

                if (p.IsStreamLinkProperty)
                {
                    // DataServiceStreamLink is not mutable externally
                    // It implements INPC to notify controls about our updates
                    // We should ignore its events since we are the only one updating it.
                    continue;
                }
                else if (p.IsPrimitiveOrComplexCollection)
                {
                    Debug.Assert(!BindingEntityInfo.IsDataServiceCollection(propertyType, model), "DataServiceCollection cannot be the type that backs collections of primitives or complex types.");
                    bpi = new BindingPropertyInfo {
                        PropertyKind = BindingPropertyKind.BindingPropertyKindPrimitiveOrComplexCollection
                    };
                }
                else if (p.IsEntityCollection)
                {
                    if (BindingEntityInfo.IsDataServiceCollection(propertyType, model))
                    {
                        bpi = new BindingPropertyInfo {
                            PropertyKind = BindingPropertyKind.BindingPropertyKindDataServiceCollection
                        };
                    }
                }
                else if (BindingEntityInfo.IsEntityType(propertyType, model))
                {
                    bpi = new BindingPropertyInfo {
                        PropertyKind = BindingPropertyKind.BindingPropertyKindEntity
                    };
                }
                else if (BindingEntityInfo.CanBeComplexType(propertyType))
                {
                    // Add complex types and nothing else.
                    Debug.Assert(!p.IsKnownType, "Known types do not implement INotifyPropertyChanged.");
                    bpi = new BindingPropertyInfo {
                        PropertyKind = BindingPropertyKind.BindingPropertyKindComplex
                    };
                }

                if (bpi != null)
                {
                    bpi.PropertyInfo = p;

                    // For entity types, all of the above types of properties are interesting.
                    // For complex types, only observe collections and complex type properties.
                    if (bindingEntityInfo.ClientType.IsEntityType ||
                        bpi.PropertyKind == BindingPropertyKind.BindingPropertyKindComplex ||
                        bpi.PropertyKind == BindingPropertyKind.BindingPropertyKindPrimitiveOrComplexCollection)
                    {
                        bindingEntityInfo.ObservableProperties.Add(bpi);
                    }
                }
            }

            metadataCacheLock.EnterWriteLock();
            try
            {
                if (!bindingEntityInfos.ContainsKey(entityType))
                {
                    bindingEntityInfos[entityType] = bindingEntityInfo;
                }
            }
            finally
            {
                metadataCacheLock.ExitWriteLock();
            }

            return(bindingEntityInfo);
        }
Пример #22
0
 /// <summary>
 /// Constructor
 /// </summary>
 /// <param name="source">Source entity</param>
 /// <param name="sourceProperty">Navigation property on the source entity</param>
 /// <param name="target">Target entity</param>
 /// <param name="model">The client model.</param>
 internal LinkDescriptor(object source, string sourceProperty, object target, ClientEdmModel model)
     : this(source, sourceProperty, target, EntityStates.Unchanged)
 {
     this.IsSourcePropertyCollection = model.GetClientTypeAnnotation(model.GetOrCreateEdmType(source.GetType())).GetProperty(sourceProperty, false).IsEntityCollection;
 }
Пример #23
0
        /// <summary>
        /// Tries to get the value of a property and corresponding BindingPropertyInfo or ClientPropertyAnnotation if the property exists
        /// </summary>
        /// <param name="source">Source object whose property needs to be read</param>
        /// <param name="sourceProperty">Name of the source object property</param>
        /// <param name="model">The client model.</param>
        /// <param name="bindingPropertyInfo">BindingPropertyInfo corresponding to <paramref name="sourceProperty"/></param>
        /// <param name="clientProperty">Instance of ClientProperty corresponding to <paramref name="sourceProperty"/></param>
        /// <param name="propertyValue">Value of the property</param>
        /// <returns>true if the property exists and the value was read; otherwise false.</returns>
        internal static bool TryGetPropertyValue(object source, string sourceProperty, ClientEdmModel model, out BindingPropertyInfo bindingPropertyInfo, out ClientPropertyAnnotation clientProperty, out object propertyValue)
        {
            Type sourceType = source.GetType();

            bindingPropertyInfo = BindingEntityInfo.GetObservableProperties(sourceType, model)
                                  .SingleOrDefault(x => x.PropertyInfo.PropertyName == sourceProperty);

            bool propertyFound = bindingPropertyInfo != null;

            // bindingPropertyInfo is null for primitive properties.
            if (!propertyFound)
            {
                clientProperty = BindingEntityInfo.GetClientType(sourceType, model)
                                 .GetProperty(sourceProperty, true);

                propertyFound = clientProperty != null;
                if (!propertyFound)
                {
                    propertyValue = null;
                }
                else
                {
                    propertyValue = clientProperty.GetValue(source);
                }
            }
            else
            {
                clientProperty = null;
                propertyValue  = bindingPropertyInfo.PropertyInfo.GetValue(source);
            }

            return(propertyFound);
        }
Пример #24
0
        private ODataRequestMessageWrapper GenerateBatchRequest()
        {
            if ((base.ChangedEntries.Count == 0) && (this.Queries == null))
            {
                base.SetCompleted();
                return(null);
            }
            ODataRequestMessageWrapper requestMessage = this.CreateBatchRequest();

            using (ODataMessageWriter writer = Serializer.CreateMessageWriter(requestMessage, base.RequestInfo))
            {
                ODataUtils.SetHeadersForPayload(writer, ODataPayloadKind.Batch);
                requestMessage.FireSendingRequest2(null);
                this.batchWriter = writer.CreateODataBatchWriter();
                this.batchWriter.WriteStartBatch();
                if (this.Queries != null)
                {
                    for (int i = 0; i < this.Queries.Length; i++)
                    {
                        Uri requestUri = base.RequestInfo.BaseUriResolver.CreateAbsoluteUriIfNeeded(this.Queries[i].QueryComponents(base.RequestInfo.MaxProtocolVersion).Uri);
                        ODataRequestMessageWrapper wrapper2 = this.CreateRequestMessage(requestUri, "GET");
                        Version requestVersion = this.Queries[i].QueryComponents(base.RequestInfo.MaxProtocolVersion).Version;
                        WebUtil.SetOperationVersionHeaders(wrapper2, requestVersion, base.RequestInfo.MaxProtocolVersionAsVersion);
                        wrapper2.FireSendingRequest2(null);
                    }
                }
                else if (0 < base.ChangedEntries.Count)
                {
                    this.batchWriter.WriteStartChangeset();
                    ClientEdmModel model = ClientEdmModel.GetModel(base.RequestInfo.MaxProtocolVersion);
                    for (int j = 0; j < base.ChangedEntries.Count; j++)
                    {
                        Descriptor descriptor = base.ChangedEntries[j];
                        if (!descriptor.ContentGeneratedForSave)
                        {
                            ODataRequestMessageWrapper wrapper3;
                            EntityDescriptor           entityDescriptor = descriptor as EntityDescriptor;
                            if (descriptor.DescriptorKind == DescriptorKind.Entity)
                            {
                                if (entityDescriptor.State != EntityStates.Added)
                                {
                                    if (((entityDescriptor.State == EntityStates.Unchanged) || (entityDescriptor.State == EntityStates.Modified)) && (entityDescriptor.SaveStream != null))
                                    {
                                        throw System.Data.Services.Client.Error.NotSupported(System.Data.Services.Client.Strings.Context_BatchNotSupportedForMediaLink);
                                    }
                                }
                                else if (model.GetClientTypeAnnotation(model.GetOrCreateEdmType(entityDescriptor.Entity.GetType())).IsMediaLinkEntry || entityDescriptor.IsMediaLinkEntry)
                                {
                                    throw System.Data.Services.Client.Error.NotSupported(System.Data.Services.Client.Strings.Context_BatchNotSupportedForMediaLink);
                                }
                            }
                            else if (descriptor.DescriptorKind == DescriptorKind.NamedStream)
                            {
                                throw System.Data.Services.Client.Error.NotSupported(System.Data.Services.Client.Strings.Context_BatchNotSupportedForNamedStreams);
                            }
                            if (descriptor.DescriptorKind == DescriptorKind.Entity)
                            {
                                wrapper3 = base.CreateRequest(entityDescriptor);
                            }
                            else
                            {
                                wrapper3 = base.CreateRequest((LinkDescriptor)descriptor);
                            }
                            wrapper3.FireSendingRequest2(descriptor);
                            base.CreateChangeData(j, wrapper3);
                        }
                    }
                    this.batchWriter.WriteEndChangeset();
                }
                this.batchWriter.WriteEndBatch();
                this.batchWriter.Flush();
            }
            return(requestMessage);
        }
Пример #25
0
 /// <summary>Gets entity set corresponding to a given type</summary>
 /// <param name="entityType">Intput type</param>
 /// <param name="model">The client model.</param>
 /// <returns>Entity set name for the type</returns>
 private static string GetEntitySetAttribute(Type entityType, ClientEdmModel model)
 {
     return(GetBindingEntityInfoFor(entityType, model).EntitySet);
 }
Пример #26
0
        internal LinkDescriptor(object source, string sourceProperty, object target, DataServiceProtocolVersion maxProtocolVersion) : this(source, sourceProperty, target, EntityStates.Unchanged)
        {
            ClientEdmModel model = ClientEdmModel.GetModel(maxProtocolVersion);

            this.IsSourcePropertyCollection = model.GetClientTypeAnnotation(model.GetOrCreateEdmType(source.GetType())).GetProperty(sourceProperty, false).IsEntityCollection;
        }
Пример #27
0
 /// <summary>Gets the ClientType corresponding to the given type</summary>
 /// <param name="entityType">Input type</param>
 /// <param name="model">The client model.</param>
 /// <returns>Corresponding ClientType</returns>
 internal static ClientTypeAnnotation GetClientType(Type entityType, ClientEdmModel model)
 {
     return(GetBindingEntityInfoFor(entityType, model).ClientType);
 }
Пример #28
0
 /// <summary>
 /// Creates a new instance of EntityTracker class which tracks all instances of entities and links tracked by the context.
 /// </summary>
 /// <param name="maxProtocolVersion">max protocol version that the client understands.</param>
 public EntityTracker(ClientEdmModel maxProtocolVersion)
 {
     this.model = maxProtocolVersion;
 }
Пример #29
0
        internal void WriteBodyOperationParameters(List <BodyOperationParameter> operationParameters, ODataRequestMessageWrapper requestMessage)
        {
            using (ODataMessageWriter writer = CreateMessageWriter(requestMessage, this.requestInfo))
            {
                ODataParameterWriter writer2 = writer.CreateODataParameterWriter(null);
                writer2.WriteStart();
                foreach (OperationParameter parameter in operationParameters)
                {
                    IEnumerator           enumerator;
                    ODataCollectionWriter writer3;
                    object obj2;
                    if (parameter.Value == null)
                    {
                        writer2.WriteValue(parameter.Name, parameter.Value);
                        continue;
                    }
                    ClientEdmModel model           = ClientEdmModel.GetModel(this.requestInfo.MaxProtocolVersion);
                    IEdmType       orCreateEdmType = model.GetOrCreateEdmType(parameter.Value.GetType());
                    switch (orCreateEdmType.TypeKind)
                    {
                    case EdmTypeKind.Primitive:
                    {
                        writer2.WriteValue(parameter.Name, parameter.Value);
                        continue;
                    }

                    case EdmTypeKind.Complex:
                    {
                        ODataComplexValue parameterValue = this.CreateODataComplexValue(model.GetClientTypeAnnotation(orCreateEdmType).ElementType, parameter.Value, null, false, null);
                        writer2.WriteValue(parameter.Name, parameterValue);
                        continue;
                    }

                    case EdmTypeKind.Collection:
                    {
                        enumerator = ((ICollection)parameter.Value).GetEnumerator();
                        writer3    = writer2.CreateCollectionWriter(parameter.Name);
                        ODataCollectionStart collectionStart = new ODataCollectionStart();
                        writer3.WriteStart(collectionStart);
                        goto Label_016D;
                    }

                    default:
                        throw new NotSupportedException(System.Data.Services.Client.Strings.Serializer_InvalidParameterType(parameter.Name, orCreateEdmType.TypeKind));
                    }
Label_00D3:
                    obj2 = enumerator.Current;
                    if (obj2 == null)
                    {
                        throw new NotSupportedException(System.Data.Services.Client.Strings.Serializer_NullCollectionParamterItemValue(parameter.Name));
                    }
                    IEdmType edmType = model.GetOrCreateEdmType(obj2.GetType());
                    switch (edmType.TypeKind)
                    {
                    case EdmTypeKind.Primitive:
                        writer3.WriteItem(obj2);
                        break;

                    case EdmTypeKind.Complex:
                    {
                        ODataComplexValue item = this.CreateODataComplexValue(model.GetClientTypeAnnotation(edmType).ElementType, obj2, null, false, null);
                        writer3.WriteItem(item);
                        break;
                    }

                    default:
                        throw new NotSupportedException(System.Data.Services.Client.Strings.Serializer_InvalidCollectionParamterItemType(parameter.Name, edmType.TypeKind));
                    }
Label_016D:
                    if (enumerator.MoveNext())
                    {
                        goto Label_00D3;
                    }
                    writer3.WriteEnd();
                    writer3.Flush();
                }
                writer2.WriteEnd();
                writer2.Flush();
            }
        }
Пример #30
0
 /// <summary>The QueryComponents associated with this request</summary>
 /// <param name="model">The client model.</param>
 /// <returns>instance of query components</returns>
 internal abstract QueryComponents QueryComponents(ClientEdmModel model);
Пример #31
0
 private Version ComputeVersionForPropertyCollection(IEnumerable<IEdmProperty> propertyCollection, HashSet<IEdmType> visitedComplexTypes, ClientEdmModel model)
 {
     Version version = Util.DataServiceVersion1;
     foreach (IEdmProperty property in propertyCollection)
     {
         ClientPropertyAnnotation clientPropertyAnnotation = model.GetClientPropertyAnnotation(property);
         if (clientPropertyAnnotation.IsPrimitiveOrComplexCollection || clientPropertyAnnotation.IsSpatialType)
         {
             WebUtil.RaiseVersion(ref version, Util.DataServiceVersion3);
         }
         else
         {
             if ((property.Type.TypeKind() == EdmTypeKind.Complex) && !clientPropertyAnnotation.IsDictionary)
             {
                 if (visitedComplexTypes == null)
                 {
                     visitedComplexTypes = new HashSet<IEdmType>(EqualityComparer<IEdmType>.Default);
                 }
                 else if (visitedComplexTypes.Contains(property.Type.Definition))
                 {
                     goto Label_00A6;
                 }
                 visitedComplexTypes.Add(property.Type.Definition);
                 WebUtil.RaiseVersion(ref version, this.ComputeVersionForPropertyCollection(model.GetClientTypeAnnotation(property).EdmProperties(), visitedComplexTypes, model));
             }
         Label_00A6:;
         }
     }
     return version;
 }
Пример #32
0
 /// <summary>Verifies the absence of observer for an DataServiceCollection</summary>
 /// <typeparam name="T">Type of DataServiceCollection</typeparam>
 /// <param name="oec">Non-typed collection object</param>
 /// <param name="sourceProperty">Collection property of the source object which is being assigned to</param>
 /// <param name="sourceType">Type of the source object</param>
 /// <param name="model">The client model.</param>
 internal static void VerifyObserverNotPresent <T>(object oec, string sourceProperty, Type sourceType, ClientEdmModel model)