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