/// <summary>
            /// Adds a header for features used in this request. Used for telemetry.
            /// </summary>
            /// <param name="requestHeaders">
            /// Additional request headers to include with the request.
            /// </param>
            /// <param name="features">
            /// Value indicating which features of the SDK are being used in this call.
            /// </param>
            /// <returns>The list of headers to send in this request.</returns>
            public static IDictionary<string, string> AddFeaturesHeader(IDictionary<string, string> requestHeaders, MobileServiceFeatures features)
            {
                if (features != MobileServiceFeatures.None)
                {
                    if (requestHeaders == null || !requestHeaders.ContainsKey(ZumoFeaturesHeader))
                    {
                        requestHeaders = new Dictionary<string, string>(requestHeaders ?? new Dictionary<string, string>());
                        requestHeaders.Add(ZumoFeaturesHeader, FeaturesToString(features));
                    }
                }

                return requestHeaders;
            }
Exemple #2
0
        /// <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,
                              Resources.MobileServiceTable_InsertWithExistingId,
                              MobileServiceSerializer.IdPropertyName),
                          "instance");
            }

            features   = AddQueryParametersFeature(features, parameters);
            parameters = AddSystemProperties(this.SystemProperties, 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: features);
                var result = GetJTokenFromResponse(response);
                return RemoveUnrequestedSystemProperties(result, parameters, response.Etag);
            }));
        }
        /// <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>
 /// Makes an HTTP request that includes the standard Mobile Services
 /// headers. It will use an HttpClient with user-defined http handlers.
 /// </summary>
 /// <param name="method">
 /// The HTTP method used to request the resource.
 /// </param>
 /// <param name="uriPathAndQuery">
 /// The URI of the resource to request (relative to the Mobile Services
 /// runtime).
 /// </param>
 /// <param name="user">
 /// The object representing the user on behalf of whom the request will be sent.
 /// </param>
 /// <param name="content">
 /// Optional content to send to the resource.
 /// </param>
 /// <param name="ensureResponseContent">
 /// Optional parameter to indicate if the response should include content.
 /// </param>
 /// <param name="requestHeaders">
 /// Additional request headers to include with the request.
 /// </param>
 /// <param name="features">
 /// Value indicating which features of the SDK are being used in this call. Useful for telemetry.
 /// </param>
 /// <returns>
 /// The response.
 /// </returns>
 public Task<MobileServiceHttpResponse> RequestAsync(HttpMethod method,
                                                      string uriPathAndQuery,
                                                      MobileServiceUser user,
                                                      string content = null,
                                                      bool ensureResponseContent = true,
                                                      IDictionary<string, string> requestHeaders = null,
                                                      MobileServiceFeatures features = MobileServiceFeatures.None)
 {
     requestHeaders = FeaturesHelper.AddFeaturesHeader(requestHeaders, features);
     return this.RequestAsync(true, method, uriPathAndQuery, user, content, ensureResponseContent, requestHeaders);
 }
        /// <summary>
        /// Adds, if applicable, the <see cref="MobileServiceFeatures.AdditionalQueryParameters"/> value to the
        /// existing list of features used in the current operation.
        /// </summary>
        /// <param name="existingFeatures">The features from the SDK being used for the current operation.</param>
        /// <param name="parameters">
        /// A dictionary of user-defined parameters and values to include in
        /// the request URI query string.
        /// </param>
        /// <returns>The features used in the current operation.</returns>
        private static MobileServiceFeatures AddQueryParametersFeature(MobileServiceFeatures existingFeatures, IDictionary<string, string> parameters)
        {
            if (parameters != null && parameters.Count > 0)
            {
                existingFeatures |= MobileServiceFeatures.AdditionalQueryParameters;
            }

            return existingFeatures;
        }
        /// <summary>
        /// Executes a query against the table.
        /// </summary>
        /// <param name="query">
        /// A query to execute.
        /// </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 results when the query finishes.
        /// </returns>
        internal virtual async Task <QueryResult> ReadAsync(string query, IDictionary <string, string> parameters, MobileServiceFeatures features)
        {
            features = this.AddRequestFeatures(features, parameters);

            string uriPath;
            Uri    uri;
            bool   absolute;

            if (HttpUtility.TryParseQueryUri(this.MobileServiceClient.MobileAppUri, query, out uri, out absolute))
            {
                if (absolute)
                {
                    features |= MobileServiceFeatures.ReadWithLinkHeader;
                }
                uriPath = HttpUtility.GetUriWithoutQuery(uri);
                query   = uri.Query;
            }
            else
            {
                uriPath = MobileServiceUrlBuilder.CombinePaths(TableRouteSeparatorName, this.TableName);
            }

            string parametersString = MobileServiceUrlBuilder.GetQueryString(parameters);

            // Concatenate the query and the user-defined query string parameters
            if (!string.IsNullOrEmpty(parametersString))
            {
                if (!string.IsNullOrEmpty(query))
                {
                    query += '&' + parametersString;
                }
                else
                {
                    query = parametersString;
                }
            }

            string uriString = MobileServiceUrlBuilder.CombinePathAndQuery(uriPath, query);

            return(await ReadAsync(uriString, features));
        }
