示例#1
0
        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));
        }
示例#2
0
        internal void WriteNavigationLink(EntityDescriptor entityDescriptor, IEnumerable <LinkDescriptor> relatedLinks, ODataWriter odataWriter)
        {
            ClientTypeAnnotation clientTypeAnnotation = null;

            foreach (LinkDescriptor descriptor in relatedLinks)
            {
                descriptor.ContentGeneratedForSave = true;
                if (clientTypeAnnotation == null)
                {
                    ClientEdmModel model = ClientEdmModel.GetModel(this.requestInfo.MaxProtocolVersion);
                    clientTypeAnnotation = model.GetClientTypeAnnotation(model.GetOrCreateEdmType(entityDescriptor.Entity.GetType()));
                }
                ODataNavigationLink navigationLink = new ODataNavigationLink {
                    Url          = this.requestInfo.EntityTracker.GetEntityDescriptor(descriptor.Target).GetLatestEditLink(),
                    IsCollection = new bool?(clientTypeAnnotation.GetProperty(descriptor.SourceProperty, false).IsEntityCollection),
                    Name         = descriptor.SourceProperty
                };
                odataWriter.WriteStart(navigationLink);
                ODataEntityReferenceLink entityReferenceLink = new ODataEntityReferenceLink {
                    Url = navigationLink.Url
                };
                odataWriter.WriteEntityReferenceLink(entityReferenceLink);
                odataWriter.WriteEnd();
            }
        }
示例#3
0
        protected ODataRequestMessageWrapper CreateRequest(EntityDescriptor entityDescriptor)
        {
            EntityStates               state          = entityDescriptor.State;
            Uri                        resourceUri    = entityDescriptor.GetResourceUri(this.RequestInfo.BaseUriResolver, false);
            ClientEdmModel             model          = ClientEdmModel.GetModel(this.RequestInfo.MaxProtocolVersion);
            Version                    requestVersion = DetermineRequestVersion(model.GetClientTypeAnnotation(model.GetOrCreateEdmType(entityDescriptor.Entity.GetType())), state);
            string                     httpMethod     = this.GetHttpMethod(state, ref requestVersion);
            ODataRequestMessageWrapper requestMessage = this.CreateRequestMessage(resourceUri, httpMethod);

            if (this.IsBatch)
            {
                requestMessage.SetHeader("Content-ID", entityDescriptor.ChangeOrder.ToString(CultureInfo.InvariantCulture));
            }
            if (EntityStates.Deleted != entityDescriptor.State)
            {
                requestMessage.SetHeader("Content-Type", "application/atom+xml");
            }
            if ((EntityStates.Deleted == state) || (EntityStates.Modified == state))
            {
                string latestETag = entityDescriptor.GetLatestETag();
                if (latestETag != null)
                {
                    requestMessage.SetHeader("If-Match", latestETag);
                    if (!this.IsBatch)
                    {
                        requestMessage.AddHeadersToReset("If-Match");
                    }
                }
            }
            ApplyPreferences(requestMessage, httpMethod, this.RequestInfo.AddAndUpdateResponsePreference, ref requestVersion);
            WebUtil.SetOperationVersionHeaders(requestMessage, requestVersion, this.RequestInfo.MaxProtocolVersionAsVersion);
            return(requestMessage);
        }
