public void AnnotationRequiredMaxMinLengthTimestamp()
        {
            var requestMessage = new HttpWebRequestMessage(
                new DataServiceClientRequestMessageArgs(
                    "GET",
                    new Uri(this.ServiceBaseUri.OriginalString + "$metadata", UriKind.Absolute),
                    useDefaultCredentials: true,
                    usePostTunneling: false,
                    headers: new Dictionary<string, string>()));
            using (var r = new StreamReader(requestMessage.GetResponse().GetStream()))
            {
                var modelStr = r.ReadToEnd();

                // [Required] ==> Nullable="false"
                Assert.Contains(
                    "<Property Name=\"FirstName\" Type=\"Edm.String\" Nullable=\"false\" MaxLength=\"max\" />",
                    modelStr,
                    StringComparison.Ordinal);

                // [MaxLength] [MinLength] --> only MaxLength=".."
                Assert.Contains(
                    "<Property Name=\"LastName\" Type=\"Edm.String\" MaxLength=\"26\" />",
                    modelStr,
                    StringComparison.Ordinal);

                // [Timestamp] ==> Computed
                Assert.Contains(
                    "<Property Name=\"TimeStampValue\" Type=\"Edm.Binary\" Nullable=\"false\" MaxLength=\"8\">\r\n"
                        + "          <Annotation Term=\"Org.OData.Core.V1.Computed\" Bool=\"true\" />",
                    modelStr,
                    StringComparison.Ordinal);
            }
        }
 public void AnnotationComputedOptimisticConcurrency()
 {
     var requestMessage = new HttpWebRequestMessage(
         new DataServiceClientRequestMessageArgs(
             "GET",
             new Uri(this.ServiceBaseUri.OriginalString + "$metadata", UriKind.Absolute),
             true,
             false,
             new Dictionary<string, string>()));
     using (var r = new StreamReader(requestMessage.GetResponse().GetStream()))
     {
         var modelStr = r.ReadToEnd();
         Assert.Contains("<Annotation Term=\"Org.OData.Core.V1.Computed\" Bool=\"true\" />", modelStr, StringComparison.Ordinal);
         Assert.Contains("<Annotation Term=\"Org.OData.Core.V1.OptimisticConcurrency\">", modelStr, StringComparison.Ordinal);
     }
 }
        public HttpWebRequestMessage(DataServiceClientRequestMessageArgs args)
            : base(args.ActualMethod)
        {
            Util.CheckArgumentNull(args, "args");
            Debug.Assert(args.RequestUri.IsAbsoluteUri, "request uri is not absolute uri");
            Debug.Assert(
                args.RequestUri.Scheme.Equals("http", StringComparison.OrdinalIgnoreCase) ||
                args.RequestUri.Scheme.Equals("https", StringComparison.OrdinalIgnoreCase),
                "request uri is not for HTTP");
            this.effectiveHttpMethod = args.Method;
            this.requestUrl          = args.RequestUri;

            this.httpRequest = HttpWebRequestMessage.CreateRequest(this.ActualMethod, this.Url, args);

            // Now set the headers.
            foreach (var keyValue in args.Headers)
            {
                this.SetHeader(keyValue.Key, keyValue.Value);
            }
        }
        public void MetadataShouldContainEnumProperty()
        {
            var requestMessage = new HttpWebRequestMessage(
                new DataServiceClientRequestMessageArgs(
                    "GET",
                    new Uri(this.ServiceBaseUri.OriginalString + "$metadata", UriKind.Absolute),
                    true,
                    false,
                    new Dictionary<string, string>()));
            using (var r = new StreamReader(requestMessage.GetResponse().GetStream()))
            {
                var modelStr = r.ReadToEnd();

                Assert.Contains("<EnumType Name=\"Feature\">", modelStr, StringComparison.Ordinal);
                Assert.Contains("<Member Name=\"Feature1\" Value=\"0\" />", modelStr, StringComparison.Ordinal);
                Assert.Contains("<Member Name=\"Feature2\" Value=\"1\" />", modelStr, StringComparison.Ordinal);
                Assert.Contains("<Member Name=\"Feature3\" Value=\"2\" />", modelStr, StringComparison.Ordinal);
                Assert.Contains("<Member Name=\"Feature4\" Value=\"3\" />", modelStr, StringComparison.Ordinal);
                Assert.Contains("<Property Name=\"FavoriteFeature\"", modelStr, StringComparison.Ordinal);
            }
        }