Exemple #7
0
            /// <summary>
            /// Adds a header for features used in this request. Used for telemetry.
            /// </summary>
            /// <param name="requestHeaders">
            /// Additional request headers to include with the request.
            /// </param>
            /// <param name="features">
            /// Value indicating which features of the SDK are being used in this call.
            /// </param>
            /// <returns>The list of headers to send in this request.</returns>
            public static IDictionary <string, string> AddFeaturesHeader(IDictionary <string, string> requestHeaders, MobileServiceFeatures features)
            {
                if (features != MobileServiceFeatures.None)
                {
                    if (requestHeaders == null || !requestHeaders.ContainsKey(ZumoFeaturesHeader))
                    {
                        requestHeaders = new Dictionary <string, string>(requestHeaders ?? new Dictionary <string, string>());
                        requestHeaders.Add(ZumoFeaturesHeader, FeaturesToString(features));
                    }
                }

                return(requestHeaders);
            }
        /// <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 = AddQueryParametersFeature(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, features);
                var result = GetJTokenFromResponse(response);
                return RemoveUnrequestedSystemProperties(result, parameters, response.Etag);
            });
        }
        /// <summary>
        /// Makes an HTTP request that includes the standard Mobile Services
        /// headers. It will use an HttpClient with user-defined http handlers.
        /// </summary>
        /// <param name="method">
        /// The HTTP method used to request the resource.
        /// </param>
        /// <param name="uriPathAndQuery">
        /// The URI of the resource to request (relative to the Mobile Services
        /// runtime).
        /// </param>
        /// <param name="user">
        /// The object representing the user on behalf of whom the request will be sent.
        /// </param>
        /// <param name="content">
        /// Content to send to the resource.
        /// </param>
        /// <param name="requestHeaders">
        /// Additional request headers to include with the request.
        /// </param>
        /// <param name="features">
        /// Value indicating which features of the SDK are being used in this call. Useful for telemetry.
        /// </param>
        /// <returns>
        /// An <see cref="HttpResponseMessage"/>.
        /// </returns>
        public async Task <HttpResponseMessage> RequestAsync(HttpMethod method, string uriPathAndQuery, MobileServiceUser user, HttpContent content, IDictionary <string, string> requestHeaders, MobileServiceFeatures features = MobileServiceFeatures.None)
        {
            Debug.Assert(method != null);
            Debug.Assert(!string.IsNullOrEmpty(uriPathAndQuery));

            requestHeaders = FeaturesHelper.AddFeaturesHeader(requestHeaders, features);
            // Create the request
            HttpRequestMessage request = this.CreateHttpRequestMessage(method, uriPathAndQuery, requestHeaders, content, user);

            // Get the response
            HttpResponseMessage response = await this.SendRequestAsync(httpClient, request, ensureResponseContent : false);

            return(response);
        }
