Index: Src/GoogleApis/Apis/Requests/ClientServiceRequest.cs =================================================================== --- a/Src/GoogleApis/Apis/Requests/ClientServiceRequest.cs +++ b/Src/GoogleApis/Apis/Requests/ClientServiceRequest.cs @@ -17,10 +17,8 @@ using System; using System.Collections.Generic; using System.IO; -using System.Linq; using System.Net.Http; using System.Net.Http.Headers; -using System.Reflection; using System.Threading; using System.Threading.Tasks; @@ -30,6 +28,7 @@ using Google.Apis.Services; using Google.Apis.Testing; using Google.Apis.Util; +using Google.Apis.Requests.Parameters; namespace Google.Apis.Requests { @@ -40,13 +39,13 @@ /// The type of the response object public abstract class ClientServiceRequest : IClientServiceRequest { - /// The class logger + /// The class logger. private static readonly ILogger Logger = ApplicationContext.Logger.ForType>(); - /// The service on which this request will be executed. + /// The service on which this request will be executed. private readonly IClientService service; - /// Defines whether the E-Tag will be used in a specified way or be ignored. + /// Defines whether the E-Tag will be used in a specified way or be ignored. public ETagAction ETagAction { get; set; } #region IClientServiceRequest Properties @@ -64,7 +63,7 @@ #endregion - /// Creates a new service request. + /// Creates a new service request. protected ClientServiceRequest(IClientService service) { this.service = service; @@ -92,7 +91,7 @@ } catch (AggregateException aex) { - // if an exception was thrown during the tasks, unwrap and throw it + // If an exception was thrown during the tasks, unwrap and throw it. throw aex.InnerException; } catch (Exception ex) @@ -106,13 +105,13 @@ // TODO(peleyal): should we copy the stream, and dispose the response? try { - // sync call + // Sync call. var response = ExecuteUnparsed(CancellationToken.None).Result; return response.Content.ReadAsStreamAsync().Result; } catch (AggregateException aex) { - // if an exception was thrown during the tasks, unwrap and throw it + // If an exception was thrown during the tasks, unwrap and throw it. throw aex.InnerException; } catch (Exception ex) @@ -151,7 +150,7 @@ #region Helpers - /// Sync executes the request without parsing the result. + /// Sync executes the request without parsing the result. private async Task ExecuteUnparsed(CancellationToken cancellationToken) { using (var request = CreateRequest()) @@ -160,12 +159,11 @@ } } - /// Async executes the request without parsing the result. + /// Async executes the request without parsing the result. private Task ExecuteAsyncUnparsed(CancellationToken cancellationToken) { // TODO(peleyal): remove the creation of a new Task (it's not necessary). // It should also be removed from ResumableMediaUpload and MediaDownloader! - // create a new task completion source and return its task. In additional task we actually send the request // using ExecuteUnparsed and setting the result or the exception on the completion source TaskCompletionSource tcs = new TaskCompletionSource(); @@ -178,14 +176,14 @@ } catch (Exception ex) { - // exception was thrown - it must be set on the task completion source + // Exception was thrown - it must be set on the task completion source. tcs.SetException(ex); } }).ConfigureAwait(false); return tcs.Task; } - /// Parses the response and deserialize the content into the requested response object. + /// Parses the response and deserialize the content into the requested response object. private async Task ParseResponse(HttpResponseMessage response) { if (response.IsSuccessStatusCode) @@ -204,7 +202,7 @@ /// Creates the which is used to generate a request. /// /// - /// A new builder instance which contains the Http method and the right Uri with its path and query parameters. + /// A new builder instance which contains the HTTP method and the right Uri with its path and query parameters. /// private RequestBuilder CreateBuilder() { @@ -215,19 +213,20 @@ Method = HttpMethod, }; - // init parameters + // Init parameters. builder.AddParameter(RequestParameterType.Query, "key", service.ApiKey); - AddParameters(builder, ParameterCollection.FromDictionary(CreateParameterDictionary())); + var parameters = ParameterUtils.CreateParameterDictionary(this); + AddParameters(builder, ParameterCollection.FromDictionary(parameters)); return builder; } - /// Generates the right Url for this request. + /// Generates the right URL for this request. protected string GenerateRequestUri() { return CreateBuilder().BuildUri().ToString(); } - /// Creates an Http request message with all class parameters, developer-key, ETag, etc. + /// Creates a HTTP request message with all class parameters, developer-key, ETag, etc. [VisibleForTestOnly] internal HttpRequestMessage CreateRequest() { @@ -250,7 +249,7 @@ #region ETag - /// + /// /// Adds the right ETag action (e.g. If-Match) header to the given HTTP request if the body contains ETag. /// private void AddETag(HttpRequestMessage request) @@ -271,9 +270,7 @@ } } - /// - /// Returns the default ETagAction for a specific http verb. - /// + /// Returns the default ETagAction for a specific HTTP verb. [VisibleForTestOnly] internal static ETagAction GetDefaultETagAction(string httpMethod) { @@ -299,7 +296,7 @@ #region Parameters - /// Adds path and query parameters to the given requestBuilder. + /// Adds path and query parameters to the given requestBuilder. private void AddParameters(RequestBuilder requestBuilder, ParameterCollection inputParameters) { foreach (var parameter in inputParameters) @@ -343,7 +340,7 @@ } } - // check if there is a required parameter which wasn't set + // Check if there is a required parameter which wasn't set. foreach (var parameter in RequestParameters.Values) { if (parameter.IsRequired && !inputParameters.ContainsKey(parameter.Name)) @@ -354,42 +351,6 @@ } } - /// - /// Creates a parameter dictionary by using reflection to look at all properties marked with a KeyAttribute. - /// - [VisibleForTestOnly] - internal IDictionary CreateParameterDictionary() - { - var dict = new Dictionary(); - - // Use reflection to build the parameter dictionary. - foreach (PropertyInfo property in GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public)) - { - // Retrieve the attribute. - RequestParameterAttribute requestParameterAttribute = - property.GetCustomAttributes(typeof(RequestParameterAttribute), false).FirstOrDefault() as - RequestParameterAttribute; - if (requestParameterAttribute == null) - { - continue; - } - - // Get the discovery name of this parameter by looking at the attribute, or taking a lower-case - // variant of the property name if no special name was set. - string name = requestParameterAttribute.Name ?? property.Name.ToLower(); - - // Set the value in the dictionary. - var propertyType = property.PropertyType; - var value = property.GetValue(this, null); - if (propertyType.IsValueType || value != null) - { - dict.Add(name, value); - } - } - - return dict; - } - #endregion } }