Пример #1
0
        /// <summary>
        /// Executes a request and transforms a 412 and 409 response to respective exception type.
        /// </summary>
        private async Task <JToken> TransformHttpException(MobileServiceSerializer serializer, Func <Task <JToken> > action)
        {
            try
            {
                return(await action());
            }
            catch (MobileServiceInvalidOperationException ex)
            {
                if (ex.Response.StatusCode != HttpStatusCode.PreconditionFailed &&
                    ex.Response.StatusCode != HttpStatusCode.Conflict)
                {
                    throw;
                }

                T item = default(T);
                try
                {
                    item = serializer.Deserialize <T>(ex.Value);
                }
                catch { }

                if (ex.Response.StatusCode == HttpStatusCode.PreconditionFailed)
                {
                    throw new MobileServicePreconditionFailedException <T>(ex, item);
                }
                else if (ex.Response.StatusCode == HttpStatusCode.Conflict)
                {
                    throw new MobileServiceConflictException <T>(ex, item);
                }
                throw;
            }
        }
        /// <summary>
        /// Inserts an <paramref name="instance"/> into the table.
        /// </summary>
        /// <param name="instance">
        /// The instance to insert into the table.
        /// </param>
        /// <param name="parameters">
        /// A dictionary of user-defined parameters and values to include in
        /// the request URI query string.
        /// </param>
        /// <returns>
        /// A task that will complete when the insert finishes.
        /// </returns>
        public async Task <JToken> InsertAsync(JObject instance, IDictionary <string, string> parameters)
        {
            if (instance == null)
            {
                throw new ArgumentNullException("instance");
            }

            // Make sure the instance doesn't have an int id set for an insertion
            object id = MobileServiceSerializer.GetId(instance, ignoreCase: false, allowDefault: true);
            bool   isStringIdOrDefaultIntId = id is string || MobileServiceSerializer.IsDefaultId(id);

            if (!isStringIdOrDefaultIntId)
            {
                throw new ArgumentException(
                          string.Format(
                              CultureInfo.InvariantCulture,
                              Resources.MobileServiceTable_InsertWithExistingId,
                              MobileServiceSerializer.IdPropertyName),
                          "instance");
            }

            parameters = AddSystemProperties(this.SystemProperties, parameters);

            string uriString = GetUri(this.TableName, null, parameters);
            MobileServiceHttpResponse response = await this.MobileServiceClient.HttpClient.RequestAsync(HttpMethod.Post, uriString, this.MobileServiceClient.CurrentUser, instance.ToString(Formatting.None), true);

            return(GetJTokenFromResponse(response));
        }
        /// <summary>
        /// Updates an instance in the table.
        /// </summary>
        /// <param name="instance">
        /// The instance to update.
        /// </param>
        /// <param name="parameters">
        /// A dictionary of user-defined parameters and values to include in
        /// the request URI query string.
        /// </param>
        /// <returns>
        /// A task that will complete when the update has finished.
        /// </returns>
        public async Task UpdateAsync(T instance, IDictionary <string, string> parameters)
        {
            if (instance == null)
            {
                throw new ArgumentNullException("instance");
            }

            MobileServiceSerializer serializer = this.MobileServiceClient.Serializer;
            JObject value = serializer.Serialize(instance) as JObject;

            JToken updatedValue = null;

            try
            {
                updatedValue = await this.UpdateAsync(value, parameters);
            }
            catch (MobileServicePreconditionFailedException ex)
            {
                T item = default(T);
                try
                {
                    item = serializer.Deserialize <T>(ex.Value);
                }
                catch { }

                throw new MobileServicePreconditionFailedException <T>(ex, item);
            }

            serializer.Deserialize <T>(updatedValue, instance);
        }
Пример #4
0
        /// <summary>
        /// Refresh the current instance with the latest values from the
        /// table.
        /// </summary>
        /// <param name="instance">
        /// The instance to refresh.
        /// </param>
        /// <param name="parameters">
        /// A dictionary of user-defined parameters and values to include in
        /// the request URI query string.
        /// </param>
        /// <returns>
        /// A task that will complete when the refresh has finished.
        /// </returns>
        public async Task RefreshAsync(T instance, IDictionary <string, string> parameters)
        {
            if (instance == null)
            {
                throw new ArgumentNullException("instance");
            }

            MobileServiceSerializer serializer = this.MobileServiceClient.Serializer;
            object id = serializer.GetId(instance, allowDefault: true);

            if (MobileServiceSerializer.IsDefaultId(id))
            {
                return;
            }
            if (id is string)
            {
                MobileServiceSerializer.EnsureValidStringId(id, allowDefault: true);
            }

            // Get the latest version of this element
            JObject refreshed = await this.GetSingleValueAsync(id, parameters);

            // Deserialize that value back into the current instance
            serializer.Deserialize <T>(refreshed, instance);
        }
