예제 #1
0
        /// <summary>
        /// Adds form data file to request
        /// </summary>
        /// <param name="request">The SolidHttpRequest</param>
        /// <param name="name">The form name of the file</param>
        /// <param name="content">The file ByteArrayContent</param>
        /// <param name="fileName">The file name</param>
        /// <returns>SolidHttpRequest</returns>
        public static SolidHttpRequest WithFormDataFile(this SolidHttpRequest request, string name, ByteArrayContent content, string fileName)
        {
            var form = request.GetMultipartFormDataContent();

            form.Add(content, name, fileName);
            return(request);
        }
예제 #2
0
        private static SolidHttpRequest WithMultipartContent(this SolidHttpRequest request, Func <MultipartContent> create)
        {
            var content   = request.BaseRequest.Content;
            var multipart = content as MultipartContent;
            var contents  = Enumerable.Empty <HttpContent>();

            if (multipart != null)
            {
                contents = multipart;
            }
            else if (content != null)
            {
                contents = new[] { content }
            }
            ;

            var m = create();

            // TODO: Make sure the headers aren't gonna be a problem
            foreach (var c in contents)
            {
                m.Add(c);
            }
            request.BaseRequest.Content = m;
            return(request);
        }
    }
예제 #3
0
        /// <summary>
        /// Deserializes the response content as the specified type using the specified settings
        /// </summary>
        /// <typeparam name="T">The type of response body</typeparam>
        /// <param name="request">The SolidHttpRequest</param>
        /// <param name="settings">The specified JsonSerializerSettings</param>
        /// <returns>Task of type T</returns>
        public static async Task <T> As <T>(this SolidHttpRequest request, JsonSerializerSettings settings)
        {
            var factory     = new JsonResponseDeserializerFactory(settings);
            var deserialize = factory.CreateDeserializer <T>();

            return(await request.As <T>(deserialize));
        }
예제 #4
0
        /// <summary>
        /// Adds StringContent containing a json string of the supplied body object
        /// </summary>
        /// <typeparam name="T">The type of body</typeparam>
        /// <param name="request">The SolidHttpRequest</param>
        /// <param name="body">The request body object</param>
        /// <param name="settings">(Optional) JsonSerializerSettings to use to serialize the body object</param>
        /// <returns>SolidHttpRequest</returns>
        public static SolidHttpRequest WithJsonContent <T>(this SolidHttpRequest request, T body, JsonSerializerSettings settings = null)
        {
            var json    = JsonConvert.SerializeObject(body, settings ?? request.GetJsonSerializerSettings());
            var content = new StringContent(json, Encoding.UTF8, "application/json");

            return(request.WithContent(content));
        }
예제 #5
0
        /// <summary>
        /// Returns the content as a GzipStream, caller is responsable for desposing the stream
        /// </summary>
        /// <param name="request"></param>
        /// <param name="level"></param>
        /// <returns></returns>
        public static async Task <T> As <T>(this SolidHttpRequest request, ZipArchiveMode mode)
        {
            var factory     = new ZipArchiveResponseDeserializerFactory(mode);
            var deserialize = factory.CreateDeserializer <T>();

            return(await request.As <T>());
        }
예제 #6
0
        /// <summary>
        /// Adds form data content to the request
        /// </summary>
        /// <param name="request">The SolidHttpRequest</param>
        /// <param name="name">The form name of the content</param>
        /// <param name="content">The HttpContent</param>
        /// <returns>SolidHttpRequest</returns>
        public static SolidHttpRequest WithFormDataContent(this SolidHttpRequest request, string name, HttpContent content)
        {
            var form = request.GetMultipartFormDataContent();

            form.Add(content, name);
            return(request);
        }
예제 #7
0
        public ISolidHttpRequest PerformRequestAsync(HttpMethod method, Uri url, CancellationToken cancellationToken)
        {
            var onRequest  = _services.GetService <SolidAsyncEventHandler <HttpRequestMessage> >();
            var onResponse = _services.GetService <SolidAsyncEventHandler <HttpResponseMessage> >();
            var request    = new SolidHttpRequest(this, _services, method, url, onRequest, onResponse, cancellationToken);

            _onRequestCreated(_services, request);
            return(request);
        }
예제 #8
0
        /// <summary>
        /// Replaces a templated parameter in the url
        /// </summary>
        /// <param name="request">The SolidHttpRequest</param>
        /// <param name="name">The name of the templated parameter</param>
        /// <param name="value">The value to inject</param>
        /// <returns>SolidHttpRequest</returns>
        public static SolidHttpRequest WithNamedParameter(this SolidHttpRequest request, string name, string value)
        {
            var url   = request.BaseRequest.RequestUri.OriginalString;
            var regex = new Regex($@"{{\s*{name}\s*}}");

            url = regex.Replace(url, value);
            request.BaseRequest.RequestUri = new Uri(url, UriKind.RelativeOrAbsolute);
            return(request);
        }