Exemple #10
0
        /// <summary>
        /// Performs a web request and includes the standard Mobile Services
        /// headers. It will use an HttpClient without any http handlers.
        /// </summary>
        /// <param name="method">
        /// The HTTP method used to request the resource.
        /// </param>
        /// <param name="uriPathAndQuery">
        /// The URI of the resource to request (relative to the Mobile Services
        /// runtime).
        /// </param>
        /// <param name="user">
        /// The object representing the user on behalf of whom the request will be sent.
        /// </param>
        /// <param name="content">
        /// Optional content to send to the resource.
        /// </param>
        /// <param name="features">
        /// Optional MobileServiceFeatures used for telemetry purpose.
        /// </param>>
        /// <returns>
        /// The content of the response as a string.
        /// </returns>
        public async Task <string> RequestWithoutHandlersAsync(HttpMethod method, string uriPathAndQuery, MobileServiceUser user, string content = null, MobileServiceFeatures features = MobileServiceFeatures.None)
        {
            IDictionary <string, string> requestHeaders = FeaturesHelper.AddFeaturesHeader(requestHeaders: null, features: features);
            MobileServiceHttpResponse    response       = await this.RequestAsync(false, method, uriPathAndQuery, user, content, false, requestHeaders);

            return(response.Content);
        }
        protected async Task<JToken> UndeleteAsync(JObject instance, IDictionary<string, string> parameters, MobileServiceFeatures features)
        {
            if (instance == null)
            {
                throw new ArgumentNullException("instance");
            }

            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(HttpMethod.Post, uriString, this.MobileServiceClient.CurrentUser, null, true, headers, 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>
        /// <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>
 /// Performs a web request and includes the standard Mobile Services
 /// headers. It will use an HttpClient without any http handlers.
 /// </summary>
 /// <param name="method">
 /// The HTTP method used to request the resource.
 /// </param>
 /// <param name="uriPathAndQuery">
 /// The URI of the resource to request (relative to the Mobile Services
 /// runtime).
 /// </param>
 /// <param name="user">
 /// The object representing the user on behalf of whom the request will be sent.
 /// </param>
 /// <param name="content">
 /// Optional content to send to the resource.
 /// </param>
 /// <param name="features">
 /// Optional MobileServiceFeatures used for telemetry purpose.
 /// </param>>
 /// <returns>
 /// The content of the response as a string.
 /// </returns>
 public async Task<string> RequestWithoutHandlersAsync(HttpMethod method, string uriPathAndQuery, MobileServiceUser user, string content = null, MobileServiceFeatures features = MobileServiceFeatures.None)
 {
     IDictionary<string, string> requestHeaders = FeaturesHelper.AddFeaturesHeader(requestHeaders: null, features: features);
     MobileServiceHttpResponse response = await this.RequestAsync(false, method, uriPathAndQuery, user, content, false, requestHeaders);
     return response.Content;
 }
        private async Task<QueryResult> ReadAsync(string uriString, MobileServiceFeatures features)
        {
            MobileServiceHttpResponse response = await this.MobileServiceClient.HttpClient.RequestAsync(HttpMethod.Get, uriString, this.MobileServiceClient.CurrentUser, null, true, features: features);

            return QueryResult.Parse(response, this.MobileServiceClient.SerializerSettings, validate: false);
        }
        /// <summary>
        /// Executes a query against the table.
        /// </summary>
        /// <param name="query">
        /// A query to execute.
        /// </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 results when the query finishes.
        /// </returns>
        internal virtual async Task<QueryResult> ReadAsync(string query, IDictionary<string, string> parameters, MobileServiceFeatures features)
        {
            features = this.AddRequestFeatures(features, parameters);
            parameters = AddSystemProperties(this.SystemProperties, parameters);

            string uriPath;
            Uri uri;
            bool absolute;
            if (HttpUtility.TryParseQueryUri(this.MobileServiceClient.ApplicationUri, query, out uri, out absolute))
            {
                if (absolute)
                {
                    features |= MobileServiceFeatures.ReadWithLinkHeader;
                }
                uriPath = HttpUtility.GetUriWithoutQuery(uri);
                query = uri.Query;
            }
            else
            {
                uriPath = MobileServiceUrlBuilder.CombinePaths(TableRouteSeparatorName, this.TableName);
            }

            string parametersString = MobileServiceUrlBuilder.GetQueryString(parameters);

            // Concatenate the query and the user-defined query string parameters
            if (!string.IsNullOrEmpty(parametersString))
            {
                if (!string.IsNullOrEmpty(query))
                {
                    query += '&' + parametersString;
                }
                else
                {
                    query = parametersString;
                }
            }

            string uriString = MobileServiceUrlBuilder.CombinePathAndQuery(uriPath, query);

            return await ReadAsync(uriString, features);
        }
        /// <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,
                            Resources.MobileServiceTable_InsertWithExistingId,
                            MobileServiceSerializer.IdPropertyName),
                            "instance");
            }

            features = AddQueryParametersFeature(features, parameters);
            parameters = AddSystemProperties(this.SystemProperties, 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: features);
                var result = GetJTokenFromResponse(response);
                return RemoveUnrequestedSystemProperties(result, parameters, response.Etag);
            });
        }
        /// <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>
        /// 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 = AddQueryParametersFeature(features, parameters);
            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, features: features);
            return GetJTokenFromResponse(response);
        }
        /// <summary>
        /// Adds, if applicable, the <see cref="MobileServiceFeatures.AdditionalQueryParameters"/> value to the
        /// existing list of features used in the current operation, as well as any features set for the
        /// entire table.
        /// </summary>
        /// <param name="existingFeatures">The features from the SDK being used for the current operation.</param>
        /// <param name="parameters">
        /// A dictionary of user-defined parameters and values to include in
        /// the request URI query string.
        /// </param>
        /// <returns>The features used in the current operation.</returns>
        private MobileServiceFeatures AddRequestFeatures(MobileServiceFeatures existingFeatures, IDictionary<string, string> parameters)
        {
            if (parameters != null && parameters.Count > 0)
            {
                existingFeatures |= MobileServiceFeatures.AdditionalQueryParameters;
            }

            existingFeatures |= this.Features;

            return existingFeatures;
        }
