如何在 C# 中创建 POST 到 BMC REMEDY API 上的端点,以使用表单数据中提交的文件创建票证?

问题描述 投票:0回答:3

我有这个问题。我必须向 bmc API 上的端点提交(或不提交)文件。

带有

KEY:entry
VALUE:data_entry.txt
是要与值一起发送的 SON,与正文相同。 Attach-z2AF_WIAttachment1是我要提交的文件。我总是抛出一些错误,或者标头无效,或者文件类型无效,但在邮递员中正在工作。

我无法转换为 C#。 这是我到目前为止的代码:

  try
        {
            //authentication
            var dict = new Dictionary<string, string>();
            dict.Add("username", "applicationUsernameJonDoe");
            dict.Add("password", "applicationPassowrdXPTO");
            var clientLogin = new HttpClient();
            var req = new HttpRequestMessage(HttpMethod.Post, Endpoint_loginITSM) { Content = new FormUrlEncodedContent(dict) };
            var res = clientLogin.SendAsync(req); //.Result.ToString();
            var body = res.GetAwaiter().GetResult().Content.ReadAsStringAsync();

            //pedido de criação de registo

            using (var client = new HttpClient())
            {
                client.Timeout = TimeSpan.FromMinutes(10);
                var request = new HttpRequestMessage
                {
                    RequestUri = new Uri(Endpoint_CreateITSM),
                    Method = HttpMethod.Post
                };
                request.Headers.Add("Authorization", body.Result.ToString());
                if (!string.IsNullOrEmpty(registos.Objeto.fileName))
                {
                    registos.Objeto.Registo.z2AF_WIAttachment1 = registos.Objeto.fileName;
                }
                string json = JsonConvert.SerializeObject(new { values = registos.Objeto });

                byte[] file_bytes = System.Convert.FromBase64String(registos.Objeto.fileEncoded);

                MemoryStream memoryStream = new MemoryStream();
                using (BsonDataWriter writer = new BsonDataWriter(memoryStream))
                {
                    JsonSerializer serializer = new JsonSerializer();
                    serializer.Serialize(writer, registos.Objeto.Registo);
                }
                var data_entry_bytes = memoryStream.ToArray();


                // we need to send a request with multipart/form-data
                var multiForm = new MultipartFormDataContent();
                ByteArrayContent data_entry_json_content = new ByteArrayContent(data_entry_bytes);
                data_entry_json_content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
                data_entry_json_content.Headers.ContentDisposition = new ContentDispositionHeaderValue("entry")
                {
                    FileName = "data_entry.txt",
                    Name = "entry",
                };
                multiForm.Add(data_entry_json_content);

                ByteArrayContent z2AF_WIAttachment1_content = new ByteArrayContent(file_bytes);
                z2AF_WIAttachment1_content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
                z2AF_WIAttachment1_content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attach-z2AF_WIAttachment1")
                {
                    FileName = registos.Objeto.fileName,
                    Name = "attach-z2AF_WIAttachment1",
                };
                multiForm.Add(z2AF_WIAttachment1_content);
                request.Content = multiForm;
                var result = await client.SendAsync(request);

                var resBody = result.Content.ReadAsStringAsync().Result.ToString();//.ConfigureAwait(false);
                dynamic _resBody = JsonConvert.DeserializeObject<dynamic>(resBody);
                string registoID = _resBody["values"].SysRequestID;
                return ResponseHandler<string>.Resposta(false, "resposta api bit criar registos", registoID);
            }

        }
        catch (Exception e)
        {
            string classname = this.GetType().Name;
            CentralLibrary.Services.ErrorLoggingService.ErrorLogsForCore(classname, e, _env.WebRootPath);
            return ResponseHandler<string>.Resposta(true, "EXCEPTION : resposta api bit criar registos", e.Message);
        }
c# post form-data remedy
3个回答
1
投票

这是一个更好的解决方案。 我对最后一个有疑问,但对于那些不想使用 RestClient 库的人来说就是这样。但这是 100% 有效的,并且我有 NewtonSoft.Json 的 JsonProperty 名称,因此可以使用类似的名称

    [JsonProperty("z1D Action")]
    public string z1D_Action { get;  } = "CREATE";

所以,我的代码是,并使用对象AbrirRegistosITSM和嵌套对象AbrirRegistosITSM_com_anexo我的最终解决方案是

AbrirRegistosITSM _registo = new AbrirRegistosITSM
{
  Values = new AbrirRegistosITSM_com_anexo
        {
          Details = registos.Objeto.Comentario,
          Customer_Login = registos.username,
          Login_ID = registos.username,
          SR_Type_Field_3 = registos.Objeto.Tipologia,
          SR_Type_Field_28 = registos.Objeto.Categoria,
          z2AF_WIAttachment1 = registos.Objeto.FicheiroNome
         }
};