Exemple #5
0
        /// <summary>
        /// Returns an instance of the IODataRequestMessage 
        /// </summary>
        /// <param name="requestMessageArgs">Arguments for creating the request message.</param>
        /// <returns>an instance of the IODataRequestMessage </returns>
        internal DataServiceClientRequestMessage CreateRequestMessage(BuildingRequestEventArgs requestMessageArgs)
        {
            var headersDictionary = requestMessageArgs.HeaderCollection.UnderlyingDictionary;

            // We are implementing the PostTunneling logic here. The reason for doing this is
            // 1> In this public class, the Method property returns the actual method (PUT, PATCH, DELETE),
            //    and not the verb that goes in the wire. So this class needs to know about
            //    actual verb since it will be using this verb to send over http.     
            if (this.UsePostTunneling)
            {
                bool setXHttpMethodHeader = false;
                if (string.CompareOrdinal(XmlConstants.HttpMethodGet, requestMessageArgs.Method) != 0 &&
                    string.CompareOrdinal(XmlConstants.HttpMethodPost, requestMessageArgs.Method) != 0)
                {
                    setXHttpMethodHeader = true;
                }

                // Setting the actual method in the header
                if (setXHttpMethodHeader)
                {
                    headersDictionary[XmlConstants.HttpXMethod] = requestMessageArgs.Method;
                }

                // Set the Content-length of a Delete to 0. Important for post tunneling when its a post, content-length must be zero in this case.
                if (string.CompareOrdinal(XmlConstants.HttpMethodDelete, requestMessageArgs.Method) == 0)
                {
                    headersDictionary[XmlConstants.HttpContentLength] = "0";

#if DEBUG
                    if (!this.UserModifiedRequestInBuildingRequest)
                    {
                        Debug.Assert(!requestMessageArgs.HeaderCollection.HasHeader(XmlConstants.HttpContentType), "Content-Type header must not be set for DELETE requests");
                    }
#endif
                }
            }

            var clientRequestMessageArgs = new DataServiceClientRequestMessageArgs(requestMessageArgs.Method, requestMessageArgs.RequestUri, this.UseDefaultCredentials, this.UsePostTunneling, headersDictionary);
            DataServiceClientRequestMessage clientRequestMessage;
            if (this.Configurations.RequestPipeline.OnMessageCreating != null)
            {
                clientRequestMessage = this.Configurations.RequestPipeline.OnMessageCreating(clientRequestMessageArgs);
                if (clientRequestMessage == null)
                {
                    throw Error.InvalidOperation(Strings.Context_OnMessageCreatingReturningNull);
                }
            }
            else
            {
                clientRequestMessage = new HttpWebRequestMessage(clientRequestMessageArgs);
            }

            return clientRequestMessage;
        }
Exemple #6
0
        private void TestGet(string relativeUri, string expectedPayload)
        {
            var headers = new Dictionary<string, string>
            {
                { "Content-Type", "application/json" }
            };

            var request = new HttpWebRequestMessage(
                new DataServiceClientRequestMessageArgs(
                    "Get",
                    new Uri(this.TestClientContext.BaseUri, relativeUri),
                    false,
                    false,
                    headers));
            using (var response = request.GetResponse() as HttpWebResponseMessage)
            {
                Assert.Equal(200, response.StatusCode);
                using (var stream = response.GetStream())
                {
                    var reader = new StreamReader(stream);
                    var content = reader.ReadToEnd();
                    Assert.Equal(expectedPayload, content);
                }
            }
        }
