internal static Task <IFlurlResponse> PatchMultipartAsync(this IFlurlRequest request, Action <CapturedMultipartContent> buildContent, CancellationToken cancellationToken = default(CancellationToken)) { var cmc = new CapturedMultipartContent(request.Settings); buildContent(cmc); return(request.SendAsync(new HttpMethod("PATCH"), cmc, cancellationToken)); }
public void can_build_multipart_content() { var content = new CapturedMultipartContent() .AddString("string", "foo") .AddStringParts(new { part1 = 1, part2 = 2, part3 = (string)null }) // part3 should be excluded .AddFile("file", @"path\to\image.jpg", "image/jpeg") .AddJson("json", new { foo = "bar" }) .AddUrlEncoded("urlEnc", new { fizz = "buzz" }); Assert.AreEqual(6, content.Parts.Length); Assert.AreEqual("string", content.Parts[0].Headers.ContentDisposition.Name); Assert.IsInstanceOf <CapturedStringContent>(content.Parts[0]); Assert.AreEqual("foo", (content.Parts[0] as CapturedStringContent).Content); Assert.AreEqual("part1", content.Parts[1].Headers.ContentDisposition.Name); Assert.IsInstanceOf <CapturedStringContent>(content.Parts[1]); Assert.AreEqual("1", (content.Parts[1] as CapturedStringContent).Content); Assert.AreEqual("part2", content.Parts[2].Headers.ContentDisposition.Name); Assert.IsInstanceOf <CapturedStringContent>(content.Parts[2]); Assert.AreEqual("2", (content.Parts[2] as CapturedStringContent).Content); Assert.AreEqual("file", content.Parts[3].Headers.ContentDisposition.Name); Assert.AreEqual("image.jpg", content.Parts[3].Headers.ContentDisposition.FileName); Assert.IsInstanceOf <FileContent>(content.Parts[3]); Assert.AreEqual("json", content.Parts[4].Headers.ContentDisposition.Name); Assert.IsInstanceOf <CapturedJsonContent>(content.Parts[4]); Assert.AreEqual("{\"foo\":\"bar\"}", (content.Parts[4] as CapturedJsonContent).Content); Assert.AreEqual("urlEnc", content.Parts[5].Headers.ContentDisposition.Name); Assert.IsInstanceOf <CapturedUrlEncodedContent>(content.Parts[5]); Assert.AreEqual("fizz=buzz", (content.Parts[5] as CapturedUrlEncodedContent).Content); }
public async Task can_build_and_send_multipart_content() { var content = new CapturedMultipartContent() .AddString("string", "foo") .AddString("string2", "bar", "text/blah") .AddStringParts(new { part1 = 1, part2 = 2, part3 = (string)null }) // part3 should be excluded .AddFile("file1", Path.Combine("path", "to", "image1.jpg"), "image/jpeg") .AddFile("file2", Path.Combine("path", "to", "image2.jpg"), "image/jpeg", fileName: "new-name.jpg") .AddJson("json", new { foo = "bar" }) .AddUrlEncoded("urlEnc", new { fizz = "buzz" }); void AssertAll() { Assert.AreEqual(8, content.Parts.Count); AssertStringPart <CapturedStringContent>(content.Parts[0], "string", "foo", null); AssertStringPart <CapturedStringContent>(content.Parts[1], "string2", "bar", "text/blah"); AssertStringPart <CapturedStringContent>(content.Parts[2], "part1", "1", null); AssertStringPart <CapturedStringContent>(content.Parts[3], "part2", "2", null); AssertFilePart(content.Parts[4], "file1", "image1.jpg", "image/jpeg"); AssertFilePart(content.Parts[5], "file2", "new-name.jpg", "image/jpeg"); AssertStringPart <CapturedJsonContent>(content.Parts[6], "json", "{\"foo\":\"bar\"}", "application/json; charset=UTF-8"); AssertStringPart <CapturedUrlEncodedContent>(content.Parts[7], "urlEnc", "fizz=buzz", "application/x-www-form-urlencoded"); } // Assert before and after sending a request. MultipartContent clears the parts collection after request is sent; // CapturedMultipartContent (as the name implies) should preserve it (#580) AssertAll(); using (var test = new HttpTest()) { await "https://upload.com".PostAsync(content); } AssertAll(); }
/// <summary> /// Sends an asynchronous multipart/form-data POST request. /// </summary> /// <param name="buildContent">A delegate for building the content parts.</param> /// <param name="request">The IFlurlRequest.</param> /// <param name="cancellationToken">A cancellation token that can be used by other objects or threads to receive notice of cancellation.</param> /// <returns>A Task whose result is the received HttpResponseMessage.</returns> public static Task <HttpResponseMessage> PostMultipartAsync(this IFlurlRequest request, Action <CapturedMultipartContent> buildContent, CancellationToken cancellationToken = default(CancellationToken)) { var cmc = new CapturedMultipartContent(request.Settings); buildContent(cmc); return(request.SendAsync(HttpMethod.Post, cmc, cancellationToken)); }
public void must_provide_required_args_to_builder() { var content = new CapturedMultipartContent(); Assert.Throws <ArgumentNullException>(() => content.AddStringParts(null)); Assert.Throws <ArgumentNullException>(() => content.AddString("other", null)); Assert.Throws <ArgumentException>(() => content.AddString(null, "hello!")); Assert.Throws <ArgumentException>(() => content.AddFile(" ", "path")); }
/** * @param CapturedMultipartContent $content * @param JToken $json * @param string $key */ private void captureMultipartContentInJson(CapturedMultipartContent content, JToken json, string key) { var property = json as JProperty; if (property == null) { return; } if (property.Value.GetType().Name == "JArray") { int index = 0; foreach (JToken child in property.Values()) { string valueKey = key == "" ? property.Name : $"{key}[{property.Name}]"; valueKey += $"[{index++}]"; if (child.GetType().Name == "JValue") { content.AddString(valueKey, $"{child}"); } else { foreach (JToken subChild in child) { captureMultipartContentInJson(content, subChild, valueKey); } } } return; } if (property.Value.GetType().Name == "JObject") { string valueKey = key == "" ? property.Name : $"{key}[{property.Name}]"; foreach (JToken child in property.Values()) { captureMultipartContentInJson(content, child, valueKey); } return; } if (property.Value.GetType().Name == "JValue") { string valueKey = key == "" ? property.Name : $"{key}[{property.Name}]"; content.AddString(valueKey, property.Value.ToString()); return; } }
/** * @param CapturedMultipartContent $content * @param object $body * @param string $key */ private void captureMultipartContentInObject(CapturedMultipartContent content, object body, string key) { var data = JsonConvert.SerializeObject(body); var json = JObject.Parse(data); foreach (JToken child in json.Children()) { var property = child as JProperty; captureMultipartContentInJson(content, child, ""); } }
//public static T AsPinataFile<T>(this T content, string remoteFilePath) where T : HttpContent //{ // var header = new ContentDispositionHeaderValue("form-data") // { // Name = "file", // FileName = remoteFilePath // }; // content.Headers.ContentDisposition = header; // return content; //} public static CapturedMultipartContent AddPinataFile(this CapturedMultipartContent multipart, HttpContent httpContent, string remoteFilePath) { var header = new ContentDispositionHeaderValue("form-data") { Name = "file", FileName = remoteFilePath }; httpContent.Headers.ContentDisposition = header; multipart.Add(httpContent); return(multipart); }
static void AssertAllHttpContentHasFileName(CapturedMultipartContent content) { foreach (var part in content) { var name = part?.Headers?.ContentDisposition?.Name; var fileName = part?.Headers?.ContentDisposition?.FileName; if (string.IsNullOrWhiteSpace(name) || string.IsNullOrWhiteSpace(fileName)) { throw new HttpRequestException("The 'httpContent.Headers.ContentDisposition.(Name|FileName)' is null or whitespace. " + "All multi-part upload content must contain a 'Name' and 'FileName' content disposition header value. " + "Try using the httpContent.AsPinataFile('name.txt') extension method to set the required fields on the HttpContent you are adding."); } } }
public async Task <Issue> CreateRepositoryIssueAttachmentAsync(string workspaceId, string repositorySlug, string issueId, IssueAttachment issueAttachment) { var capturedContent = new CapturedMultipartContent(); foreach (var propertyInfo in issueAttachment.GetType().GetProperties()) { capturedContent.Add(propertyInfo.Name, new StringContent(propertyInfo.GetValue(issueAttachment).ToString())); } var response = await GetIssuesUrl(workspaceId, repositorySlug, issueId) .PostMultipartAsync(content => content.AddStringParts(capturedContent)) .ConfigureAwait(false); return(await HandleResponseAsync <Issue>(response).ConfigureAwait(false)); }
/** * @param string $method * @param string $path * @param object $query * @param object $body * @param object files * * @return Task<string> */ private async Task <HttpResponseMessage> Request(string method, string path, object query, object body, object files) { Url url = new Url($"{this.url}/v3/{path}"); FlurlClient Request = url .SetQueryParams(query) .WithOAuthBearerToken(this.accessToken) .WithHeader("User-Agent", "signaturit-net-sdk 1.1.0"); switch (method) { case "get": return(await Request.GetAsync()); case "post": if (files == null) { body = body == null ? new {} : body; return(await Request.PostJsonAsync(body as object)); } var content = new CapturedMultipartContent(); foreach (string file in files as IList <string> ) { string name = System.IO.Path.GetFileName(file); string ext = System.IO.Path.GetExtension(file); string mime = ext == "pdf" ? "application/pdf" : "application/msword"; content.AddFile($"files[{name}]", file, mime); } captureMultipartContentInObject(content, body, ""); return(await Request.PostAsync(content)); case "patch": body = body == null ? new {} : body; return(await Request.PatchJsonAsync(body as object)); case "delete": return(await Request.DeleteAsync()); } return(null); }
public async Task <IEnumerable <TemporaryAttachment> > AttachTemporaryFileToServiceDeskAsync(string serviceDeskId, IEnumerable <string> filePaths) { var content = new CapturedMultipartContent(); foreach (var filePath in filePaths) { content.AddFile("file", File.OpenRead(filePath), Path.GetFileName(filePath)); } var response = await GetServiceDeskUrl(serviceDeskId) .AppendPathSegment("/attachTemporaryFile") .SendAsync(HttpMethod.Post, content) .ConfigureAwait(false); return(await HandleResponseAsync <IEnumerable <TemporaryAttachment> >(response, s => JsonConvert.DeserializeObject <TemporaryAttachmentsResult>(s).TemporaryAttachments).ConfigureAwait(false)); }
// dev references for IFormFile and CapturedMultipartContent: // https://docs.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.http.iformfile?view=aspnetcore-2.2 // https://github.com/tmenier/Flurl/issues/113 // https://stackoverflow.com/questions/50340234/sending-rest-request-with-files-and-json-restsharp-on-framework-and-standard#50374486 public async Task <IEnumerable <TemporaryAttachment> > AttachTemporaryFileToServiceDeskAsync(string serviceDeskId, IList <IFormFile> files) { var content = new CapturedMultipartContent(); foreach (var file in files) { if (file.Length > 0) { content.AddFile(file.Name, file.OpenReadStream(), file.FileName); } } var response = await GetServiceDeskUrl(serviceDeskId) .AppendPathSegment("/attachTemporaryFile") .SendAsync(HttpMethod.Post, content) .ConfigureAwait(false); return(await HandleResponseAsync <IEnumerable <TemporaryAttachment> >(response, s => JsonConvert.DeserializeObject <TemporaryAttachmentsResult>(s).TemporaryAttachments).ConfigureAwait(false)); }
public void can_build_multipart_content() { var content = new CapturedMultipartContent() .AddString("string", "foo") .AddStringParts(new { part1 = 1, part2 = 2, part3 = (string)null }) // part3 should be excluded .AddFile("file1", Path.Combine("path", "to", "image1.jpg"), "image/jpeg") .AddFile("file2", Path.Combine("path", "to", "image2.jpg"), "image/jpeg", fileName: "new-name.jpg") .AddJson("json", new { foo = "bar" }) .AddUrlEncoded("urlEnc", new { fizz = "buzz" }); Assert.AreEqual(7, content.Parts.Length); AssertStringPart <CapturedStringContent>(content.Parts[0], "string", "foo"); AssertStringPart <CapturedStringContent>(content.Parts[1], "part1", "1"); AssertStringPart <CapturedStringContent>(content.Parts[2], "part2", "2"); AssertFilePart(content.Parts[3], "file1", "image1.jpg", "image/jpeg"); AssertFilePart(content.Parts[4], "file2", "new-name.jpg", "image/jpeg"); AssertStringPart <CapturedJsonContent>(content.Parts[5], "json", "{\"foo\":\"bar\"}"); AssertStringPart <CapturedUrlEncodedContent>(content.Parts[6], "urlEnc", "fizz=buzz"); }