Пример #5
0
        /// <summary>
        /// Updates an instance in the table.
        /// </summary>
        /// <param name="instance">
        /// The instance to update.
        /// </param>
        /// <param name="parameters">
        /// A dictionary of user-defined parameters and values to include in
        /// the request URI query string.
        /// </param>
        /// <returns>
        /// A task that will complete when the update has finished.
        /// </returns>
        public async Task UpdateAsync(T instance, IDictionary <string, string> parameters)
        {
            if (instance == null)
            {
                throw new ArgumentNullException("instance");
            }

            MobileServiceSerializer serializer = this.MobileServiceClient.Serializer;
            object id = serializer.GetId(instance);

            if (serializer.IsDefaultId(id))
            {
                throw new ArgumentException(
                          string.Format(
                              CultureInfo.InvariantCulture,
                              Resources.MobileServiceTable_UpdateWithoutId,
                              MobileServiceUrlBuilder.IdPropertyName),
                          "instance");
            }

            string value        = serializer.Serialize(instance);
            string updatedValue = await this.SendUpdateAsync(id, value, parameters);

            serializer.Deserialize <T>(updatedValue, instance);
        }
Пример #6
0
        /// <summary>
        /// Inserts a new instance into the table.
        /// </summary>
        /// <param name="instance">
        /// The instance to insert.
        /// </param>
        /// <param name="parameters">
        /// A dictionary of user-defined parameters and values to include in
        /// the request URI query string.
        /// </param>
        /// <returns>
        /// A task that will complete when the insertion has finished.
        /// </returns>
        public async Task InsertAsync(T instance, IDictionary <string, string> parameters)
        {
            if (instance == null)
            {
                throw new ArgumentNullException("instance");
            }

            MobileServiceSerializer serializer = this.MobileServiceClient.Serializer;

            object id = serializer.GetId(instance);

            // Make sure the instance doesn't have an id set for an insertion
            if (!serializer.IsDefaultId(id))
            {
                throw new ArgumentException(
                          string.Format(
                              CultureInfo.InvariantCulture,
                              Resources.MobileServiceTable_InsertWithExistingId,
                              MobileServiceUrlBuilder.IdPropertyName),
                          "instance");
            }

            string value         = serializer.Serialize(instance);
            string insertedValue = await this.SendInsertAsync(value, parameters);

            serializer.Deserialize <T>(insertedValue, instance);
        }
