示例#1
0
        internal void SetETagValues(object resourceCookie, ResourceSetWrapper container)
        {
            DataServiceHostWrapper host   = this.service.OperationContext.Host;
            object                   obj2 = this.ResolveResource(resourceCookie);
            ResourceType             nonPrimitiveResourceType = WebUtil.GetNonPrimitiveResourceType(this.service.Provider, obj2);
            IList <ResourceProperty> eTagProperties           = this.service.Provider.GetETagProperties(container.Name, nonPrimitiveResourceType);

            if (eTagProperties.Count == 0)
            {
                if (!string.IsNullOrEmpty(host.RequestIfMatch))
                {
                    throw DataServiceException.CreateBadRequestError(System.Data.Services.Strings.Serializer_NoETagPropertiesForType);
                }
            }
            else
            {
                IDataServiceUpdateProvider updateProvider = this.updateProvider as IDataServiceUpdateProvider;
                if (updateProvider != null)
                {
                    IEnumerable <KeyValuePair <string, object> > emptyKeyValuePairStringObject;
                    bool?checkForEquality = null;
                    if (!string.IsNullOrEmpty(host.RequestIfMatch))
                    {
                        checkForEquality = true;
                        emptyKeyValuePairStringObject = ParseETagValue(eTagProperties, host.RequestIfMatch);
                    }
                    else
                    {
                        emptyKeyValuePairStringObject = WebUtil.EmptyKeyValuePairStringObject;
                    }
                    updateProvider.SetConcurrencyValues(resourceCookie, checkForEquality, emptyKeyValuePairStringObject);
                }
                else
                {
                    if (string.IsNullOrEmpty(host.RequestIfMatch))
                    {
                        throw DataServiceException.CreateBadRequestError(System.Data.Services.Strings.DataService_CannotPerformOperationWithoutETag(nonPrimitiveResourceType.FullName));
                    }
                    if ((host.RequestIfMatch != "*") && (WebUtil.GetETagValue(resourceCookie, nonPrimitiveResourceType, eTagProperties, this.service, false) != host.RequestIfMatch))
                    {
                        throw DataServiceException.CreatePreConditionFailedError(System.Data.Services.Strings.Serializer_ETagValueDoesNotMatch);
                    }
                }
            }
        }
示例#2
0
        /// <summary>
        /// If the provider implements IConcurrencyProvider, then this method passes the etag values
        /// to the provider, otherwise compares the etag itself.
        /// </summary>
        /// <param name="resourceCookie">etag values for the given resource.</param>
        /// <param name="container">container for the given resource.</param>
        internal void SetETagValues(object resourceCookie, ResourceSetWrapper container)
        {
            Debug.Assert(resourceCookie != null, "resourceCookie != null");
            Debug.Assert(container != null, "container != null");
            DataServiceHostWrapper host = this.service.OperationContext.Host;

            Debug.Assert(String.IsNullOrEmpty(host.RequestIfNoneMatch), "IfNoneMatch header cannot be specified for Update/Delete operations");

            // Resolve the cookie first to the actual resource type
            object actualEntity = this.ResolveResource(resourceCookie);

            Debug.Assert(actualEntity != null, "actualEntity != null");

            ResourceType resourceType = WebUtil.GetNonPrimitiveResourceType(this.service.Provider, actualEntity);

            Debug.Assert(resourceType != null, "resourceType != null");

            IList <ResourceProperty> etagProperties = this.service.Provider.GetETagProperties(container.Name, resourceType);

            if (etagProperties.Count == 0)
            {
                if (!String.IsNullOrEmpty(host.RequestIfMatch))
                {
                    throw DataServiceException.CreateBadRequestError(Strings.Serializer_NoETagPropertiesForType);
                }

                // If the type has no etag properties, then we do not need to do any etag checks
                return;
            }

            // If the provider implements IConcurrencyProvider, then we need to call the provider
            // and pass the etag values. Else, we need to compare the etag values ourselves.
            IDataServiceUpdateProvider concurrencyProvider = this.updateProvider as IDataServiceUpdateProvider;

            if (concurrencyProvider != null)
            {
                bool?checkForEquality = null;
                IEnumerable <KeyValuePair <string, object> > etagValues = null;
                if (!String.IsNullOrEmpty(host.RequestIfMatch))
                {
                    checkForEquality = true;
                    etagValues       = ParseETagValue(etagProperties, host.RequestIfMatch);
                }
                else
                {
                    etagValues = new KeyValuePair <string, object> [0];
                }

                concurrencyProvider.SetConcurrencyValues(resourceCookie, checkForEquality, etagValues);
            }
            else if (String.IsNullOrEmpty(host.RequestIfMatch))
            {
                throw DataServiceException.CreateBadRequestError(Strings.DataService_CannotPerformOperationWithoutETag(resourceType.FullName));
            }
            else if (host.RequestIfMatch != XmlConstants.HttpAnyETag)
            {
                // Compare If-Match header value with the current etag value, if the If-Match header value is not equal to '*'
                string etagValue = WebUtil.GetETagValue(resourceCookie, resourceType, etagProperties, this.service, false /*getMethod*/);
                Debug.Assert(!String.IsNullOrEmpty(etagValue), "etag value can never be null");

                if (etagValue != host.RequestIfMatch)
                {
                    throw DataServiceException.CreatePreConditionFailedError(Strings.Serializer_ETagValueDoesNotMatch);
                }
            }
        }