/// <summary> /// Parse a JSON response into a sequence of elements and also return /// the count of objects. This method abstracts out the differences /// between a raw array response and an inline count response. /// </summary> /// <param name="response">The JSON response.</param> /// <param name="totalCount"> /// The total count as requested via the IncludeTotalCount method. /// </param> /// <returns>The response as a JSON array.</returns> internal static JsonArray GetResponseSequence(IJsonValue response, out long totalCount) { double?inlineCount = null; // Try and get the values as an array JsonArray values = response.AsArray(); if (values == null) { // Otherwise try and get the values from the results property // (which is the case when we retrieve the count inline) values = response.Get(InlineCountResultsKey).AsArray(); inlineCount = response.Get(InlineCountCountKey).AsNumber(); if (values == null) { throw new InvalidOperationException( string.Format( CultureInfo.InvariantCulture, Resources.MobileServiceTables_GetResponseSequence_ExpectedArray, (response ?? JsonExtensions.Null()).Stringify())); } } // Get the count via the inline count or default an unspecified // count to -1 totalCount = inlineCount != null ? (long)inlineCount.Value : -1L; return(values); }
public void DataContractSerialization() { // Serialize a type with a data contract Animal bear = new Animal { Id = 1, Species = "Grizzly", Deadly = true, SoftAndFurry = true }; IJsonValue value = MobileServiceTableSerializer.Serialize(bear); Assert.AreEqual(1, value.Get("id").AsInteger()); Assert.AreEqual("Grizzly", value.Get("species").AsString()); Assert.IsTrue(value.Get("SoftAndFurry").AsBool().Value); Assert.IsTrue(value.Get("Deadly").IsNull()); // Deserialize a type with a data contract Animal donkey = MobileServiceTableSerializer.Deserialize <Animal>( new JsonObject() .Set("id", 2) .Set("species", "Stubbornus Maximums") .Set("Deadly", true) .Set("SoftAndFurry", false)); Assert.AreEqual(2, donkey.Id); Assert.AreEqual("Stubbornus Maximums", donkey.Species); Assert.IsFalse(donkey.SoftAndFurry); Assert.IsFalse(donkey.Deadly); // No DataMember so not serialized // Ensure we throw if we're missing a required Assert.Throws <SerializationException>(() => MobileServiceTableSerializer.Deserialize <Animal>( new JsonObject().Set("id", 3).Set("name", "Pterodactyl").Set("Deadly", true))); }
/// <summary> /// Log a user into a Mobile Services application given an access /// token. /// </summary> /// <param name="authenticationToken"> /// OAuth access token that authenticates the user. /// </param> /// <returns> /// Task that will complete when the user has finished authentication. /// </returns> public async Task <MobileServiceUser> SendLoginAsync(string authenticationToken) { if (authenticationToken == null) { throw new ArgumentNullException("authenticationToken"); } else if (string.IsNullOrEmpty(authenticationToken)) { throw new ArgumentException( string.Format( CultureInfo.InvariantCulture, Resources.EmptyArgumentExceptionMessage, "authenticationToken")); } JsonObject request = new JsonObject() .Set(LoginAsyncAuthenticationTokenKey, authenticationToken); IJsonValue response = await this.Client.RequestAsync("POST", LoginAsyncUriFragment, request, this.IgnoreFilters); // Get the Mobile Services auth token and user data this.Client.CurrentUser = new MobileServiceUser(response.Get("user").Get("userId").AsString()); this.Client.CurrentUser.MobileServiceAuthenticationToken = response.Get(LoginAsyncAuthenticationTokenKey).AsString(); return(this.Client.CurrentUser); }
/// <summary> /// Log a user into a Mobile Services application given an access /// token. /// </summary> /// <param name="authenticationToken"> /// OAuth access token that authenticates the user. /// </param> /// <returns> /// Task that will complete when the user has finished authentication. /// </returns> internal async Task <MobileServiceUser> SendLoginAsync(string authenticationToken) { if (authenticationToken == null) { throw new ArgumentNullException("authenticationToken"); } else if (string.IsNullOrEmpty(authenticationToken)) { throw new ArgumentException( string.Format( CultureInfo.InvariantCulture, Resources.EmptyArgumentExceptionMessage, "authenticationToken")); } // TODO: Decide what we should do when CurrentUser isn't null // (i.e., do we just log out the current user or should we throw // an exception?). For now we just overwrite the the current user // and their token on a successful login. JsonObject request = new JsonObject() .Set(LoginAsyncAuthenticationTokenKey, authenticationToken); IJsonValue response = await this.RequestAsync("POST", LoginAsyncUriFragment, request); // Get the Mobile Services auth token and user data this.currentUserAuthenticationToken = response.Get(LoginAsyncAuthenticationTokenKey).AsString(); this.CurrentUser = new MobileServiceUser(response.Get("user").Get("userId").AsString()); return(this.CurrentUser); }
private void SetupCurrentUser(IJsonValue value) { IJsonValue response = value; // Get the Mobile Services auth token and user data CurrentUser = new MobileServiceUser(response.Get("user").Get("userId").AsString()); CurrentUser.MobileServiceAuthenticationToken = response.Get(LoginAsyncAuthenticationTokenKey).AsString(); }
/// <summary> /// Throw an exception for an invalid response to a web request. /// </summary> /// <param name="request">The request.</param> /// <param name="response">The response.</param> /// <param name="body">The body of the response as JSON.</param> private static void ThrowInvalidResponse(IServiceFilterRequest request, IServiceFilterResponse response, IJsonValue body) { Debug.Assert(request != null, "request cannot be null!"); Debug.Assert(response != null, "response cannot be null!"); Debug.Assert( response.ResponseStatus != ServiceFilterResponseStatus.Success || response.StatusCode >= 400, "response should be failing!"); // Create either an invalid response or connection failed message // (check the status code first because some status codes will // set a protocol ErrorStatus). string message = null; if (response.StatusCode >= 400) { if (body != null) { if (body.ValueType == JsonValueType.String) { // User scripts might return errors with just a plain string message as the // body content, so use it as the exception message message = body.GetString(); } else if (body.ValueType == JsonValueType.Object) { // Get the error message, but default to the status description // below if there's no error message present. message = body.Get("error").AsString() ?? body.Get("description").AsString(); } } if (string.IsNullOrWhiteSpace(message)) { message = string.Format( CultureInfo.InvariantCulture, Resources.MobileServiceClient_ErrorMessage, response.StatusDescription); } } else { message = string.Format( CultureInfo.InvariantCulture, Resources.MobileServiceClient_ErrorMessage, response.ResponseStatus); } // Combine the pieces and throw the exception throw CreateMobileServiceException(message, request, response); }
public void CustomSerialization() { SimpleTree tree = new SimpleTree { Id = 1, Name = "John", Children = new List <SimpleTree> { new SimpleTree { Id = 2, Name = "James" }, new SimpleTree { Id = 3, Name = "David", Children = new List <SimpleTree> { new SimpleTree { Id = 4, Name = "Jennifer" } } } } }; IJsonValue family = MobileServiceTableSerializer.Serialize(tree); Assert.AreEqual("Jennifer", family.Get("children").AsArray()[1].Get("children").AsArray()[0].Get("name").AsString()); SimpleTree second = MobileServiceTableSerializer.Deserialize <SimpleTree>(family); Assert.AreEqual(tree.Children[0].Name, second.Children[0].Name); }
/// <summary> /// Throw an exception for an invalid response to a web request. /// </summary> /// <param name="request">The request.</param> /// <param name="response">The response.</param> /// <param name="body">The body of the response as JSON.</param> private static void ThrowInvalidResponse(IServiceFilterRequest request, IServiceFilterResponse response, IJsonValue body) { Debug.Assert(request != null, "request cannot be null!"); Debug.Assert(response != null, "response cannot be null!"); Debug.Assert( response.ResponseStatus != ServiceFilterResponseStatus.Success || response.StatusCode >= 400, "response should be failing!"); // Create either an invalid response or connection failed message // (check the status code first because some status codes will // set a protocol ErrorStatus). string message = null; if (response.StatusCode >= 400) { // Get the error message, but default to the status message // if there's no error message present. string error = body.Get("error").AsString() ?? body.Get("description").AsString() ?? response.StatusDescription; // Get the status code, text int code = body.Get("code").AsInteger() ?? response.StatusCode; // Combine the pieces and throw the exception message = string.Format(CultureInfo.InvariantCulture, Resources.MobileServiceClient_ThrowInvalidResponse_ErrorMessage, code, (HttpStatusCode)code, error, response.Content); } else { message = string.Format( CultureInfo.InvariantCulture, Resources.MobileServiceClient_ThrowConnectionFailure_ErrorMessage, response.ResponseStatus); } // Combine the pieces and throw the exception throw CreateMobileServiceException(message, request, response); }
void ICustomMobileServiceTableSerialization.Deserialize(IJsonValue value) { int?id = value.Get("id").AsInteger(); if (id != null) { Id = id.Value; } Name = value.Get("name").AsString(); JsonArray children = value.Get("children").AsArray(); if (children != null) { Children.AddRange(children.Select(MobileServiceTableSerializer.Deserialize <SimpleTree>)); } }
public void DataMemberJsonConverter() { // Serialize with a custom JSON converter IJsonValue link = MobileServiceTableSerializer.Serialize( new Hyperlink { Href = new Uri("http://www.microsoft.com/"), Alt = "Microsoft" }); Assert.AreEqual("Microsoft", link.Get("Alt").AsString()); Assert.AreEqual("http://www.microsoft.com/", link.Get("Href").AsString()); // Deserialize with a custom JSON converter Hyperlink azure = MobileServiceTableSerializer.Deserialize <Hyperlink>( new JsonObject().Set("Alt", "Windows Azure").Set("Href", "http://windowsazure.com")); Assert.AreEqual("Windows Azure", azure.Alt); Assert.AreEqual("windowsazure.com", azure.Href.Host); }
public void BasicSerialization() { // Serialize an instance without an ID IJsonValue value = MobileServiceTableSerializer.Serialize( new Person { Name = "John", Age = 45 }); Assert.AreEqual("John", value.Get("Name").AsString()); Assert.AreEqual(45, value.Get("Age").AsInteger()); Assert.IsNull(value.Get("id").AsInteger()); // Ensure the ID is written when provided // Serialize an instance without an ID value = MobileServiceTableSerializer.Serialize( new Person { Id = 2, Name = "John", Age = 45 }); Assert.AreEqual("John", value.Get("Name").AsString()); Assert.AreEqual(45, value.Get("Age").AsInteger()); Assert.AreEqual(2, value.Get("id").AsInteger()); // Ensure other properties are included but null value = MobileServiceTableSerializer.Serialize(new Person { Id = 12 }); string text = value.Stringify(); Assert.That(text, Contains.Substring("Name")); Assert.That(text, Contains.Substring("Age")); Assert.Throws <ArgumentNullException>(() => MobileServiceTableSerializer.Serialize(null)); }
public void Get() { IJsonValue obj = null; Assert.IsNull(obj.Get("fail")); obj = new JsonObject() .Set("a", "apple") .Set("b", "banana") .Set("c", "cherry"); Assert.AreEqual("apple", obj.Get("a").AsString()); Assert.AreEqual("banana", obj.Get("b").AsString()); Assert.AreEqual("cherry", obj.Get("c").AsString()); Assert.IsNull(obj.Get("d")); }
void ICustomMobileServiceTableSerialization.Deserialize(IJsonValue value) { int? id = value.Get("id").AsInteger(); if (id != null) { Id = id.Value; } Name = value.Get("name").AsString(); JsonArray children = value.Get("children").AsArray(); if (children != null) { Children.AddRange(children.Select(MobileServiceTableSerializer.Deserialize<SimpleTree>)); } }
/// <summary> /// Log a user into a Mobile Services application given a provider name and optional token object. /// </summary> /// <param name="provider" type="MobileServiceAuthenticationProvider"> /// Authentication provider to use. /// </param> /// <param name="token" type="JsonObject"> /// Optional, provider specific object with existing OAuth token to log in with. /// </param> /// <param name="useSingleSignOn"> /// Indicates that single sign-on should be used. Single sign-on requires that the /// application's Package SID be registered with the Windows Azure Mobile Service, but it /// provides a better experience as HTTP cookies are supported so that users do not have to /// login in everytime the application is launched. /// </param> /// <returns> /// Task that will complete when the user has finished authentication. /// </returns> public async Task <MobileServiceUser> SendLoginAsync(MobileServiceAuthenticationProvider provider, JsonObject token, bool useSingleSignOn) { if (this.LoginInProgress) { throw new InvalidOperationException(Resources.Platform_Login_Error_Response); } if (!Enum.IsDefined(typeof(MobileServiceAuthenticationProvider), provider)) { throw new ArgumentOutOfRangeException("provider"); } string providerName = provider.ToString().ToLower(); this.LoginInProgress = true; try { IJsonValue response = null; if (token != null) { // Invoke the POST endpoint to exchange provider-specific token for a Windows Azure Mobile Services token response = await this.Client.RequestAsync("POST", LoginAsyncUriFragment + "/" + providerName, token, this.IgnoreFilters); } else { // Use WebAuthenicationBroker to launch server side OAuth flow using the GET endpoint WebAuthenticationResult result = null; if (useSingleSignOn) { string endUri = WebAuthenticationBroker.GetCurrentApplicationCallbackUri().AbsoluteUri; Uri startUri = new Uri(this.Client.ApplicationUri, LoginAsyncUriFragment + "/" + providerName + "?sso_end_uri=" + endUri); result = await WebAuthenticationBroker.AuthenticateAsync(WebAuthenticationOptions.None, startUri); } else { Uri startUri = new Uri(this.Client.ApplicationUri, LoginAsyncUriFragment + "/" + providerName); Uri endUri = new Uri(this.Client.ApplicationUri, LoginAsyncDoneUriFragment); result = await WebAuthenticationBroker.AuthenticateAsync(WebAuthenticationOptions.None, startUri, endUri); } if (result.ResponseStatus == WebAuthenticationStatus.ErrorHttp) { throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, Resources.Authentication_Failed, result.ResponseErrorDetail)); } else if (result.ResponseStatus == WebAuthenticationStatus.UserCancel) { throw new InvalidOperationException(Resources.Authentication_Canceled); } int index = result.ResponseData.IndexOf("#token="); if (index > 0) { response = JsonValue.Parse(Uri.UnescapeDataString(result.ResponseData.Substring(index + 7))); } else { index = result.ResponseData.IndexOf("#error="); if (index > 0) { throw new InvalidOperationException(string.Format( CultureInfo.InvariantCulture, Resources.MobileServiceLogin_Login_Error_Response, Uri.UnescapeDataString(result.ResponseData.Substring(index + 7)))); } else { throw new InvalidOperationException(Resources.Platform_Login_Invalid_Response_Format); } } } // Get the Mobile Services auth token and user data this.Client.CurrentUser = new MobileServiceUser(response.Get("user").Get("userId").AsString()); this.Client.CurrentUser.MobileServiceAuthenticationToken = response.Get(LoginAsyncAuthenticationTokenKey).AsString(); } finally { this.LoginInProgress = false; } return(this.Client.CurrentUser); }