Пример #7
0
        /// <summary>
        /// Deletes an instance from the table.
        /// </summary>
        /// <param name="instance">
        /// The instance to delete.
        /// </param>
        /// <param name="parameters">
        /// A dictionary of user-defined parameters and values to include in
        /// the request URI query string.
        /// </param>
        /// <returns>
        /// A task that will complete when the delete has finished.
        /// </returns>
        public async Task DeleteAsync(T instance, IDictionary <string, string> parameters)
        {
            if (instance == null)
            {
                throw new ArgumentNullException("instance");
            }

            MobileServiceSerializer serializer = this.MobileServiceClient.Serializer;
            object id = serializer.GetId(instance);

            if (serializer.IsDefaultId(id))
            {
                throw new ArgumentException(
                          string.Format(
                              CultureInfo.InvariantCulture,
                              Resources.MobileServiceTable_DeleteWithoutId,
                              MobileServiceUrlBuilder.IdPropertyName),
                          "instance");
            }

            // Send the request
            await this.SendDeleteAsync(id, parameters);

            // Clear the instance id since it's no longer associated with that
            // id on the server (note that reflection is goodly enough to turn
            // null into the correct value for us).
            serializer.ClearId(instance);
        }
        /// <summary>
        /// Inserts an <paramref name="instance"/> into the table.
        /// </summary>
        /// <param name="instance">
        /// The instance to insert into the table.
        /// </param>
        /// <param name="parameters">
        /// A dictionary of user-defined parameters and values to include in
        /// the request URI query string.
        /// </param>
        /// <param name="features">
        /// Value indicating which features of the SDK are being used in this call. Useful for telemetry.
        /// </param>
        /// <returns>
        /// A task that will complete when the insert finishes.
        /// </returns>
        internal async Task <JToken> InsertAsync(JObject instance, IDictionary <string, string> parameters, MobileServiceFeatures features)
        {
            if (instance == null)
            {
                throw new ArgumentNullException("instance");
            }

            // Make sure the instance doesn't have an int id set for an insertion
            object id = MobileServiceSerializer.GetId(instance, ignoreCase: false, allowDefault: true);
            bool   isStringIdOrDefaultIntId = id is string || MobileServiceSerializer.IsDefaultId(id);

            if (!isStringIdOrDefaultIntId)
            {
                throw new ArgumentException(
                          string.Format(
                              CultureInfo.InvariantCulture,
                              "Cannot insert if the {0} member is already set.",
                              MobileServiceSystemColumns.Id),
                          "instance");
            }

            features = this.AddRequestFeatures(features, parameters);
            string uriString = GetUri(this.TableName, null, parameters);

            return(await this.TransformHttpException(async() =>
            {
                MobileServiceHttpResponse response = await this.MobileServiceClient.HttpClient.RequestAsync(HttpMethod.Post, uriString, this.MobileServiceClient.CurrentUser, instance.ToString(Formatting.None), true, features: this.Features | features);
                return GetJTokenFromResponse(response);
            }));
        }
        /// <summary>
        /// Inserts an <paramref name="instance"/> into the table.
        /// </summary>
        /// <param name="instance">
        /// The instance to insert into the table.
        /// </param>
        /// <param name="parameters">
        /// A dictionary of user-defined parameters and values to include in
        /// the request URI query string.
        /// </param>
        /// <returns>
        /// A task that will complete when the insert finishes.
        /// </returns>
        public async Task <JToken> InsertAsync(JObject instance, IDictionary <string, string> parameters)
        {
            if (instance == null)
            {
                throw new ArgumentNullException("instance");
            }

            // Make sure the instance doesn't have an id set for an insertion
            MobileServiceSerializer serializer = this.MobileServiceClient.Serializer;
            object id = serializer.GetId(instance, true);

            if (!serializer.IsDefaultId(id))
            {
                throw new ArgumentException(
                          string.Format(
                              CultureInfo.InvariantCulture,
                              Resources.MobileServiceTable_InsertWithExistingId,
                              MobileServiceUrlBuilder.IdPropertyName),
                          "instance");
            }

            string response = await this.SendInsertAsync(instance.ToString(), parameters);

            return(response.ParseToJToken());
        }
Пример #10
0
        /// <summary>
        /// Removes system properties from the passed in item
        /// </summary>
        /// <param name="item">
        /// The item returned from the server
        /// </param>
        /// <param name="parameters">
        /// A dictionary of user-defined parameters and values to include in
        /// the request URI query string.
        /// </param>
        /// <param name="version">
        /// Set to the value of the version system property before it is removed.
        /// </param>
        /// <returns>
        /// An item that only contains normal fields and the requested system properties
        /// </returns>
        private JToken RemoveUnrequestedSystemProperties(JToken item, IDictionary <string, string> parameters, string version)
        {
            object id = null;

            if (item == null)
            {
                return(null);
            }

            MobileServiceSerializer.TryGetId(item as JObject, true, out id);
            if (id == null || MobileServiceSerializer.IsIntegerId(id))
            {
                return(item);
            }

            var actualSystemProperties = GetRequestedSystemProperties(parameters);

            if (actualSystemProperties == MobileServiceSystemProperties.All)
            {
                return(item);
            }

            string ignoredVersion = null;
            var    cleanedItem    = MobileServiceSerializer.RemoveSystemProperties(item as JObject, out ignoredVersion, actualSystemProperties);

            if (version != null)
            {
                cleanedItem[MobileServiceSerializer.VersionSystemPropertyString] = GetValueFromEtag(version);
            }

            return(cleanedItem);
        }
        /// <summary>
        /// Initializes a new instance of the MobileServiceTables class.
        /// </summary>
        /// <param name="tableName">
        /// The name of the table.
        /// </param>
        /// <param name="client">
        /// The <see cref="MobileServiceClient"/> associated with this table.
        /// </param>
        public MobileServiceTable(string tableName, MobileServiceClient client)
            : base(tableName, client)
        {
            this.queryProvider    = new MobileServiceTableQueryProvider();
            this.SystemProperties = client.Serializer.GetSystemProperties(typeof(T));
            Type idType = client.Serializer.GetIdPropertyType <T>(throwIfNotFound: false);

            this.hasIntegerId = idType == null || MobileServiceSerializer.IsIntegerId(idType);
        }