예제 #9
0
 /// <summary>
 /// Map a handler to a specific http status code
 /// </summary>
 /// <param name="request">The SolidHttpRequest</param>
 /// <param name="predicate">The predicate</param>
 /// <param name="handler">The handler</param>
 /// <returns>SolidHttpRequest</returns>
 public static SolidHttpRequest On(this SolidHttpRequest request, Func <HttpResponseMessage, bool> predicate, Action <HttpResponseMessage, IServiceProvider> handler)
 {
     request.OnResponse += (sender, args) =>
     {
         if (predicate(args.Response))
         {
             handler(args.Response, args.Services);
         }
     };
     return(request);
 }
예제 #10
0
        private static MultipartFormDataContent GetMultipartFormDataContent(this SolidHttpRequest request)
        {
            var multipart = request.BaseRequest.Content as MultipartFormDataContent;

            if (multipart == null)
            {
                multipart = request.WithMultipartContent(() => new MultipartFormDataContent()).BaseRequest.Content as MultipartFormDataContent;
            }

            return(multipart);
        }
예제 #11
0
        /// <summary>
        /// Perform an http request
        /// </summary>
        /// <param name="method">The http method for the request</param>
        /// <param name="url">The url to be requested</param>
        /// <param name="cancellationToken">The cancellation token for the request</param>
        /// <returns></returns>
        public SolidHttpRequest PerformRequestAsync(HttpMethod method, Uri url, CancellationToken cancellationToken)
        {
            var request = new SolidHttpRequest(this, method, url, cancellationToken);

            Events.InvokeOnRequestCreated(this, request);
            if (OnRequestCreated != null)
            {
                OnRequestCreated(this, Events.CreateArgs(request));
            }
            return(request);
        }
예제 #12
0
        /// <summary>
        /// Adds StringContent containing a json string of the supplied body object
        /// </summary>
        /// <typeparam name="T">The type of body</typeparam>
        /// <param name="request">The SolidHttpRequest</param>
        /// <param name="body">The request body object</param>
        /// <param name="settings">(Optional) DataContractSerializerSettings to use to serialize the body object</param>
        /// <returns>SolidHttpRequest</returns>
        public static SolidHttpRequest WithXmlContent <T>(this SolidHttpRequest request, T body, DataContractSerializerSettings settings = null)
        {
            using (var ms = new MemoryStream())
            {
                var ser = new DataContractSerializer(typeof(T), settings ?? request.GetXmlSerializerSettings());
                ser.WriteObject(ms, body);
                ms.Position = 0;

                var content = new StringContent(new StreamReader(ms).ReadToEnd(), Encoding.UTF8, "application/xml");
                return(request.WithContent(content));
            }
        }
예제 #13
0
        /// <summary>
        /// Adds HttpContent to the request
        /// <para>If there is already HttpContent on the request, it makes the request multipart</para>
        /// </summary>
        /// <param name="request">The SolidHttpRequest</param>
        /// <param name="content">The HttpContent</param>
        /// <returns>SolidHttpRequest</returns>
        public static SolidHttpRequest WithContent(this SolidHttpRequest request, HttpContent content)
        {
            if (request.BaseRequest.Content == null)
            {
                request.BaseRequest.Content = content;
                return(request);
            }
            var multipart = request.WithMultipartContent(() => new MultipartContent()).BaseRequest.Content as MultipartContent;

            multipart.Add(content);
            return(request);
        }
예제 #14
0
        /// <summary>
        /// Expect a success status code
        /// <para>If a non-success status code is received, an InvalidOperationException is thrown</para>
        /// </summary>
        /// <param name="request">The SolidHttpRequest</param>
        /// <returns>SolidHttpRequest</returns>
        public static SolidHttpRequest ExpectSuccess(this SolidHttpRequest request)
        {
            request.OnResponse += async(sender, args) =>
            {
                if (!args.Response.IsSuccessStatusCode)
                {
                    var message = await GenerateNonSuccessMessage(args.Response);

                    // TODO: reevaluate this exception type. maybe a seperate type for server error and client error
                    throw new InvalidOperationException(message);
                }
            };
            return(request);
        }
