如何制作一个通过多部分表单数据发送 Base64 加密八位字节流的 http 客户端?
How can I make a http client that sends Base64 encrypted octet stream via Multipart form data?
上下文
我公司有一个 API 很难处理。我成功地使用 Postman
发出了一个 PUT 请求,现在我想使用一个简单的控制台应用程序在 C# 中构建相同的 http 请求。
这是邮递员要求:
第二个键必须完全这样命名。 entry
Json 我可以通过文件或直接作为值使用。
这是headers:
唯一重要的是授权 Header.
问题
我不知道如何在 C# 中实际创建这个复杂的请求,因为我对这种语言还很陌生,找不到解决我的具体问题的方法。
我尝试使用 C# 和 RestSharp
中的普通 httpclient,但无法发出此请求。
这是我目前的情况:
{
class Program
{
static readonly HttpClient client = new HttpClient();
static async Task Main(string[] args)
{
using var multipart = new MultipartFormDataContent();
var jsonBytes = JsonSerializer.SerializeToUtf8Bytes(new { Metadata = "abc" });
// Need to add my json file or the json direct here somewhere
// This is how the JSON looks like
/*
{
"values": {
"z1D_WorklogDetails": "very new workinfo 3",
"z1D_View_Access": "Internal",
"z1D Action": "MODIFY",
"z2AF_Act_Attachment_1": "UID Liste.xlsx"
}
}
*/
multipart.Add(new ByteArrayContent(jsonBytes), "entry");
using var fs = File.OpenRead(@"C:\myFile.txt");
multipart.Add(new StreamContent(fs), "attach-z2AF_Act_Attachment_1");
multipart.Headers.Add("Authorization", "//my token here");
using var resp = await client.PostAsync("**/entry/HPD:IncidentInterface/INC000001479529|INC000001479529", multipart);
resp.EnsureSuccessStatusCode();
}
}
}
那么如何才能让这个复杂的请求像Postman中显示的on一样在C#中完全一样呢? API 管理员告诉我 attach-z2AF_Act_Attachment_1
中的附件必须经过 Base64 加密
任何对这个调用的实际作用感兴趣的人:
它向我们的工单系统 (BMC Remedy) 中的现有工单添加了一个新的工作日志,并且还向这个新的工作日志条目添加了一个附件。
非常感谢。
请查看下面的代码,请在您的环境中进行测试。
重点是您可以手动设置内容类型。
还有一点就是你设置的Authorization header错误。
using System.Net.Http.Headers;
using System.Net.Mime;
using System.Security.Cryptography;
using System.Text;
using System.Text.Json;
string url = "https://localhost/";
string token = "token_here";
//Prepare json data
string json = JsonSerializer.Serialize(new { Metadata = "abc" });
StringContent jsonContent = new StringContent(json, Encoding.UTF8, MediaTypeNames.Application.Json);
StreamContent streamContent;
bool base64 = false;
//Prepare octet-stream data
if (base64)
{
//For base-64 encoded message
using FileStream inputFile = new FileStream(@"2.txt", FileMode.Open, FileAccess.Read, FileShare.None,
bufferSize: 1024 * 1024, useAsync: true);
using CryptoStream base64Stream = new CryptoStream(inputFile, new ToBase64Transform(), CryptoStreamMode.Read);
streamContent = new StreamContent(base64Stream);
streamContent.Headers.Add("Content-Type", MediaTypeNames.Application.Octet);
await SendRequest(jsonContent, streamContent, url, token);
}
else
{
//For plain message
using FileStream file = File.OpenRead("2.txt");
streamContent = new StreamContent(file);
streamContent.Headers.Add("Content-Type", MediaTypeNames.Application.Octet);
await SendRequest(jsonContent, streamContent, url, token);
}
async Task SendRequest(StringContent stringContent, StreamContent streamContent, string url, string token)
{
// Add json and octet-stream to multipart content
MultipartFormDataContent multipartContent = new MultipartFormDataContent();
multipartContent.Add(stringContent, "entry");
multipartContent.Add(streamContent, "attach-z2AF_Act_Attachment_1");
//Create request
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Put, url);
//Here is the right setting of auth header value, sheme is on the left side
request.Headers.Authorization = new AuthenticationHeaderValue("AR-JWT", token);
request.Content = multipartContent;
//Last step - sending request
HttpClient http = new HttpClient();
HttpResponseMessage resp = await http.SendAsync(request);
resp.EnsureSuccessStatusCode();
}
通过我的方法,我得到了这个请求:
Headers:
{
"content-length": "6538",
"authorization": "AR-JWT token_here",
"content-type": "multipart/form-data; boundary=\"02600173-b9af-49f4-8591-e7edf2c0b397\""
}
Body:
--02600173-b9af-49f4-8591-e7edf2c0b397
Content-Type: application/json; charset=utf-8
Content-Disposition: form-data; name=entry
{"Metadata":"abc"}
--02600173-b9af-49f4-8591-e7edf2c0b397
Content-Type: application/octet-stream
Content-Disposition: form-data; name=attach-z2AF_Act_Attachment_1
OCTET DATA HERE
--02600173-b9af-49f4-8591-e7edf2c0b397--
正确吗?
更新:我制作了一个 base-64 编码版本的附件。
只需将 base64
设置为 true。
使用 base64 方法请求:
Headers:
{
"content-length": "354",
"authorization": "AR-JWT token_here",
"content-type": "multipart/form-data; boundary=\"7572d1e8-7bd7-4f01-9c78-ce5b624faab3\""
}
Body:
--7572d1e8-7bd7-4f01-9c78-ce5b624faab3
Content-Type: application/json; charset=utf-8
Content-Disposition: form-data; name=entry
{"Metadata":"abc"}
--7572d1e8-7bd7-4f01-9c78-ce5b624faab3
Content-Type: application/octet-stream
Content-Disposition: form-data; name=attach-z2AF_Act_Attachment_1
MjIyMg==
--7572d1e8-7bd7-4f01-9c78-ce5b624faab3--
上下文
我公司有一个 API 很难处理。我成功地使用 Postman
发出了一个 PUT 请求,现在我想使用一个简单的控制台应用程序在 C# 中构建相同的 http 请求。
这是邮递员要求:
第二个键必须完全这样命名。 entry
Json 我可以通过文件或直接作为值使用。
这是headers:
问题
我不知道如何在 C# 中实际创建这个复杂的请求,因为我对这种语言还很陌生,找不到解决我的具体问题的方法。
我尝试使用 C# 和 RestSharp
中的普通 httpclient,但无法发出此请求。
这是我目前的情况:
{
class Program
{
static readonly HttpClient client = new HttpClient();
static async Task Main(string[] args)
{
using var multipart = new MultipartFormDataContent();
var jsonBytes = JsonSerializer.SerializeToUtf8Bytes(new { Metadata = "abc" });
// Need to add my json file or the json direct here somewhere
// This is how the JSON looks like
/*
{
"values": {
"z1D_WorklogDetails": "very new workinfo 3",
"z1D_View_Access": "Internal",
"z1D Action": "MODIFY",
"z2AF_Act_Attachment_1": "UID Liste.xlsx"
}
}
*/
multipart.Add(new ByteArrayContent(jsonBytes), "entry");
using var fs = File.OpenRead(@"C:\myFile.txt");
multipart.Add(new StreamContent(fs), "attach-z2AF_Act_Attachment_1");
multipart.Headers.Add("Authorization", "//my token here");
using var resp = await client.PostAsync("**/entry/HPD:IncidentInterface/INC000001479529|INC000001479529", multipart);
resp.EnsureSuccessStatusCode();
}
}
}
那么如何才能让这个复杂的请求像Postman中显示的on一样在C#中完全一样呢? API 管理员告诉我 attach-z2AF_Act_Attachment_1
中的附件必须经过 Base64 加密
任何对这个调用的实际作用感兴趣的人:
它向我们的工单系统 (BMC Remedy) 中的现有工单添加了一个新的工作日志,并且还向这个新的工作日志条目添加了一个附件。
非常感谢。
请查看下面的代码,请在您的环境中进行测试。
重点是您可以手动设置内容类型。
还有一点就是你设置的Authorization header错误。
using System.Net.Http.Headers;
using System.Net.Mime;
using System.Security.Cryptography;
using System.Text;
using System.Text.Json;
string url = "https://localhost/";
string token = "token_here";
//Prepare json data
string json = JsonSerializer.Serialize(new { Metadata = "abc" });
StringContent jsonContent = new StringContent(json, Encoding.UTF8, MediaTypeNames.Application.Json);
StreamContent streamContent;
bool base64 = false;
//Prepare octet-stream data
if (base64)
{
//For base-64 encoded message
using FileStream inputFile = new FileStream(@"2.txt", FileMode.Open, FileAccess.Read, FileShare.None,
bufferSize: 1024 * 1024, useAsync: true);
using CryptoStream base64Stream = new CryptoStream(inputFile, new ToBase64Transform(), CryptoStreamMode.Read);
streamContent = new StreamContent(base64Stream);
streamContent.Headers.Add("Content-Type", MediaTypeNames.Application.Octet);
await SendRequest(jsonContent, streamContent, url, token);
}
else
{
//For plain message
using FileStream file = File.OpenRead("2.txt");
streamContent = new StreamContent(file);
streamContent.Headers.Add("Content-Type", MediaTypeNames.Application.Octet);
await SendRequest(jsonContent, streamContent, url, token);
}
async Task SendRequest(StringContent stringContent, StreamContent streamContent, string url, string token)
{
// Add json and octet-stream to multipart content
MultipartFormDataContent multipartContent = new MultipartFormDataContent();
multipartContent.Add(stringContent, "entry");
multipartContent.Add(streamContent, "attach-z2AF_Act_Attachment_1");
//Create request
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Put, url);
//Here is the right setting of auth header value, sheme is on the left side
request.Headers.Authorization = new AuthenticationHeaderValue("AR-JWT", token);
request.Content = multipartContent;
//Last step - sending request
HttpClient http = new HttpClient();
HttpResponseMessage resp = await http.SendAsync(request);
resp.EnsureSuccessStatusCode();
}
通过我的方法,我得到了这个请求:
Headers:
{
"content-length": "6538",
"authorization": "AR-JWT token_here",
"content-type": "multipart/form-data; boundary=\"02600173-b9af-49f4-8591-e7edf2c0b397\""
}
Body:
--02600173-b9af-49f4-8591-e7edf2c0b397
Content-Type: application/json; charset=utf-8
Content-Disposition: form-data; name=entry
{"Metadata":"abc"}
--02600173-b9af-49f4-8591-e7edf2c0b397
Content-Type: application/octet-stream
Content-Disposition: form-data; name=attach-z2AF_Act_Attachment_1
OCTET DATA HERE
--02600173-b9af-49f4-8591-e7edf2c0b397--
正确吗?
更新:我制作了一个 base-64 编码版本的附件。
只需将 base64
设置为 true。
使用 base64 方法请求:
Headers:
{
"content-length": "354",
"authorization": "AR-JWT token_here",
"content-type": "multipart/form-data; boundary=\"7572d1e8-7bd7-4f01-9c78-ce5b624faab3\""
}
Body:
--7572d1e8-7bd7-4f01-9c78-ce5b624faab3
Content-Type: application/json; charset=utf-8
Content-Disposition: form-data; name=entry
{"Metadata":"abc"}
--7572d1e8-7bd7-4f01-9c78-ce5b624faab3
Content-Type: application/octet-stream
Content-Disposition: form-data; name=attach-z2AF_Act_Attachment_1
MjIyMg==
--7572d1e8-7bd7-4f01-9c78-ce5b624faab3--