Пример #12
0
        /// <summary>
        /// Undeletes an <paramref name="instance"/> from the table.
        /// </summary>
        /// <param name="instance">The instance to undelete from the table.</param>
        /// <param name="parameters">
        /// A dictionary of user-defined parameters and values to include in
        /// the request URI query string.
        /// </param>
        /// <returns>A task that will complete when the undelete finishes.</returns>
        public async Task UndeleteAsync(T instance, IDictionary <string, string> parameters)
        {
            Arguments.IsNotNull(instance, nameof(instance));

            MobileServiceSerializer serializer = this.MobileServiceClient.Serializer;
            JObject value        = serializer.Serialize(instance) as JObject;
            JToken  updatedValue = await TransformHttpException(serializer, () => UndeleteAsync(value, parameters, MobileServiceFeatures.TypedTable));

            serializer.Deserialize(updatedValue, instance);
        }
        /// <summary>
        /// if id is of type string then it strips the system properties and adds version header.
        /// </summary>
        /// <returns>The header collection with if-match header.</returns>
        private Dictionary <string, string> StripSystemPropertiesAndAddVersionHeader(ref JObject instance, ref IDictionary <string, string> parameters, object id)
        {
            string version = null;

            instance = MobileServiceSerializer.RemoveSystemProperties(instance, out version);

            Dictionary <string, string> headers = AddIfMatchHeader(version);

            return(headers);
        }
        /// <summary>
        /// Executes a lookup against a table.
        /// </summary>
        /// <param name="id">
        /// The id of the instance to lookup.
        /// </param>
        /// <param name="parameters">
        /// A dictionary of user-defined parameters and values to include in
        /// the request URI query string.
        /// </param>
        /// <param name="features">
        /// Value indicating which features of the SDK are being used in this call. Useful for telemetry.
        /// </param>
        /// <returns>
        /// A task that will return with a result when the lookup finishes.
        /// </returns>
        internal async Task <JToken> LookupAsync(object id, IDictionary <string, string> parameters, MobileServiceFeatures features)
        {
            MobileServiceSerializer.EnsureValidId(id);

            features = this.AddRequestFeatures(features, parameters);

            string uriString = GetUri(this.TableName, id, parameters);
            MobileServiceHttpResponse response = await this.MobileServiceClient.HttpClient.RequestAsync(HttpMethod.Get, uriString, this.MobileServiceClient.CurrentUser, null, true, features : this.Features | features);

            return(GetJTokenFromResponse(response));
        }
Пример #15
0
        /// <summary>
        /// Executes a lookup against a table.
        /// </summary>
        /// <param name="id">
        /// The id of the instance to lookup.
        /// </param>
        /// <param name="parameters">
        /// A dictionary of user-defined parameters and values to include in
        /// the request URI query string.
        /// </param>
        /// <returns>
        /// A task that will return with a result when the lookup finishes.
        /// </returns>
        public async Task <JToken> LookupAsync(object id, IDictionary <string, string> parameters)
        {
            MobileServiceSerializer.EnsureValidId(id);

            parameters = AddSystemProperties(this.SystemProperties, parameters);

            string uriString = GetUri(this.TableName, id, parameters);
            MobileServiceHttpResponse response = await this.MobileServiceClient.HttpClient.RequestAsync(HttpMethod.Get, uriString, this.MobileServiceClient.CurrentUser, null, true);

            return(GetJTokenFromResponse(response));
        }
Пример #16
0
        /// <summary>
        /// Inserts a new instance into the table.
        /// </summary>
        /// <param name="instance">
        /// The instance to insert.
        /// </param>
        /// <param name="parameters">
        /// A dictionary of user-defined parameters and values to include in
        /// the request URI query string.
        /// </param>
        /// <returns>
        /// A task that will complete when the insertion has finished.
        /// </returns>
        public async Task InsertAsync(T instance, IDictionary <string, string> parameters)
        {
            Arguments.IsNotNull(instance, nameof(instance));

            MobileServiceSerializer serializer = this.MobileServiceClient.Serializer;
            JObject value = serializer.Serialize(instance) as JObject;

            value = MobileServiceSerializer.RemoveSystemProperties(value, out string unused);
            JToken insertedValue = await TransformHttpException(serializer, () => InsertAsync(value, parameters, MobileServiceFeatures.TypedTable));

            serializer.Deserialize(insertedValue, instance);
        }
