Beispiel #1
0
        protected void HandleOperationResponseHeaders(HttpStatusCode statusCode, Dictionary <string, string> headers)
        {
            Descriptor descriptor = this.ChangedEntries[this.entryIndex];

            if (descriptor.DescriptorKind == DescriptorKind.Entity)
            {
                EntityDescriptor descriptor2 = (EntityDescriptor)descriptor;
                if ((((descriptor.State == EntityStates.Added) || (this.streamRequestKind == StreamRequestKind.PostMediaResource)) || Util.IsFlagSet(this.Options, SaveChangesOptions.PatchOnUpdate)) && WebUtil.SuccessStatusCode(statusCode))
                {
                    string str;
                    string str2;
                    Uri    editLink = null;
                    headers.TryGetValue("Location", out str);
                    headers.TryGetValue("DataServiceId", out str2);
                    if (str != null)
                    {
                        editLink = WebUtil.ValidateLocationHeader(str);
                    }
                    else if ((descriptor.State == EntityStates.Added) || (this.streamRequestKind == StreamRequestKind.PostMediaResource))
                    {
                        throw System.Data.Services.Client.Error.NotSupported(System.Data.Services.Client.Strings.Deserialize_NoLocationHeader);
                    }
                    if (str2 != null)
                    {
                        if (str == null)
                        {
                            throw System.Data.Services.Client.Error.NotSupported(System.Data.Services.Client.Strings.Context_BothLocationAndIdMustBeSpecified);
                        }
                        WebUtil.ValidateIdentityValue(str2);
                    }
                    else
                    {
                        str2 = str;
                    }
                    if (null != editLink)
                    {
                        this.RequestInfo.EntityTracker.AttachLocation(descriptor2.Entity, str2, editLink);
                    }
                }
                if (this.streamRequestKind != StreamRequestKind.None)
                {
                    if (!WebUtil.SuccessStatusCode(statusCode))
                    {
                        if (this.streamRequestKind == StreamRequestKind.PostMediaResource)
                        {
                            descriptor.State = EntityStates.Added;
                        }
                        this.streamRequestKind             = StreamRequestKind.None;
                        descriptor.ContentGeneratedForSave = true;
                    }
                    else
                    {
                        string str3;
                        if ((this.streamRequestKind == StreamRequestKind.PostMediaResource) && headers.TryGetValue("ETag", out str3))
                        {
                            descriptor2.ETag = str3;
                        }
                    }
                }
            }
        }
Beispiel #2
0
        /// <summary>operation with HttpWebResponse</summary>
        /// <param name="statusCode">status code of the response.</param>
        /// <param name="headers">response headers.</param>
        protected void HandleOperationResponseHeaders(HttpStatusCode statusCode, HeaderCollection headers)
        {
            Descriptor descriptor = this.ChangedEntries[this.entryIndex];

            // in the first pass, the http response is packaged into a batch response (which is then processed in second pass).
            // in this first pass, (all added entities and first call of modified media link entities) update their edit location
            // added entities - so entities that have not sent content yet w/ reference links can inline those reference links in their payload
            // media entities - because they can change edit location which is then necessary for second call that includes property content
            if (descriptor.DescriptorKind == DescriptorKind.Entity)
            {
                EntityDescriptor entityDescriptor = (EntityDescriptor)descriptor;
                Debug.Assert(this.streamRequestKind != StreamRequestKind.PostMediaResource || descriptor.State == EntityStates.Modified, "For the POST MR, the entity state must be modified");

                // For POST and PATCH scenarios
                if (descriptor.State == EntityStates.Added ||
                    this.streamRequestKind == StreamRequestKind.PostMediaResource ||
                    !Util.IsFlagSet(this.Options, SaveChangesOptions.ReplaceOnUpdate))
                {
                    if (WebUtil.SuccessStatusCode(statusCode))
                    {
                        string location;
                        string odataEntityId;
                        Uri editLink = null;
                        headers.TryGetHeader(XmlConstants.HttpResponseLocation, out location);
                        headers.TryGetHeader(XmlConstants.HttpODataEntityId, out odataEntityId);

                        if (location != null)
                        {
                            // Verify the location header is an absolute uri
                            editLink = WebUtil.ValidateLocationHeader(location);
                        }
                        else if (descriptor.State == EntityStates.Added ||
                                 this.streamRequestKind == StreamRequestKind.PostMediaResource)
                        {
                            // For POST scenarios, location header must be specified.
                            throw Error.NotSupported(Strings.Deserialize_NoLocationHeader);
                        }

                        // Verify the id value if present. Otherwise we should use the location header
                        // as identity. This was done to avoid breaking change, since in V1/V2, we used
                        // to do this.
                        Uri odataId = null;
                        if (odataEntityId != null)
                        {
                            odataId = WebUtil.ValidateIdentityValue(odataEntityId);
                            if (location == null)
                            {
                                throw Error.NotSupported(Strings.Context_BothLocationAndIdMustBeSpecified);
                            }
                        }
                        else
                        {
                            // we already verified that the location must be an absolute uri
                            odataId = UriUtil.CreateUri(location, UriKind.Absolute);
                        }

                        if (null != editLink)
                        {
                            this.RequestInfo.EntityTracker.AttachLocation(entityDescriptor.Entity, odataId, editLink);
                        }
                    }
                }

                if (this.streamRequestKind != StreamRequestKind.None)
                {
                    if (!WebUtil.SuccessStatusCode(statusCode))
                    {
                        // If the request failed and it was the MR request we should not try to send the PUT MLE after it
                        // for one we don't have the location to send it to (if it was POST MR)
                        if (this.streamRequestKind == StreamRequestKind.PostMediaResource)
                        {
                            // If this was the POST MR it means we tried to add the entity. Now its state is Modified but we need
                            //   to revert back to Added so that user can retry by calling SaveChanges again.
                            Debug.Assert(descriptor.State == EntityStates.Modified, "Entity state should be set to Modified once we've sent the POST MR");
                            descriptor.State = EntityStates.Added;
                        }

                        // Just reset the streamRequestKind flag - that means that we will not try to PUT the MLE and instead skip over
                        //   to the next change (if we are to ignore errors that is)
                        this.streamRequestKind = StreamRequestKind.None;

                        // And we also need to mark it such that we generated the save content (which we did before the POST request in fact)
                        // to workaround the fact that we use the same descriptor object to track two requests.
                        descriptor.ContentGeneratedForSave = true;
                    }
                    else if (this.streamRequestKind == StreamRequestKind.PostMediaResource)
                    {
                        // We just finished a POST MR request and the PUT MLE coming immediately after it will
                        // need the new etag value from the server to succeed.
                        string etag;
                        if (headers.TryGetHeader(XmlConstants.HttpResponseETag, out etag))
                        {
                            entityDescriptor.ETag = etag;
                        }

                        // else is not interesting and we intentionally do nothing.
                    }
                }
            }
        }
Beispiel #3
0
 protected void HandleOperationResponseHeaders(HttpStatusCode statusCode, Dictionary<string, string> headers)
 {
     Descriptor descriptor = this.ChangedEntries[this.entryIndex];
     if (descriptor.DescriptorKind == DescriptorKind.Entity)
     {
         EntityDescriptor descriptor2 = (EntityDescriptor) descriptor;
         if ((((descriptor.State == EntityStates.Added) || (this.streamRequestKind == StreamRequestKind.PostMediaResource)) || Util.IsFlagSet(this.Options, SaveChangesOptions.PatchOnUpdate)) && WebUtil.SuccessStatusCode(statusCode))
         {
             string str;
             string str2;
             Uri editLink = null;
             headers.TryGetValue("Location", out str);
             headers.TryGetValue("DataServiceId", out str2);
             if (str != null)
             {
                 editLink = WebUtil.ValidateLocationHeader(str);
             }
             else if ((descriptor.State == EntityStates.Added) || (this.streamRequestKind == StreamRequestKind.PostMediaResource))
             {
                 throw System.Data.Services.Client.Error.NotSupported(System.Data.Services.Client.Strings.Deserialize_NoLocationHeader);
             }
             if (str2 != null)
             {
                 if (str == null)
                 {
                     throw System.Data.Services.Client.Error.NotSupported(System.Data.Services.Client.Strings.Context_BothLocationAndIdMustBeSpecified);
                 }
                 WebUtil.ValidateIdentityValue(str2);
             }
             else
             {
                 str2 = str;
             }
             if (null != editLink)
             {
                 this.RequestInfo.EntityTracker.AttachLocation(descriptor2.Entity, str2, editLink);
             }
         }
         if (this.streamRequestKind != StreamRequestKind.None)
         {
             if (!WebUtil.SuccessStatusCode(statusCode))
             {
                 if (this.streamRequestKind == StreamRequestKind.PostMediaResource)
                 {
                     descriptor.State = EntityStates.Added;
                 }
                 this.streamRequestKind = StreamRequestKind.None;
                 descriptor.ContentGeneratedForSave = true;
             }
             else
             {
                 string str3;
                 if ((this.streamRequestKind == StreamRequestKind.PostMediaResource) && headers.TryGetValue("ETag", out str3))
                 {
                     descriptor2.ETag = str3;
                 }
             }
         }
     }
 }