简体   繁体   English

如何制作 http 客户端,通过多部分表单数据发送 Base64 加密八位字节 stream?

[英]How can I make a http client that sends Base64 encrypted octet stream via Multipart form data?

Context语境

In my company we have a API that's very tricky to handle.在我的公司,我们有一个 API 很难处理。 I managed to make a successful PUT Request using Postman and now I want to build this same http request in C# using a simple Console application.我设法使用Postman成功发出 PUT 请求,现在我想使用简单的控制台应用程序在 C# 中构建相同的 http 请求。 Here is the postman request:这是 postman 请求:

在此处输入图像描述

The 2nd key has to be named exactly like that.第二个键必须完全这样命名。 The entry Json I can use via file or directly as value. entry Json 我可以通过文件或直接作为值使用。

Here are the headers:以下是标题:

在此处输入图像描述 Only important one is the Authorization Header.唯一重要的是授权 Header。

The problem问题

I don't know how to actually create this complicated request in C# since I'm very new to this language and couldn't find a solution to my specific problem.我不知道如何在 C# 中实际创建这个复杂的请求,因为我对这种语言非常陌生,无法找到解决我的具体问题的方法。

I tried with the normal httpclient from C# and RestSharp but wasn't able to make this request.我尝试使用来自 C# 和RestSharp的普通 httpclient,但无法发出此请求。

Here is what I have so far:这是我到目前为止所拥有的:

{
  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("https://test-itsm.voestalpine.net/api/arsys/v1/entry/HPD:IncidentInterface/INC000001479529|INC000001479529", multipart);
      resp.EnsureSuccessStatusCode();
    }
  }
}

So how can I make this complicated request like the on shown in Postman exactly the same in C#?那么我怎样才能使这个复杂的请求像 Postman 中显示的那样在 C# 中完全相同呢? The API Admins told me the attachment in attach-z2AF_Act_Attachment_1 has to come Base64 encrypted API 管理员告诉我attach-z2AF_Act_Attachment_1中的附件必须经过 Base64 加密

For anyone that is interested what this call actually does:对于任何对此调用的实际作用感兴趣的人:

It adds a new Worklog to an existing ticket in our ticket system (BMC Remedy) and also adds an attachment to this new worklog entry.它向我们的工单系统 (BMC Remedy) 中的现有工单添加了一个新的工作日志,并且还在这个新的工作日志条目中添加了一个附件。

Thank you very much.非常感谢。

Please look at the code below, please test it at your environment.请看下面的代码,请在您的环境中测试它。

The point is that you can set content types manually.关键是您可以手动设置内容类型。

Another point is that you set Authorization header wrong.还有一点就是你设置 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();
    }

With my approach i got this request:通过我的方法,我收到了这个请求:

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--

Is it correct?这是对的吗?


Update: I've made a base-64 encoded version of attachment.更新:我制作了一个 base-64 编码的附件版本。 Simply set base64 to true.只需将base64设置为 true。

Request with base64 approach:使用 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--

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM