コード例 #1
0
        /// <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);
        }
コード例 #2
0
        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)));
        }
コード例 #3
0
        /// <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);
        }
コード例 #4
0
        /// <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);
        }
コード例 #5
0
        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();
        }
コード例 #6
0
        /// <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);
        }
コード例 #7
0
        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);
        }
コード例 #8
0
        /// <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);
        }
コード例 #9
0
        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>));
            }
        }
コード例 #10
0
        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);
        }
コード例 #11
0
        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));
        }
コード例 #12
0
        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"));
        }
コード例 #13
0
        /// <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);
        }
コード例 #14
0
        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>));
            }
        }
コード例 #15
0
        /// <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);
        }
コード例 #16
0
        /// <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);
        }