Пример #17
0
        /// <summary>
        /// Undeletes an <paramref name="instance"/> from the table.
        /// </summary>
        /// <param name="instance">The instance to undelete from the table.</param>
        /// <param name="parameters">
        /// A dictionary of user-defined parameters and values to include in
        /// the request URI query string.
        /// </param>
        /// <returns>A task that will complete when the undelete finishes.</returns>
        public async Task UndeleteAsync(T instance, IDictionary <string, string> parameters)
        {
            if (instance == null)
            {
                throw new ArgumentNullException("instance");
            }

            MobileServiceSerializer serializer = this.MobileServiceClient.Serializer;
            JObject value = serializer.Serialize(instance) as JObject;

            JToken updatedValue = await TransformHttpException(serializer, () => this.UndeleteAsync(value, parameters, MobileServiceFeatures.TypedTable));

            serializer.Deserialize <T>(updatedValue, instance);
        }
Пример #18
0
        /// <summary>
        /// Updates an <paramref name="instance"/> in the table.
        /// </summary>
        /// <param name="instance">
        /// The instance to update in the table.
        /// </param>
        /// <param name="parameters">
        /// A dictionary of user-defined parameters and values to include in
        /// the request URI query string.
        /// </param>
        /// <returns>
        /// A task that will complete when the update finishes.
        /// </returns>
        public async Task <JToken> UpdateAsync(JObject instance, IDictionary <string, string> parameters)
        {
            if (instance == null)
            {
                throw new ArgumentNullException("instance");
            }

            MobileServiceInvalidOperationException error = null;

            object id      = MobileServiceSerializer.GetId(instance);
            string version = null;

            if (!MobileServiceSerializer.IsIntegerId(id))
            {
                instance = RemoveSystemProperties(instance, out version);
            }
            parameters = AddSystemProperties(this.SystemProperties, parameters);

            try
            {
                Dictionary <string, string> headers = null;

                string content   = instance.ToString(Formatting.None);
                string uriString = GetUri(this.TableName, id, parameters);

                if (version != null)
                {
                    headers = new Dictionary <string, string>();
                    headers.Add("If-Match", GetEtagFromValue(version));
                }

                MobileServiceHttpResponse response = await this.MobileServiceClient.HttpClient.RequestAsync(patchHttpMethod, uriString, this.MobileServiceClient.CurrentUser, content, true, headers);

                return(GetJTokenFromResponse(response));
            }
            catch (MobileServiceInvalidOperationException ex)
            {
                if (ex.Response != null &&
                    ex.Response.StatusCode != HttpStatusCode.PreconditionFailed)
                {
                    throw;
                }

                error = ex;
            }

            JToken value = await this.ParseContent(error.Response);

            throw new MobileServicePreconditionFailedException(error, value);
        }
Пример #19
0
        /// <summary>
        /// Deletes an instance from the table.
        /// </summary>
        /// <param name="instance">
        /// The instance to delete.
        /// </param>
        /// <param name="parameters">
        /// A dictionary of user-defined parameters and values to include in
        /// the request URI query string.
        /// </param>
        /// <returns>
        /// A task that will complete when the delete has finished.
        /// </returns>
        public async Task DeleteAsync(T instance, IDictionary <string, string> parameters)
        {
            Arguments.IsNotNull(instance, nameof(instance));

            MobileServiceSerializer serializer = this.MobileServiceClient.Serializer;
            JObject value = serializer.Serialize(instance) as JObject;

            await TransformHttpException(serializer, () => DeleteAsync(value, parameters, MobileServiceFeatures.TypedTable));

            // Clear the instance id since it's no longer associated with that
            // id on the server (note that reflection is goodly enough to turn
            // null into the correct value for us).
            serializer.SetIdToDefault(instance);
        }