var client = new RestClient(Endpoint_CreateITSM);
string baseFolder = _env.WebRootPath;
string pathDir = Path.Combine(baseFolder, DateTime.Now.ToString().Replace('/', '_').Replace(' ', '_').Replace(':', '_'));
Directory.CreateDirectory(pathDir);
string pathDirFile = Path.Combine(pathDir, registos.Objeto.FicheiroNome);
File.WriteAllBytes(pathDirFile, Convert.FromBase64String(registos.Objeto.FicheiroBase64));
string pathEntryDir = Path.Combine(baseFolder, DateTime.Now.ToString().Replace('/', '_').Replace(' ', '_').Replace(':', '_'));
Directory.CreateDirectory(pathEntryDir);
string patnEntrydirFile = Path.Combine(pathEntryDir, "data_entry.txt");  
File.WriteAllText(patnEntrydirFile, JsonConvert.SerializeObject(new { values = _registo.Values }));
var request = new RestRequest();
request.Method = Method.Post;
request.AddHeader("Authorization", token);
request.AddFile("entry", patnEntrydirFile, "application/json");
request.AddFile("attach-z2AF_WIAttachment1", pathDirFile, "application/octet-stream");
var reqbody = JsonConvert.SerializeObject(_registo);                   
request.AddParameter("application/json", reqbody, ParameterType.RequestBody);
RestResponse response = client.Execute(request);
var respostaBody = response.Content.ToString();//.ConfigureAwait(false);
dynamic _respostaBody = JsonConvert.DeserializeObject<dynamic>(respostaBody);
string _registoID = _respostaBody["values"]["Request Number"];

然后我返回我需要的请求号,但是那里有很多值。我使用 NewtonSoft 记住这一点。我不使用 JsonSerializer,因为我无法使用 JsonSerializer 保存带有空格的 json 属性名称。


0
投票

我不完全确定这里出了什么问题。可能有很多事情,但我也许可以帮助你。在过去的几周里,我构建了一个 HttpClient,它将包含元数据的文件发送到 GraphQL 端点。

请确保以下事项: 我认为您正在通过电话请求该文件。请使用

Byte[]
将其存储在变量中作为
ReadAsByteArrayAsync()
。请注意对其进行解码或将其转换为字符串或其他内容。你只会损坏文件。

var response = client.GetAsync(fileUrl);
    
var downloadedFile = await response.Result.Content.ReadAsByteArrayAsync();

以下代码可能无法完全适合您的情况,但应该可以帮助您构建正确的请求,因为我还在请求中发送包含文件扩展名和其他一些信息的元数据。这很可能会将文件发送到您的 API,而不带文件扩展名。

using (var client = new HttpClient())
{
    var file = new byte[] { 1, 2, 3 };
    var fileToUpload = new ByteArrayContent(file);

    var formData = new MultipartFormDataContent
                {
                    { fileToUpload, "entry", "passInFileExtensionForExample"},
                    { fileToUpload, "attach-z2AF_WIAttachment1", "passInFileExtensionForExample" }
                };

    var response = await client.PostAsync("endpoint", formData);
}

使用以下代码添加承载令牌:

 client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);

0
投票

所以我找到了解决我的问题的方法。我将只提交一份文件。我还必须将 Json 正文作为文件提交 “entry”“data_entry.txt”,对于 HttpRequestMessage,您必须有一个内容

MultipartFormDataContent
,在这里您可以添加尽可能多的文件。我必须将 Json 主体转换为一个文件(在本例中我转换为二进制数组),其中包含名称条目和文件 data_entry.txt 的名称,但这是端点所需要的,所以......无论如何。

  using (var client = new HttpClient())
                {
                    client.Timeout = TimeSpan.FromMinutes(10);
                    MultipartFormDataContent content = new MultipartFormDataContent();

                    //adicionar ficheiro
                    byte[] file_bytes = System.Convert.FromBase64String(registos.Objeto.fileEncoded);
                    StreamContent fileContent = new StreamContent(new MemoryStream(file_bytes));       
                    fileContent.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data")
                    {
                        Name = "files[attach-z2AF_WIAttachment1]",
                        FileName = registos.Objeto.fileName
                    };

                    fileContent.Headers.ContentType = MediaTypeHeaderValue.Parse("application/octet-stream");
                    content.Add(fileContent);
                    //adicionar ficheiro entry
                    StreamContent entryStreamContent = new StreamContent(new MemoryStream(ObjectToByteArray(registos.Objeto.Registo)));
                    entryStreamContent.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data")
                    {
                        Name = "files[entry]",
                        FileName = "data_entry.txt"
                    };

                    entryStreamContent.Headers.ContentType = MediaTypeHeaderValue.Parse("application/json");
                    content.Add(entryStreamContent);

                    var request = new HttpRequestMessage
                    {
                        RequestUri = new Uri(Endpoint_CreateITSM),
                        Method = HttpMethod.Post,
                        Content= content

                    };

                    request.Headers.Add("Authorization", body.Result.ToString());
                    string json = JsonConvert.SerializeObject(new { values = registos.Objeto.Registo});
                    request.Content = new ByteArrayContent(Encoding.UTF8.GetBytes(json));
                    request.Content.Headers.ContentType = new MediaTypeHeaderValue("application/json");

                    var resposta = await client.SendAsync(request);
                    var respostaBody = resposta.Content.ReadAsStringAsync().Result.ToString();//.ConfigureAwait(false);
                    dynamic _respostaBody = JsonConvert.DeserializeObject<dynamic>(respostaBody);
                    string _registoID = _respostaBody["values"].SysRequestID;
                    return ResponseHandler<string>.Resposta(false, "resposta api bit criar registos", _registoID);         

这就是我的解决方案。它正在工作:)

© www.soinside.com 2019 - 2024. All rights reserved.