예제 #15
0
        /// <summary>
        /// Deserializes the response content using a specified deserializer
        /// </summary>
        /// <typeparam name="T">The type to deserialize to</typeparam>
        /// <param name="request">The SolidHttpRequest</param>
        /// <param name="deserialize">The deserialization method</param>
        /// <returns>Task of type T</returns>
        public static async Task <T> As <T>(this SolidHttpRequest request, Func <HttpContent, Task <T> > deserialize)
        {
            var content = await request.GetContentAsync();

            if (content == null)
            {
                return(default(T));                 // should we maybe throw an exception if there is no content?
            }
            if (request.BaseRequest.Properties.ContainsKey("IgnoreSerializationError"))
            {
                return(await SafeDeserializeAsync(() => deserialize(content)));
            }
            return(await deserialize(content));
        }
예제 #16
0
        /// <summary>
        /// Map an async handler to a specific http status code
        /// </summary>
        /// <param name="request">The SolidHttpRequest</param>
        /// <param name="predicate">The predicate</param>
        /// <param name="handler">The async handler</param>
        /// <returns>SolidHttpRequest</returns>
        public static SolidHttpRequest On(this SolidHttpRequest request, Func <HttpResponseMessage, bool> predicate, Func <HttpResponseMessage, IServiceProvider, Task> handler)
        {
            request.OnResponse += (sender, args) =>
            {
                var done = false;
                if (predicate(args.Response))
                {
                    handler(args.Response, args.Services).ContinueWith(t =>
                    {
                        done = true;
                    });
                }
                else
                {
                    done = true;
                }

                System.Threading.SpinWait.SpinUntil(() => done);
            };
            return(request);
        }
예제 #17
0
        /// <summary>
        /// Adds a query parameter to the url
        /// </summary>
        /// <param name="request">The SolidHttpRequest</param>
        /// <param name="name">The name of the query parameter</param>
        /// <param name="values">Value or values for the query parameter</param>
        /// <returns></returns>
        public static SolidHttpRequest WithQueryParameter(this SolidHttpRequest request, string name, StringValues values)
        {
            if (values == StringValues.Empty)
            {
                return(request);
            }
            var queryVals = string.Join("&", values.Select(v => $"{name}={v}"));

            var url = request.BaseRequest.RequestUri.OriginalString;

            if (url.Contains("?"))
            {
                url += $"&{queryVals}";
            }
            else
            {
                url += $"?{queryVals}";
            }
            request.BaseRequest.RequestUri = new Uri(url, UriKind.RelativeOrAbsolute);
            return(request);
        }
예제 #18
0
        /// <summary>
        /// Deserializes the response content
        /// </summary>
        /// <typeparam name="T">The type to deserialize to</typeparam>
        /// <param name="request">The SolidHttpRequest</param>
        /// <returns>Task of type T</returns>
        public static async Task <T> As <T>(this SolidHttpRequest request)
        {
            var content = await request.GetContentAsync();

            if (content == null)
            {
                return(default(T));                 // should we maybe throw an exception if there is no content?
            }
            var mime = content?.Headers?.ContentType?.MediaType;

            var deserializer = request.Client.Deserializers.FirstOrDefault(d => d.CanDeserialize(mime));

            if (deserializer == null)
            {
                throw new InvalidOperationException($"Cannot deserialize {mime} response as {typeof(T).FullName}");
            }
            if (request.BaseRequest.Properties.ContainsKey("IgnoreSerializationError"))
            {
                return(await SafeDeserializeAsync(() => deserializer.DeserializeAsync <T>(content)));
            }
            return(await deserializer.DeserializeAsync <T>(content));
        }
예제 #19
0
 /// <summary>
 /// Returns the response content as text
 /// </summary>
 /// <param name="request">The SolidHttpRequest</param>
 /// <returns>Task of type string</returns>
 public static async Task <string> AsText(this SolidHttpRequest request)
 {
     return(await request.As(async content => await content.ReadAsStringAsync()));
 }
예제 #20
0
 /// <summary>
 /// Deserializes the response content as the specified anonymous type
 /// </summary>
 /// <typeparam name="T">The type to deserialize to</typeparam>
 /// <param name="request">The SolidHttpRequest</param>
 /// <param name="anonymous">An anonumous type to infer T</param>
 /// <returns>Task of type T</returns>
 public static async Task <T> As <T>(this SolidHttpRequest request, T anonymous)
 {
     return(await request.As <T>());
 }
예제 #21
0
 /// <summary>
 /// Deserializes the response content as an array of type T
 /// </summary>
 /// <typeparam name="T">The type to deserialize to</typeparam>
 /// <param name="request">The SolidHttpRequest</param>
 /// <returns>Task of type IEnumerable&lt;T&gt;</returns>
 public static async Task <IEnumerable <T> > AsMany <T>(this SolidHttpRequest request)
 {
     return(await request.As <IEnumerable <T> >());
 }