示例#4
0
        /// <summary>
        /// Creates and returns an ODataComplexValue from the given value.
        /// </summary>
        /// <param name="complexType">The value type.</param>
        /// <param name="value">The complex value.</param>
        /// <param name="propertyName">If the value is a property, then it represents the name of the property. Can be null, for non-property.</param>
        /// <param name="isCollectionItem">True, if the value is an item in a collection, false otherwise.</param>
        /// <param name="visitedComplexTypeObjects">Set of instances of complex types encountered in the hierarchy. Used to detect cycles.</param>
        /// <returns>An ODataComplexValue representing the given value.</returns>
        internal ODataComplexValue CreateODataComplexValue(Type complexType, object value, string propertyName, bool isCollectionItem, HashSet <object> visitedComplexTypeObjects)
        {
            Debug.Assert(complexType != null, "complexType != null");
            Debug.Assert(value != null || !isCollectionItem, "Collection items must not be null");

            ClientEdmModel       model = this.requestInfo.Model;
            ClientTypeAnnotation complexTypeAnnotation = model.GetClientTypeAnnotation(complexType);

            Debug.Assert(complexTypeAnnotation != null, "complexTypeAnnotation != null");
            Debug.Assert(!complexTypeAnnotation.IsEntityType, "Unexpected entity");

            // Handle null values for complex types by putting m:null="true"
            if (value == null)
            {
                Debug.Assert(!isCollectionItem, "Null collection items are not supported. Should have already been checked.");
                return(null);
            }

            if (visitedComplexTypeObjects == null)
            {
                visitedComplexTypeObjects = new HashSet <object>(ReferenceEqualityComparer <object> .Instance);
            }
            else if (visitedComplexTypeObjects.Contains(value))
            {
                if (propertyName != null)
                {
                    throw Error.InvalidOperation(Strings.Serializer_LoopsNotAllowedInComplexTypes(propertyName));
                }
                else
                {
                    Debug.Assert(complexTypeAnnotation.ElementTypeName != null, "complexTypeAnnotation.ElementTypeName != null");
                    throw Error.InvalidOperation(Strings.Serializer_LoopsNotAllowedInNonPropertyComplexTypes(complexTypeAnnotation.ElementTypeName));
                }
            }

            visitedComplexTypeObjects.Add(value);
            ODataComplexValue odataComplexValue = new ODataComplexValue();

            // When TypeName is set, it causes validation to occur when ODataLib writes out the collection. Part of the validation ensures that all items
            // in the collection are exactly the same type, no derived types are allowed. In the released WCF Data Services 5.0 implementation, we don't set
            // TypeName here, so that validation does not occur, therefore we will set this value only for JSON Light, so we don't break existing code.
            if (!this.requestInfo.Format.UsingAtom)
            {
                odataComplexValue.TypeName = complexTypeAnnotation.ElementTypeName;
            }

            // If this complex type is a collection item don't put type name on each item
            if (!isCollectionItem)
            {
                odataComplexValue.SetAnnotation(new SerializationTypeNameAnnotation {
                    TypeName = this.requestInfo.GetServerTypeName(complexTypeAnnotation)
                });
            }

            odataComplexValue.Properties = this.PopulateProperties(value, complexTypeAnnotation.PropertiesToSerialize(), visitedComplexTypeObjects);

            visitedComplexTypeObjects.Remove(value);
            return(odataComplexValue);
        }
示例#5
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);
        }
示例#6
0
        /// <summary>
        /// Creates the ResponseInfo object.
        /// </summary>
        /// <returns>ResponseInfo object.</returns>
        protected override ResponseInfo CreateResponseInfo()
        {
            DataServiceContext context = (DataServiceContext)this.Source;

            ClientEdmModel model = context.Model;

            ClientTypeAnnotation type = model.GetClientTypeAnnotation(model.GetOrCreateEdmType(this.entity.GetType()));

            Debug.Assert(type.IsEntityType, "Must be entity type to be contained.");

            return(this.RequestInfo.GetDeserializationInfoForLoadProperty(
                       null,
                       context.GetEntityDescriptor(this.entity),
                       type.GetProperty(this.propertyName, false)));
        }
示例#7
0
        /// <summary>
        /// loading a property from a response
        /// </summary>
        /// <returns>QueryOperationResponse instance containing information about the response.</returns>
        internal QueryOperationResponse LoadProperty()
        {
            MaterializeAtom results = null;

            DataServiceContext context = (DataServiceContext)this.Source;

            ClientEdmModel       model = context.Model;
            ClientTypeAnnotation type  = model.GetClientTypeAnnotation(model.GetOrCreateEdmType(this.entity.GetType()));

            Debug.Assert(type.IsEntityType, "must be entity type to be contained");

            EntityDescriptor box = context.GetEntityDescriptor(this.entity);

            if (EntityStates.Added == box.State)
            {
                throw Error.InvalidOperation(Strings.Context_NoLoadWithInsertEnd);
            }

            ClientPropertyAnnotation property = type.GetProperty(this.propertyName, false);
            Type elementType = property.EntityCollectionItemType ?? property.NullablePropertyType;

            try
            {
                if (type.MediaDataMember == property)
                {
                    results = this.ReadPropertyFromRawData(property);
                }
                else
                {
                    results = this.ReadPropertyFromAtom(property);
                }

                return(this.GetResponseWithType(results, elementType));
            }
            catch (InvalidOperationException ex)
            {
                QueryOperationResponse response = this.GetResponseWithType(results, elementType);
                if (response != null)
                {
                    response.Error = ex;
                    throw new DataServiceQueryException(Strings.DataServiceException_GeneralError, ex, response);
                }

                throw;
            }
        }
示例#8
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);
        }
示例#9
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();
            }
        }
示例#10
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;
        }
示例#11
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);
            }
        }
示例#12
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));
        }
示例#13
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);
        }
示例#14
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);
        }
示例#15
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);
        }
示例#16
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();
            }
        }
示例#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
        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));
        }
示例#19
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();
            }
        }
示例#20
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);
        }
示例#21
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;
        }
示例#22
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;
 }
示例#23
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;
 }