Пример #20
0
        /// <summary>
        /// Deletes an <paramref name="instance"/> from the table.
        /// </summary>
        /// <param name="instance">
        /// The instance to delete from the table.
        /// </param>
        /// <param name="parameters">
        /// A dictionary of user-defined parameters and values to include in
        /// the request URI query string.
        /// </param>
        /// <returns>
        /// A task that will complete when the delete finishes.
        /// </returns>
        public async Task <JToken> DeleteAsync(JObject instance, IDictionary <string, string> parameters)
        {
            if (instance == null)
            {
                throw new ArgumentNullException("instance");
            }

            object id = MobileServiceSerializer.GetId(instance);

            parameters = AddSystemProperties(this.SystemProperties, parameters);

            string uriString = GetUri(this.TableName, id, parameters);
            MobileServiceHttpResponse response = await this.MobileServiceClient.HttpClient.RequestAsync(HttpMethod.Delete, uriString, this.MobileServiceClient.CurrentUser, null, false);

            return(GetJTokenFromResponse(response));
        }
        public async Task <U> InvokeApiAsync <T, U>(string apiName, T body, HttpMethod method, IDictionary <string, string> parameters, CancellationToken cancellationToken = default)
        {
            Arguments.IsNotNullOrWhiteSpace(apiName, nameof(apiName));

            MobileServiceSerializer serializer = this.Serializer;
            string content = null;

            if (body != null)
            {
                content = serializer.Serialize(body).ToString();
            }

            string response = await this.InternalInvokeApiAsync(apiName, content, method, parameters, MobileServiceFeatures.TypedApiCall, cancellationToken);

            if (string.IsNullOrEmpty(response))
            {
                return(default);
        /// <summary>
        /// Deletes an instance from the table.
        /// </summary>
        /// <param name="instance">
        /// The instance to delete.
        /// </param>
        /// <param name="parameters">
        /// A dictionary of user-defined parameters and values to include in
        /// the request URI query string.
        /// </param>
        /// <returns>
        /// A task that will complete when the delete has finished.
        /// </returns>
        public async Task DeleteAsync(T instance, IDictionary <string, string> parameters)
        {
            if (instance == null)
            {
                throw new ArgumentNullException("instance");
            }

            MobileServiceSerializer serializer = this.MobileServiceClient.Serializer;
            JObject value = serializer.Serialize(instance) as JObject;

            await this.DeleteAsync(value, parameters);

            // Clear the instance id since it's no longer associated with that
            // id on the server (note that reflection is goodly enough to turn
            // null into the correct value for us).
            serializer.SetIdToDefault(instance);
        }
Пример #23
0
        /// <summary>
        /// Inserts a new instance into the table.
        /// </summary>
        /// <param name="instance">
        /// The instance to insert.
        /// </param>
        /// <param name="parameters">
        /// A dictionary of user-defined parameters and values to include in
        /// the request URI query string.
        /// </param>
        /// <returns>
        /// A task that will complete when the insertion has finished.
        /// </returns>
        public async Task InsertAsync(T instance, IDictionary <string, string> parameters)
        {
            if (instance == null)
            {
                throw new ArgumentNullException("instance");
            }

            MobileServiceSerializer serializer = this.MobileServiceClient.Serializer;
            JObject value = serializer.Serialize(instance) as JObject;

            string unused;

            value = MobileServiceSerializer.RemoveSystemProperties(value, out unused);

            JToken insertedValue = await TransformHttpException(serializer, () => this.InsertAsync(value, parameters, MobileServiceFeatures.TypedTable));

            serializer.Deserialize <T>(insertedValue, instance);
        }
        /// <summary>
        /// Invokes a user-defined custom API of a Windows Azure Mobile Service using the specified HTTP Method.
        /// Additional data can be sent though the HTTP content or the query string.
        /// </summary>
        /// <typeparam name="T">The type of instance sent to the Windows Azure Mobile Service.</typeparam>
        /// <typeparam name="U">The type of instance returned from the Windows Azure Mobile Service.</typeparam>
        /// <param name="apiName">The name of the custom API.</param>
        /// <param name="body">The value to be sent as the HTTP body.</param>
        /// <param name="method">The HTTP method.</param>
        /// <param name="parameters">
        /// A dictionary of user-defined parameters and values to include in the request URI query string.
        /// </param>
        /// <returns>The response content from the custom api invocation.</returns>
        public async Task <U> InvokeApiAsync <T, U>(string apiName, T body, HttpMethod method, IDictionary <string, string> parameters)
        {
            if (string.IsNullOrWhiteSpace(apiName))
            {
                throw new ArgumentNullException("apiName");
            }

            MobileServiceSerializer serializer = this.Serializer;
            string content = null;

            if (body != null)
            {
                content = serializer.Serialize(body);
            }

            string response = await this.InternalInvokeApiAsync(apiName, content, method, parameters);

            return(serializer.Deserialize <U>(response));
        }
        /// <summary>
        /// Inserts a new instance into the table.
        /// </summary>
        /// <param name="instance">
        /// The instance to insert.
        /// </param>
        /// <param name="parameters">
        /// A dictionary of user-defined parameters and values to include in
        /// the request URI query string.
        /// </param>
        /// <returns>
        /// A task that will complete when the insertion has finished.
        /// </returns>
        public async Task InsertAsync(T instance, IDictionary <string, string> parameters)
        {
            if (instance == null)
            {
                throw new ArgumentNullException("instance");
            }

            MobileServiceSerializer serializer = this.MobileServiceClient.Serializer;
            JObject value = serializer.Serialize(instance) as JObject;

            if (!this.hasIntegerId)
            {
                string unused;
                value = RemoveSystemProperties(value, out unused);
            }
            JToken insertedValue = await this.InsertAsync(value, parameters);

            serializer.Deserialize <T>(insertedValue, instance);
        }
        /// <summary>
        /// Deletes an <paramref name="instance"/> from the table.
        /// </summary>
        /// <param name="instance">
        /// The instance to delete from the table.
        /// </param>
        /// <param name="parameters">
        /// A dictionary of user-defined parameters and values to include in
        /// the request URI query string.
        /// </param>
        /// <param name="features">
        /// Value indicating which features of the SDK are being used in this call. Useful for telemetry.
        /// </param>
        /// <returns>
        /// A task that will complete when the delete finishes.
        /// </returns>
        internal async Task <JToken> DeleteAsync(JObject instance, IDictionary <string, string> parameters, MobileServiceFeatures features)
        {
            if (instance == null)
            {
                throw new ArgumentNullException("instance");
            }

            object id = MobileServiceSerializer.GetId(instance);

            features = this.AddRequestFeatures(features, parameters);
            Dictionary <string, string> headers = StripSystemPropertiesAndAddVersionHeader(ref instance, ref parameters, id);
            string uriString = GetUri(this.TableName, id, parameters);

            return(await TransformHttpException(async() =>
            {
                MobileServiceHttpResponse response = await this.MobileServiceClient.HttpClient.RequestAsync(HttpMethod.Delete, uriString, this.MobileServiceClient.CurrentUser, null, false, headers, this.Features | features);
                return GetJTokenFromResponse(response);
            }));
        }
Пример #27
0
        /// <summary>
        /// Creates a collection of <see cref="JsonProperty"/> instances for the members of a given
        /// type.
        /// </summary>
        /// <remarks>
        /// This method is overridden in order to handle the id property of the type. Because multiple
        /// property names ("id" with different casings) are all treated as the id property, we must
        /// ensure that there is one and only one id property for the type. Also, the id property
        /// should be ignored when it is the default or null value and it should always serialize to JSON
        /// with a lowercase 'id' name.
        ///
        /// This method also checks for and applies and system property attributes.
        /// </remarks>
        /// <param name="type">
        /// The type for which to create the collection of <see cref="JsonProperty"/> instances.
        /// </param>
        /// <param name="memberSerialization">
        /// Specifies the member serialization options for the type.
        /// </param>
        /// <returns>
        /// A collection of <see cref="JsonProperty"/> instances for the members of a given
        /// type.
        /// </returns>
        protected override IList <JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization)
        {
            IList <JsonProperty> properties = base.CreateProperties(type, memberSerialization);

            // If this type is for a known table, ensure that it has an id.
            TypeInfo typeInfo = type.GetTypeInfo();

            if (this.tableNameCache.ContainsKey(type) || this.tableNameCache.Keys.Any(t => t.GetTypeInfo().IsAssignableFrom(typeInfo)))
            {
                // Filter out properties that are not read/write
                properties = properties.Where(p => p.Writable).ToList();

                // Find the id property
                JsonProperty idProperty      = DetermineIdProperty(type, properties);
                bool         isIntegerIdType = MobileServiceSerializer.IsIntegerId(idProperty);

                // Create a reverse cache of property to memberInfo to be used locally for validating the type
                Dictionary <JsonProperty, MemberInfo> memberInfoCache = new Dictionary <JsonProperty, MemberInfo>();
                foreach (KeyValuePair <MemberInfo, JsonProperty> pair in jsonPropertyCache)
                {
                    if (pair.Key.DeclaringType.GetTypeInfo().IsAssignableFrom(typeInfo))
                    {
                        memberInfoCache.Add(pair.Value, pair.Key);
                    }
                }

                // Set any needed converters and look for system property attributes
                foreach (JsonProperty property in properties)
                {
                    SetMemberConverters(property);
                    ApplySystemPropertyAttributes(property, memberInfoCache[property], isIntegerIdType);
                }

                // Determine the system properties from the property names
                // and add the system properties to the cache
                if (!isIntegerIdType)
                {
                    AddSystemPropertyCacheEntry(type, properties);
                }
            }

            return(properties);
        }
Пример #28
0
        /// <summary>
        /// Updates an <paramref name="instance"/> in the table.
        /// </summary>
        /// <param name="instance">
        /// The instance to update in the table.
        /// </param>
        /// <param name="parameters">
        /// A dictionary of user-defined parameters and values to include in
        /// the request URI query string.
        /// </param>
        /// <param name="features">
        /// Value indicating which features of the SDK are being used in this call. Useful for telemetry.
        /// </param>
        /// <returns>
        /// A task that will complete when the update finishes.
        /// </returns>
        internal async Task <JToken> UpdateAsync(JObject instance, IDictionary <string, string> parameters, MobileServiceFeatures features)
        {
            if (instance == null)
            {
                throw new ArgumentNullException("instance");
            }

            features = this.AddRequestFeatures(features, parameters);
            object id = MobileServiceSerializer.GetId(instance);
            Dictionary <string, string> headers = StripSystemPropertiesAndAddVersionHeader(ref instance, ref parameters, id);
            string content   = instance.ToString(Formatting.None);
            string uriString = GetUri(this.TableName, id, parameters);

            return(await this.TransformHttpException(async() =>
            {
                MobileServiceHttpResponse response = await this.MobileServiceClient.HttpClient.RequestAsync(patchHttpMethod, uriString, this.MobileServiceClient.CurrentUser, content, true, headers, this.Features | features);
                var result = GetJTokenFromResponse(response);
                return RemoveUnrequestedSystemProperties(result, parameters, response.Etag);
            }));
        }
        /// <summary>
        /// Returns the id of the <paramref name="instance"/>.
        /// </summary>
        /// <param name="instance">
        /// The instance that should have an id.
        /// </param>
        /// <returns>
        /// The id of the instance.
        /// </returns>
        /// <exception cref="ArgumentException">
        /// Thrown if the <paramref name="instance"/> does not have an id.
        /// </exception>
        private object GetIdFromInstance(JObject instance)
        {
            Debug.Assert(instance != null);

            // Get the value of the object (as a primitive JSON type)
            MobileServiceSerializer serializer = this.MobileServiceClient.Serializer;
            object id = serializer.GetId(instance);

            if (serializer.IsDefaultId(id))
            {
                throw new ArgumentException(
                          string.Format(
                              CultureInfo.InvariantCulture,
                              Resources.MobileServiceTable_IdNotFound,
                              MobileServiceUrlBuilder.IdPropertyName),
                          "instance");
            }

            return(id);
        }
Пример #30
0
        /// <summary>
        /// Invokes a user-defined custom API of a Microsoft Azure Mobile Service using the specified HTTP Method.
        /// Additional data can be sent though the HTTP content or the query string.
        /// </summary>
        /// <typeparam name="T">The type of instance sent to the Microsoft Azure Mobile Service.</typeparam>
        /// <typeparam name="U">The type of instance returned from the Microsoft Azure Mobile Service.</typeparam>
        /// <param name="apiName">The name of the custom API.</param>
        /// <param name="body">The value to be sent as the HTTP body.</param>
        /// <param name="method">The HTTP method.</param>
        /// <param name="parameters">
        /// A dictionary of user-defined parameters and values to include in the request URI query string.
        /// </param>
        /// <returns>The response content from the custom api invocation.</returns>
        public async Task <U> InvokeApiAsync <T, U>(string apiName, T body, HttpMethod method, IDictionary <string, string> parameters)
        {
            if (string.IsNullOrWhiteSpace(apiName))
            {
                throw new ArgumentNullException("apiName");
            }

            MobileServiceSerializer serializer = this.Serializer;
            string content = null;

            if (body != null)
            {
                content = serializer.Serialize(body).ToString();
            }

            string response = await this.InternalInvokeApiAsync(apiName, content, method, parameters, MobileServiceFeatures.TypedApiCall);

            if (string.IsNullOrEmpty(response))
            {
                return(default(U));
            }
            return(serializer.Deserialize <U>(JToken.Parse(response)));
        }