예제 #22
0
 /// <summary>
 /// Deserializes the response content as the specified anonymous type using the specified settings
 /// </summary>
 /// <typeparam name="T">The type of resonse body</typeparam>
 /// <param name="request">The SolidHttpRequest</param>
 /// <param name="anonymous">The anonymous type</param>
 /// <param name="settings">The specified JsonSerializerSettings</param>
 /// <returns>Task of type T</returns>
 public static Task <T> As <T>(this SolidHttpRequest request, T anonymous, JsonSerializerSettings settings)
 {
     return(request.As <T>(settings));
 }
예제 #23
0
        private static async Task <HttpContent> GetContentAsync(this SolidHttpRequest request)
        {
            var response = await request;

            return(response.Content);
        }
예제 #24
0
 /// <summary>
 /// Deserializes the response content as the specified anonymous type using the specified settings
 /// </summary>
 /// <typeparam name="T">The type of resonse body</typeparam>
 /// <param name="request">The SolidHttpRequest</param>
 /// <param name="anonymous">The anonymous type</param>
 /// <param name="settings">The specified JsonSerializerSettings</param>
 /// <returns>Task of type IEnumerable&lt;T&gt;</returns>
 public static Task <IEnumerable <T> > AsMany <T>(this SolidHttpRequest request, T anonymous, JsonSerializerSettings settings)
 {
     return(request.As <IEnumerable <T> >(settings));
 }
예제 #25
0
 /// <summary>
 /// Map an async handler to a specific http status code
 /// </summary>
 /// <param name="request">The SolidHttpRequest</param>
 /// <param name="predicate">The predicate</param>
 /// <param name="handler">The async handler</param>
 /// <returns>SolidHttpRequest</returns>
 public static SolidHttpRequest On(this SolidHttpRequest request, Func <HttpResponseMessage, bool> predicate, Func <HttpResponseMessage, Task> handler)
 {
     return(request.On(predicate, (response, provider) => handler(response)));
 }
예제 #26
0
 /// <summary>
 /// Map an async handler to a specific http status code
 /// </summary>
 /// <param name="request">The SolidHttpRequest</param>
 /// <param name="code">The http status code</param>
 /// <param name="handler">The async handler</param>
 /// <returns>SolidHttpRequest</returns>
 public static SolidHttpRequest On(this SolidHttpRequest request, HttpStatusCode code, Func <HttpResponseMessage, IServiceProvider, Task> handler)
 {
     return(request.On(response => response.StatusCode == code, handler));
 }
예제 #27
0
 /// <summary>
 /// Map an async handler to a specific http status code
 /// </summary>
 /// <param name="request">The SolidHttpRequest</param>
 /// <param name="code">The http status code</param>
 /// <param name="handler">The async handler</param>
 /// <returns>SolidHttpRequest</returns>
 public static SolidHttpRequest On(this SolidHttpRequest request, HttpStatusCode code, Func <HttpResponseMessage, Task> handler)
 {
     return(request.On(code, (response, provider) => handler(response)));
 }
예제 #28
0
 /// <summary>
 /// Expect a success status code
 /// <para>If a non-success status code is received, an InvalidOperationException is thrown</para>
 /// </summary>
 /// <param name="request">The SolidHttpRequest</param>
 /// <returns>SolidHttpRequest</returns>
 public static SolidHttpRequest IgnoreSerializationError(this SolidHttpRequest request)
 {
     request.BaseRequest.Properties.Add("IgnoreSerializationError", bool.TrueString);
     return(request);
 }
예제 #29
0
 /// <summary>
 /// Map a handler to a specific http status code
 /// </summary>
 /// <param name="request">The SolidHttpRequest</param>
 /// <param name="predicate">The predicate</param>
 /// <param name="handler">The handler</param>
 /// <returns>SolidHttpRequest</returns>
 public static SolidHttpRequest On(this SolidHttpRequest request, Func <HttpResponseMessage, bool> predicate, Action <HttpResponseMessage> handler)
 {
     return(request.On(predicate, (response, services) => handler(response)));
 }
예제 #30
0
 /// <summary>
 /// Map a handler to a specific http status code
 /// </summary>
 /// <param name="request">The SolidHttpRequest</param>
 /// <param name="code">The http status code</param>
 /// <param name="handler">The handler</param>
 /// <returns>SolidHttpRequest</returns>
 public static SolidHttpRequest On(this SolidHttpRequest request, HttpStatusCode code, Action <HttpResponseMessage, IServiceProvider> handler)
 {
     return(request.On(r => r.StatusCode == code, handler));
 }