/// <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); }
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); } }
/// <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)); }
/// <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)); }
/// <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>()); }
/// <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); }
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); }
/// <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); }
/// <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); }
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); }
/// <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); }
/// <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)); } }
/// <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); }
/// <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); }
/// <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)); }
/// <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); }
/// <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); }
/// <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)); }
/// <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())); }
/// <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>()); }
/// <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<T></returns> public static async Task <IEnumerable <T> > AsMany <T>(this SolidHttpRequest request) { return(await request.As <IEnumerable <T> >()); }
/// <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)); }
private static async Task <HttpContent> GetContentAsync(this SolidHttpRequest request) { var response = await request; return(response.Content); }
/// <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<T></returns> public static Task <IEnumerable <T> > AsMany <T>(this SolidHttpRequest request, T anonymous, JsonSerializerSettings settings) { return(request.As <IEnumerable <T> >(settings)); }
/// <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))); }
/// <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)); }
/// <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))); }
/// <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); }
/// <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))); }
/// <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)); }