Exemple #20
0
        /// <summary>
        /// Invokes a user-defined custom API of a Microsoft Azure Mobile Service.
        /// </summary>
        /// <param name="apiName">The name of the custom API.</param>
        /// <param name="content">The HTTP content, as a string, in json format.</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>
        /// <param name="features">
        /// Value indicating which features of the SDK are being used in this call. Useful for telemetry.
        /// </param>
        /// <param name="cancellationToken">The <see cref="System.Threading.CancellationToken"/> token to observe</param>
        /// <returns>The response content from the custom api invocation.</returns>
        private async Task <string> InternalInvokeApiAsync(string apiName, string content, HttpMethod method, IDictionary <string, string> parameters, MobileServiceFeatures features, CancellationToken cancellationToken = default(CancellationToken))
        {
            method = method ?? defaultHttpMethod;
            if (parameters != null && parameters.Count > 0)
            {
                features |= MobileServiceFeatures.AdditionalQueryParameters;
            }

            MobileServiceHttpResponse response = await this.HttpClient.RequestAsync(method, CreateAPIUriString(apiName, parameters), this.CurrentUser, content, false, features : features, cancellationToken : cancellationToken);

            return(response.Content);
        }
        /// <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);
                var result = GetJTokenFromResponse(response);
                return RemoveUnrequestedSystemProperties(result, parameters, response.Etag);
            }));
        }
        private async Task <QueryResult> ReadAsync(string uriString, MobileServiceFeatures features)
        {
            MobileServiceHttpResponse response = await this.MobileServiceClient.HttpClient.RequestAsync(HttpMethod.Get, uriString, this.MobileServiceClient.CurrentUser, null, true, features : this.Features | features);

            return(QueryResult.Parse(response, this.MobileServiceClient.SerializerSettings, validate: false));
        }
        /// <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);
            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, features : this.Features | features);

            return(GetJTokenFromResponse(response));
        }
        /// <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);
                return GetJTokenFromResponse(response);
            }));
        }
        /// <summary>
        /// Executes a query against the table.
        /// </summary>
        /// <param name="query">
        /// A query to execute.
        /// </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 results when the query finishes.
        /// </returns>
        internal virtual async Task <QueryResult> ReadAsync(string query, IDictionary <string, string> parameters, MobileServiceFeatures features)
        {
            features = AddRequestFeatures(features, parameters);

            string uriPath;

            if (HttpUtility.TryParseQueryUri(this.MobileServiceClient.MobileAppUri, query, out Uri uri, out bool absolute))
            {
                if (absolute)
                {
                    features |= MobileServiceFeatures.ReadWithLinkHeader;
                }
                uriPath = HttpUtility.GetUriWithoutQuery(uri);
                query   = uri.Query;
            }
        /// <summary>
        /// Makes an HTTP request that includes the standard Mobile Services
        /// headers. It will use an HttpClient with user-defined http handlers.
        /// </summary>
        /// <param name="method">
        /// The HTTP method used to request the resource.
        /// </param>
        /// <param name="uriPathAndQuery">
        /// The URI of the resource to request (relative to the Mobile Services
        /// runtime).
        /// </param>
        /// <param name="user">
        /// The object representing the user on behalf of whom the request will be sent.
        /// </param>
        /// <param name="content">
        /// Content to send to the resource.
        /// </param>
        /// <param name="requestHeaders">
        /// Additional request headers to include with the request.
        /// </param>
        /// <param name="features">
        /// Value indicating which features of the SDK are being used in this call. Useful for telemetry.
        /// </param>
        /// <returns>
        /// An <see cref="HttpResponseMessage"/>.
        /// </returns>
        public async Task<HttpResponseMessage> RequestAsync(HttpMethod method, string uriPathAndQuery, MobileServiceUser user, HttpContent content, IDictionary<string, string> requestHeaders, MobileServiceFeatures features = MobileServiceFeatures.None)
        {
            Debug.Assert(method != null);
            Debug.Assert(!string.IsNullOrEmpty(uriPathAndQuery));

            requestHeaders = FeaturesHelper.AddFeaturesHeader(requestHeaders, features);
            // Create the request
            HttpRequestMessage request = this.CreateHttpRequestMessage(method, uriPathAndQuery, requestHeaders, content, user);

            // Get the response
            HttpResponseMessage response = await this.SendRequestAsync(httpClient, request, ensureResponseContent: false);

            return response;
        }
        /// <summary>
        /// Executes a query against the table.
        /// </summary>
        /// <param name="query">
        /// A query to execute.
        /// </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 results when the query finishes.
        /// </returns>
        internal virtual async Task<QueryResult> ReadAsync(string query, IDictionary<string, string> parameters, MobileServiceFeatures features)
        {
            parameters = AddSystemProperties(this.SystemProperties, parameters);

            string uriPath;
            Uri uri;
            if (Uri.TryCreate(query, UriKind.Absolute, out uri))
            {
                features |= MobileServiceFeatures.ReadWithLinkHeader;
                uriPath = uri.GetComponents(UriComponents.Scheme | UriComponents.UserInfo | UriComponents.Host | UriComponents.Port | UriComponents.Path, UriFormat.UriEscaped);
                query = uri.Query;
            }
            else
            {
                uriPath = MobileServiceUrlBuilder.CombinePaths(TableRouteSeparatorName, this.TableName);
            }

            string parametersString = MobileServiceUrlBuilder.GetQueryString(parameters);

            // Concatenate the query and the user-defined query string parameters
            if (!string.IsNullOrEmpty(parametersString))
            {
                if (!string.IsNullOrEmpty(query))
                {
                    query += '&' + parametersString;
                }
                else
                {
                    query = parametersString;
                }
            }

            string uriString = MobileServiceUrlBuilder.CombinePathAndQuery(uriPath, query);
            features = AddQueryParametersFeature(features, parameters);

            return await ReadAsync(uriString, features);
        }
 /// <summary>
 /// Returns the value to be used in the HTTP header corresponding to the given features.
 /// </summary>
 /// <param name="features">The features to be sent as telemetry to the service.</param>
 /// <returns>The value of the HTTP header to be sent to the service.</returns>
 private static string FeaturesToString(MobileServiceFeatures features)
 {
     return string.Join(",",
         AllTelemetryFeatures
             .Where(t => (features & t.Item1) == t.Item1)
             .Select(t => t.Item2));
 }
Exemple #29
0
        /// <summary>
        /// Executes a query against the table.
        /// </summary>
        /// <param name="query">
        /// A query to execute.
        /// </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 results when the query finishes.
        /// </returns>
        internal virtual async Task <QueryResult> ReadAsync(string query, IDictionary <string, string> parameters, MobileServiceFeatures features)
        {
            parameters = AddSystemProperties(this.SystemProperties, parameters);

            string uriPath;
            Uri    uri;

            if (Uri.TryCreate(query, UriKind.Absolute, out uri))
            {
                features |= MobileServiceFeatures.ReadWithLinkHeader;
                uriPath   = uri.GetComponents(UriComponents.Scheme | UriComponents.UserInfo | UriComponents.Host | UriComponents.Port | UriComponents.Path, UriFormat.UriEscaped);
                query     = uri.Query;
            }
            else
            {
                uriPath = MobileServiceUrlBuilder.CombinePaths(TableRouteSeparatorName, this.TableName);
            }

            string parametersString = MobileServiceUrlBuilder.GetQueryString(parameters);

            // Concatenate the query and the user-defined query string parameters
            if (!string.IsNullOrEmpty(parametersString))
            {
                if (!string.IsNullOrEmpty(query))
                {
                    query += '&' + parametersString;
                }
                else
                {
                    query = parametersString;
                }
            }

            string uriString = MobileServiceUrlBuilder.CombinePathAndQuery(uriPath, query);

            features = AddQueryParametersFeature(features, parameters);

            return(await ReadAsync(uriString, features));
        }