Пример #1
0
        /// <summary> Converts SDK request object into HttpRequestMessage.</summary>
        /// <param name="uri">The uri of this http request.</param>
        /// <param name="method">The method of this http request.</param>
        /// <param name="request">The SDK object for this request.</param>
        /// <returns>An HttpRequestMessage that can be sent by HttpClient.</returns>
        public static HttpRequestMessage ToHttpRequestMessage <T>(Uri uri, HttpMethod method, T request) where T : IOciRequest
        {
            // Update properties of requests if needed

            var requestMessage = new HttpRequestMessage();

            requestMessage.Method = method;
            var updatedUri = uri.AbsoluteUri;
            // Build queries string.
            var queries = new Dictionary <string, string>();

            PropertyInfo[] props = typeof(T).GetProperties();
            foreach (var prop in props)
            {
                if (prop.GetValue(request) == null)
                {
                    continue;
                }
                object[] attrs = prop.GetCustomAttributes(false);
                foreach (var attr in attrs)
                {
                    HttpConverterAttribute httpRequestAttr = attr as HttpConverterAttribute;
                    if (httpRequestAttr != null)
                    {
                        if (httpRequestAttr.Target == TargetEnum.Query)
                        {
                            logger.Debug($"Adding query {httpRequestAttr.Name}: {HttpUtils.EncodeQueryParam(prop.GetValue(request))}");
                            queries.Add(httpRequestAttr.Name, HttpUtils.EncodeQueryParam(prop.GetValue(request)));
                        }
                        else if (httpRequestAttr.Target == TargetEnum.Header)
                        {
                            var propertyType = prop.PropertyType;
                            // Special handling of Dictionary type in header since the Dictionary contents are returned as individual header entries.
                            if (propertyType.IsGenericType && propertyType.GetGenericTypeDefinition() == typeof(Dictionary <,>))
                            {
                                foreach (KeyValuePair <string, string> pair in prop.GetValue(request) as IDictionary <string, string> )
                                {
                                    requestMessage.Headers.TryAddWithoutValidation(pair.Key, pair.Value);
                                }
                            }
                            else
                            {
                                logger.Debug($"Adding header {httpRequestAttr.Name}: {prop.GetValue(request)}");
                                // To avoid validating header name formatting (.Net HttpClient has some strict validation rules and not all OCI service headers satisfy them.),
                                // call TryAddWithoutValidation instead of Add.
                                requestMessage.Headers.TryAddWithoutValidation(httpRequestAttr.Name, HeaderUtils.FromValue(prop.GetValue(request)));
                            }
                        }
                        else if (httpRequestAttr.Target == TargetEnum.Body)
                        {
                            logger.Debug($"Adding content from property {prop.Name}");
                            requestMessage.Content = ContentHelper.CreateHttpContent(prop.GetValue(request));
                        }
                        else if (httpRequestAttr.Target == TargetEnum.Path)
                        {
                            logger.Debug($"Adding path parameter {httpRequestAttr.Name}: {prop.GetValue(request)}");
                            updatedUri = updatedUri.Replace(Uri.EscapeUriString($"{{{httpRequestAttr.Name}}}"), HeaderUtils.FromValue(prop.GetValue(request)));
                        }
                    }
                }
            }
            var uriBuilder = new UriBuilder(updatedUri);

            uriBuilder.Query          = HttpUtils.BuildQueryString(queries);
            requestMessage.RequestUri = uriBuilder.Uri;
            return(requestMessage);
        }
Пример #2
0
        /// <summary>Converts HttpResponseMessage into SDK response object.</summary>
        /// <param name="responseMessage">An HttpResponseMessage object</param>
        /// <returns>A SDK response object.</returns>
        public static T FromHttpResponseMessage <T>(HttpResponseMessage responseMessage) where T : IOciResponse, new()
        {
            var response = new T();

            PropertyInfo[] props = typeof(T).GetProperties();
            foreach (var prop in props)
            {
                object[] attrs = prop.GetCustomAttributes(false);
                foreach (var attr in attrs)
                {
                    HttpConverterAttribute httpResponseAttr = attr as HttpConverterAttribute;
                    if (httpResponseAttr == null)
                    {
                        continue;
                    }
                    if (httpResponseAttr.Target == TargetEnum.Header)
                    {
                        var propertyType = prop.PropertyType;
                        // Special handling of Dictionary type in header since the Dictionary contents are returned as individual header entries.
                        if (propertyType.IsGenericType && propertyType.GetGenericTypeDefinition() == typeof(Dictionary <,>))
                        {
                            var value  = new Dictionary <string, string>();
                            var prefix = httpResponseAttr.Name;
                            foreach (var header in responseMessage.Headers)
                            {
                                if (header.Key.StartsWith(prefix))
                                {
                                    // Remove the prefix and add header to dictionary.
                                    value.Add(header.Key.Substring(prefix.Length), header.Value.FirstOrDefault());
                                }
                            }
                            foreach (var header in responseMessage.Content.Headers)
                            {
                                if (header.Key.StartsWith(prefix))
                                {
                                    // Remove the prefix and add header to dictionary.
                                    value.Add(header.Key.Substring(prefix.Length), header.Value.FirstOrDefault());
                                }
                            }
                            if (value.Count > 0)
                            {
                                prop.SetValue(response, value);
                            }
                        }
                        else
                        {
                            if (responseMessage.Headers.TryGetValues(httpResponseAttr.Name, out var headerValues))
                            {
                                logger.Debug($"Setting property value from header {httpResponseAttr.Name}");
                                prop.SetValue(response, HeaderUtils.ToValue(headerValues.FirstOrDefault(), prop.PropertyType));
                            }
                            if (responseMessage.Content.Headers.TryGetValues(httpResponseAttr.Name, out var contentHeaderValues))
                            {
                                logger.Debug($"Setting property value from content header {httpResponseAttr.Name}");
                                prop.SetValue(response, HeaderUtils.ToValue(contentHeaderValues.FirstOrDefault(), prop.PropertyType));
                            }
                        }
                    }
                    else if (httpResponseAttr.Target == TargetEnum.Body)
                    {
                        GenericInvokerParameters genericInvokerParameters = new GenericInvokerParameters
                        {
                            InvokeType      = prop.PropertyType,
                            ResponseMessage = responseMessage
                        };
                        var responseEntity = GenericHelper.InvokeGenericMethod(genericInvokerParameters);
                        prop.SetValue(response, responseEntity);
                    }
                }
            }
            return(response);
        }