Exemple #7
0
        private void TestPut(string relativeUri, string payload)
        {
            var headers = new Dictionary<string, string>
            {
                { "Content-Type", "application/json" }
            };

            var request = new HttpWebRequestMessage(
                new DataServiceClientRequestMessageArgs(
                    "Put",
                    new Uri(this.TestClientContext.BaseUri, relativeUri),
                    false,
                    false,
                    headers));
            using (var stream = request.GetStream())
            using (var writer = new StreamWriter(stream))
            {
                writer.Write(payload);
            }

            using (var response = request.GetResponse() as HttpWebResponseMessage)
            {
                Assert.Equal(200, response.StatusCode);
            }
        }
        public void RequestNonExistingEntityShouldReturnNotFound()
        {
            var requestMessage = new HttpWebRequestMessage(
                new DataServiceClientRequestMessageArgs(
                    "GET",
                    new Uri(this.ServiceBaseUri.OriginalString + "Airlines('NonExisting')", UriKind.Absolute),
                    useDefaultCredentials: true,
                    usePostTunneling: false,
                    headers: new Dictionary<string, string>()));

            DataServiceTransportException exception = null;

            try
            {
                requestMessage.GetResponse();
            }
            catch (DataServiceTransportException e)
            {
                exception = e;
            }

            Assert.NotNull(exception);
            Assert.Equal(404, exception.Response.StatusCode);
        }
        public void QueryWithFormat()
        {
            Dictionary<string, string> testCases = new Dictionary<string, string>()
            {
                {"People?$format=application/json", "application/json"},
                // ODL Bug: https://github.com/OData/odata.net/issues/313
                ////{"People?$format=application/json;odata.metadata=full", "application/json; odata.metadata=full"},
                {"People?$format=json", "application/json"},
            };

            ODataMessageReaderSettings readerSettings = new ODataMessageReaderSettings() { BaseUri = ServiceBaseUri };
            foreach (var testCase in testCases)
            {
                DataServiceClientRequestMessageArgs args = new DataServiceClientRequestMessageArgs(
                    "GET",
                    new Uri(ServiceBaseUri.AbsoluteUri + testCase.Key, UriKind.Absolute),
                    false, false, new Dictionary<string, string>() { });

                var requestMessage = new HttpWebRequestMessage(args);
                using (var responseMessage = requestMessage.GetResponse() as HttpWebResponseMessage)
                {
                    Assert.Equal(200, responseMessage.StatusCode);

                    string contentType = responseMessage.Headers.FirstOrDefault(x => x.Key.Equals("Content-Type")).Value;
                    Assert.True(contentType.StartsWith(testCase.Value));

                    using (var messageReader = new ODataMessageReader(
                        responseMessage,
                        readerSettings,
                        this.TestClientContext.Format.LoadServiceModel()))
                    {
                        var reader = messageReader.CreateODataFeedReader();

                        while (reader.Read())
                        {
                            if (reader.State == ODataReaderState.EntryEnd)
                            {
                                ODataEntry entry = reader.Item as ODataEntry;
                                Assert.NotNull(entry.Properties.Single(p => p.Name == "PersonId").Value);
                            }
                            else if (reader.State == ODataReaderState.FeedEnd)
                            {
                                Assert.NotNull(reader.Item as ODataFeed);
                            }
                        }

                        Assert.Equal(ODataReaderState.Completed, reader.State);
                    }
                }
            }
        }
 private void TestPostStatusCodeIs(string uriStringAfterServiceRoot, int statusCode)
 {
     var requestMessage = new HttpWebRequestMessage(
         new DataServiceClientRequestMessageArgs(
             "POST",
             new Uri(this.ServiceBaseUri.OriginalString + uriStringAfterServiceRoot, UriKind.Absolute),
             useDefaultCredentials: true,
             usePostTunneling: false,
             headers: new Dictionary<string, string>() { { "Content-Length", "0" } }));
     Assert.Equal(statusCode, requestMessage.GetResponse().StatusCode);
 }
 /// <summary>
 /// Returns the value of the header with the given name.
 /// </summary>
 /// <param name="headerName">Name of the header.</param>
 /// <returns>Returns the value of the header with the given name.</returns>
 public override string GetHeader(string headerName)
 {
     Util.CheckArgumentNullAndEmpty(headerName, "headerName");
     return(HttpWebRequestMessage.GetHeaderValue(this.httpRequest, headerName));
 }
        public void UQProperty()
        {
            this.TestClientContext.MergeOption = MergeOption.OverwriteChanges;
            // Post an entity
            Person person = new Person()
            {
                FirstName = "Sheldon",
                LastName = "Cooper",
                UserName = "******"
            };

            this.TestClientContext.AddToPeople(person);
            this.TestClientContext.SaveChanges();
            int personId = person.PersonId;

            // Query a property
            var lastName = this.TestClientContext.People
                .Where(p => p.PersonId == personId).Select(p => p.LastName)
                .SingleOrDefault();
            Assert.Equal("Cooper", lastName);

            // Update a property
            Dictionary<string, string> headers = new Dictionary<string, string>() 
            {
                { "Content-Type", "application/json" } 
            };

            HttpWebRequestMessage request = new HttpWebRequestMessage(
                new DataServiceClientRequestMessageArgs(
                    "Put",
                    new Uri(string.Format(this.TestClientContext.BaseUri + "/People({0})/LastName", personId),
                        UriKind.Absolute),
                    false,
                    false,
                    headers));
            using (var stream = request.GetStream())
            using (StreamWriter writer = new StreamWriter(stream))
            {
                var Payload = @"{""value"":""Lee""}";
                writer.Write(Payload);
            }

            using (var response = request.GetResponse() as HttpWebResponseMessage)
            {
                Assert.Equal(200, response.StatusCode);
            }

            // Query a property's value : ~/$value
            headers.Clear();
            ODataMessageReaderSettings readerSettings = new ODataMessageReaderSettings { BaseUri = this.TestClientContext.BaseUri };

            request = new HttpWebRequestMessage(
                new DataServiceClientRequestMessageArgs(
                    "Get",
                    new Uri(string.Format(this.TestClientContext.BaseUri + "/People({0})/LastName/$value", personId),
                        UriKind.Absolute),
                    false,
                    false,
                    headers));
            using (var response = request.GetResponse() as HttpWebResponseMessage)
            {
                Assert.Equal(200, response.StatusCode);
                using (var stream = response.GetStream())
                {
                    StreamReader reader = new StreamReader(stream);
                    var expectedPayload = "Lee";
                    var content = reader.ReadToEnd();
                    Assert.Equal(expectedPayload, content);
                }
            }
        }
 public void MetadataShouldContainDerivedType()
 {
     var requestMessage = new HttpWebRequestMessage(
         new DataServiceClientRequestMessageArgs(
             "GET",
             new Uri(this.ServiceBaseUri.OriginalString + "$metadata", UriKind.Absolute),
             true,
             false,
             new Dictionary<string, string>()));
     using (var r = new StreamReader(requestMessage.GetResponse().GetStream()))
     {
         var modelStr = r.ReadToEnd();
         Assert.Contains("<EntityType Name=\"Manager\" BaseType=\"Microsoft.OData.Service.Sample.Trippin.Models.Person\">", modelStr, StringComparison.Ordinal);
         Assert.Contains("<EntityType Name=\"Employee\" BaseType=\"Microsoft.OData.Service.Sample.Trippin.Models.Person\">", modelStr, StringComparison.Ordinal);
     }
 }
        private void SendRequest(HttpWebRequestMessage requestMessage)
        {
            Assert.IsNotNull(requestMessage, "sendRequest test hook was called with null request message");
            Dictionary<string, string> headers = WrapHttpHeaders(requestMessage.HttpWebRequest.Headers);
            headers.Add("__Uri", requestMessage.HttpWebRequest.RequestUri.AbsoluteUri);
            headers.Add("__HttpVerb", requestMessage.HttpWebRequest.Method);
            requestHeaders.Add(headers);

            if (null != this.CustomSendRequestAction)
            {
                this.CustomSendRequestAction(requestMessage.HttpWebRequest);
            }
        }
        /// <summary>
        /// Loads the metadata and converts it into an EdmModel that is then used by a dataservice context
        /// This allows the user to use the DataServiceContext directly without having to manually pass an IEdmModel in the Format
        /// </summary>
        /// <returns>A service model to be used in format tracking</returns>
        internal IEdmModel LoadServiceModelFromNetwork()
        {
            HttpWebRequestMessage    httpRequest;
            BuildingRequestEventArgs requestEventArgs = null;

            // test hook for injecting a network request to use instead of the default
            if (InjectMetadataHttpNetworkRequest != null)
            {
                httpRequest = InjectMetadataHttpNetworkRequest();
            }
            else
            {
                requestEventArgs = new BuildingRequestEventArgs(
                    "GET",
                    context.GetMetadataUri(),
                    null,
                    null,
                    context.HttpStack);

                // fire the right events if they exist to allow user to modify the request
                if (context.HasBuildingRequestEventHandlers)
                {
                    requestEventArgs = context.CreateRequestArgsAndFireBuildingRequest(
                        requestEventArgs.Method,
                        requestEventArgs.RequestUri,
                        requestEventArgs.HeaderCollection,
                        requestEventArgs.ClientHttpStack,
                        requestEventArgs.Descriptor);
                }

                DataServiceClientRequestMessageArgs args = new DataServiceClientRequestMessageArgs(
                    requestEventArgs.Method,
                    requestEventArgs.RequestUri,
                    context.UseDefaultCredentials,
                    context.UsePostTunneling,
                    requestEventArgs.Headers);

                httpRequest = new HttpWebRequestMessage(args);
            }

            Descriptor descriptor = requestEventArgs != null ? requestEventArgs.Descriptor : null;

            // fire the right events if they exist
            if (context.HasSendingRequest2EventHandlers)
            {
                SendingRequest2EventArgs eventArgs = new SendingRequest2EventArgs(
                    httpRequest,
                    descriptor,
                    false);

                context.FireSendingRequest2(eventArgs);
            }

            Task <IODataResponseMessage> asyncResponse =
                Task <IODataResponseMessage> .Factory.FromAsync(httpRequest.BeginGetResponse, httpRequest.EndGetResponse,
                                                                httpRequest);

            IODataResponseMessage response = asyncResponse.GetAwaiter().GetResult();

            ReceivingResponseEventArgs responseEvent = new ReceivingResponseEventArgs(response, descriptor);

            context.FireReceivingResponseEvent(responseEvent);

            using (StreamReader streamReader = new StreamReader(response.GetStream()))
                using (XmlReader xmlReader = XmlReader.Create(streamReader))
                {
                    return(CsdlReader.Parse(xmlReader));
                }
        }
        public void CURDSingleNavigationPropertyAndRef()
        {
            this.TestClientContext.MergeOption = Microsoft.OData.Client.MergeOption.OverwriteChanges;

            Airline airline = new Airline()
            {
                Name = "American Delta",
                AirlineCode = "DL",
                TimeStampValue = new byte[] { 0 }
            };

            this.TestClientContext.AddToAirlines(airline);
            this.TestClientContext.SaveChanges();

            // Post an entity
            Flight flight = new Flight()
            {
                ConfirmationCode = "JH58496",
                FlightNumber = "DL589",
                StartsAt = new DateTimeOffset(new DateTime(2014, 2, 10, 15, 00, 0)),
                EndsAt = new DateTimeOffset(new DateTime(2014, 2, 10, 16, 30, 0)),
                AirlineId = null,
                SeatNumber = "C32",
                FromId = "KSEA",
                ToId = "ZSSS"
            };

            this.TestClientContext.AddToFlights(flight);
            this.TestClientContext.SaveChanges();

            // Set $ref
            this.TestClientContext.SetLink(flight, "Airline", airline);
            this.TestClientContext.SaveChanges();

            this.TestClientContext.Detach(airline);
            // Query an Navigation Property
            var airline2 = this.TestClientContext.Flights
                .ByKey(new Dictionary<string, object>() { { "FlightId", flight.FlightId } })
                .Airline.GetValue();
            Assert.Equal(airline.AirlineCode, airline2.AirlineCode);

            // Expand an Navigation Property
            var flight2 = this.TestClientContext.Flights
                .Expand(f => f.From)
                .Expand(f => f.To)
                .Where(f => f.FlightId == flight.FlightId)
                .SingleOrDefault();
            Assert.Equal(flight.FromId, flight2.From.IcaoCode);
            Assert.Equal(flight.ToId, flight2.To.IcaoCode);

            // Expand with select
            this.TestClientContext.Detach(flight2.From);
            var flight3 = this.TestClientContext.Flights
                .AddQueryOption("$expand", "From($select=IcaoCode)")
                .Where(f => f.FlightId == flight.FlightId)
                .SingleOrDefault();
            Assert.Equal(flight.FromId, flight3.From.IcaoCode);
            Assert.Null(flight3.From.IataCode);

            // Get $ref
            Dictionary<string, string> headers = new Dictionary<string, string>();
            ODataMessageReaderSettings readerSettings = new ODataMessageReaderSettings { BaseUri = this.TestClientContext.BaseUri };

            HttpWebRequestMessage request = new HttpWebRequestMessage(
                new DataServiceClientRequestMessageArgs(
                    "Get",
                    new Uri(string.Format(this.TestClientContext.BaseUri + "/Flights({0})/Airline/$ref", flight.FlightId),
                        UriKind.Absolute),
                    false,
                    false,
                    headers));

            using (HttpWebResponseMessage response = request.GetResponse() as HttpWebResponseMessage)
            {
                Assert.Equal(200, response.StatusCode);
                using (var stream = response.GetStream())
                {
                    StreamReader reader = new StreamReader(stream);
                    var expectedPayload = "{"
                        + "\r\n"
                        + @"  ""@odata.context"":""http://*****:*****@"""@odata.id"":""http://localhost:18384/api/Trippin/Airlines('{0}')""", airline2.AirlineCode)
                        + "\r\n"
                        + "}";
                    var content = reader.ReadToEnd();
                    Assert.Equal(expectedPayload, content);
                }
            }

            // Delete $ref
            this.TestClientContext.SetLink(flight, "Airline", null);
            this.TestClientContext.SaveChanges();

            this.TestClientContext.Detach(airline);

            HttpWebRequestMessage request2 = new HttpWebRequestMessage(
                new DataServiceClientRequestMessageArgs(
                    "Get",
                    new Uri(string.Format(this.TestClientContext.BaseUri + "/Flights({0})/Airline/$ref", flight.FlightId)
                        , UriKind.Absolute),
                    false,
                    false,
                    headers));

            DataServiceTransportException exception = null;

            try
            {
                request2.GetResponse();
            }
            catch (DataServiceTransportException e)
            {
                exception = e;
            }
            Assert.NotNull(exception);
            Assert.Equal(404, exception.Response.StatusCode);

            // TODO GitHubIssue#48 : Add case for null entity return value
            // WebApi doesn't allow return a null entity.
            // Query an Navigation Property
            //airline2 = this.TestClientContext.Flights.ByKey(new Dictionary<string, object>() { { "FlightId", flight.FlightId } }).Airline.GetValue();
            //Assert.Null(airline2);
        }
        public void CURDCollectionNavigationPropertyAndRef()
        {
            this.TestClientContext.MergeOption = MergeOption.OverwriteChanges;

            Person person = new Person()
            {
                FirstName = "Sheldon",
                LastName = "Cooper",
                UserName = "******"
            };

            this.TestClientContext.AddToPeople(person);
            this.TestClientContext.SaveChanges();
            int personId = person.PersonId;

            var startDate = DateTime.Now;
            Trip trip1 = new Trip()
            {
                PersonId = personId,
                TrackGuid = Guid.NewGuid(),
                ShareId = new Guid("c95d15e8-582b-44cf-9e97-ff63a5f26091"),
                Name = "Honeymoon",
                Budget = 2000.0f,
                Description = "Happy honeymoon trip",
                StartsAt = startDate,
                EndsAt = startDate.AddDays(3),
                LastUpdated = DateTime.UtcNow,
            };

            Trip trip2 = new Trip()
            {
                PersonId = personId,
                TrackGuid = Guid.NewGuid(),
                ShareId = new Guid("56947cf5-2133-43b8-81f0-b6c3f1e5e51a"),
                Name = "Honeymoon",
                Budget = 3000.0f,
                Description = "Happy honeymoon trip",
                StartsAt = startDate.AddDays(1),
                EndsAt = startDate.AddDays(5),
                LastUpdated = DateTime.UtcNow,
            };

            this.TestClientContext.AddToTrips(trip1);
            this.TestClientContext.SaveChanges();

            // Create a related entity by Navigation link
            this.TestClientContext.AddRelatedObject(person, "Trips", trip2);
            this.TestClientContext.SaveChanges();

            // Query Navigation properties.
            var trips = this.TestClientContext.People
                .ByKey(new Dictionary<string, object> { { "PersonId", personId } })
                .Trips.ToList();
            Assert.Equal(2, trips.Count());
            Assert.True(trips.Any(t => t.TripId == trip1.TripId));
            Assert.True(trips.Any(t => t.TripId == trip2.TripId));

            // Get $ref
            HttpWebRequestMessage request = new HttpWebRequestMessage(
                new DataServiceClientRequestMessageArgs(
                    "Get",
                    new Uri(string.Format(this.TestClientContext.BaseUri + "/People({0})/Trips/$ref", personId),
                        UriKind.Absolute),
                    false,
                    false,
                    new Dictionary<string, string>()));

            using (var response = request.GetResponse() as HttpWebResponseMessage)
            {
                Assert.Equal(200, response.StatusCode);
                using (var stream = response.GetStream())
                {
                    StreamReader reader = new StreamReader(stream);
                    var expectedPayload = "{"
                        + "\r\n"
                        + @"  ""@odata.context"":""http://*****:*****@"    {"
                        + "\r\n"
                        + string.Format(@"      ""@odata.id"":""http://*****:*****@"      ""@odata.id"":""http://localhost:18384/api/Trippin/Trips({0})""", trip2.TripId)
                        + "\r\n"
                        + "    }"
                        + "\r\n"
                        + "  ]"
                        + "\r\n"
                        + "}";
                    var content = reader.ReadToEnd();
                    Assert.Equal(expectedPayload, content);
                }
            }

            // Delete $ref
            this.TestClientContext.DeleteLink(person, "Trips", trip2);
            this.TestClientContext.SaveChanges();

            // Expand Navigation properties
            this.TestClientContext.Detach(trip1);
            person = this.TestClientContext.People
                .ByKey(new Dictionary<string, object> { { "PersonId", personId } })
                .Expand(t => t.Trips)
                .GetValue();
            Assert.Equal(1, person.Trips.Count);
            Assert.True(person.Trips.Any(t => t.TripId == trip1.TripId));

            Person person2 = new Person()
            {
                FirstName = "Sheldon2",
                LastName = "Cooper2",
                UserName = "******"
            };

            this.TestClientContext.AddToPeople(person2);
            this.TestClientContext.SaveChanges();
            personId = person2.PersonId;

            // Add $ref
            this.TestClientContext.AddLink(person2, "Trips", trip2);
            this.TestClientContext.SaveChanges();

            // Expand Navigation properties
            this.TestClientContext.Detach(trip1);
            this.TestClientContext.Detach(trip2);
            person = this.TestClientContext.People
                .ByKey(new Dictionary<string, object> { { "PersonId", personId } })
                .Expand(t => t.Trips)
                .GetValue();
            Assert.Equal(1, person.Trips.Count);
            Assert.True(person.Trips.Any(t => t.TripId == trip2.TripId));
        }
 private void TestPayloadString(string uriAfterServiceRoot, Action<string> testMethod)
 {
     var requestMessage = new HttpWebRequestMessage(
         new DataServiceClientRequestMessageArgs(
             "GET",
             new Uri(this.ServiceBaseUri, uriAfterServiceRoot),
             true,
             false,
             new Dictionary<string, string>()));
     using (var r = new StreamReader(requestMessage.GetResponse().GetStream()))
     {
         var payloadStr = r.ReadToEnd();
         testMethod(payloadStr);
     }
 }
 private void TestPostPayloadContains(string uriStringAfterServiceRoot, string expectedSubString)
 {
     var requestMessage = new HttpWebRequestMessage(
         new DataServiceClientRequestMessageArgs(
             "POST",
             new Uri(this.ServiceBaseUri.OriginalString + uriStringAfterServiceRoot, UriKind.Absolute),
             useDefaultCredentials: true,
             usePostTunneling: false,
             headers: new Dictionary<string, string>() { { "Content-Length", "0" } }));
     using (var r = new StreamReader(requestMessage.GetResponse().GetStream()))
     {
         var payloadString = r.ReadToEnd();
         Assert.Contains(expectedSubString, payloadString);
     }
 }