Как установить FileType для файлового потока - PullRequest
0 голосов
/ 17 марта 2020

Я пытаюсь отправить поток файлов из c# в мой js бэкэнд. Имя и путь передаются корректно, но тип, кажется, отсутствует, когда я регистрирую файл, который входит в мой бэкэнд, и мне абсолютно необходим тип файла, но я не могу понять, как передать его. Может ли кто-нибудь помочь мне с этим, пожалуйста?

объект, который входит:

File {
  _events: [Object: null prototype] {},
  _eventsCount: 0,
  _maxListeners: undefined,
  size: 13920,
  path: '/var/folders/5g/f343vctd6hd7smyd5ybnfp4m0000gn/T/upload_4aebdbbee06344e12d8566dd706fd1e6',
  name: 'Invoice19.pdf',
  type: null,
  hash: null,
  lastModifiedDate: 2020-03-17T14:11:04.812Z,
  _writeStream: WriteStream {
    _writableState: WritableState {
      objectMode: false,
      highWaterMark: 16384,
      finalCalled: true,
      needDrain: false,
      ending: true,
      ended: true,
      finished: true,
      destroyed: true,
      decodeStrings: true,
      defaultEncoding: 'utf8',
      length: 0,
      writing: false,
      corked: 0,
      sync: false,
      bufferProcessing: false,
      onwrite: [Function: bound onwrite],
      writecb: null,
      writelen: 0,
      bufferedRequest: null,
      lastBufferedRequest: null,
      pendingcb: 0,
      prefinished: true,
      errorEmitted: false,
      emitClose: false,
      autoDestroy: false,
      bufferedRequestCount: 0,
      corkedRequestsFree: [Object]
    },
    writable: false,
    _events: [Object: null prototype] {},
    _eventsCount: 0,
    _maxListeners: undefined,
    path: '/var/folders/5g/f343vctd6hd7smyd5ybnfp4m0000gn/T/upload_4aebdbbee06344e12d8566dd706fd1e6',
    fd: null,
    flags: 'w',
    mode: 438,
    start: undefined,
    autoClose: true,
    pos: undefined,
    bytesWritten: 13920,
    closed: false
  }
}

мой c# код

 public IAsyncResult BeginExecute()
        {
            // set authentication
            client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", BearerToken);
            string url = "http://12915520.ngrok.io/api/organisations/" + OrganisationId + "/projects/" + ProjectId + "/process";
            string response = null;
            bool succesfullRequest = false;
            try
            {
                using (FileStream fs = File.Open(@"C:\Users\X Y\Downloads\Invoice19.pdf", FileMode.Open, FileAccess.Read))
                {
                    // send the content to the backend, parse results
                    HttpContent content = new StreamContent(fs);

                    MultipartFormDataContent formdata = new MultipartFormDataContent();
                    formdata.Add(content, "files", "Invoice19.pdf");
                    var result = client.PostAsync(url, formdata).Result;
                    response = result.Content.ReadAsStringAsync().Result;
                    succesfullRequest = result.IsSuccessStatusCode;
                }
            }
            // I absolutely want to catch every exception and pass these along to the workflow
            catch (Exception ex)
            {
                ExceptionDispatchInfo.Capture(ex.InnerException).Throw();
                throw;
            }
            // if something went wrong in the backend, throw an error
            if (!succesfullRequest)
            {
                throw new Exception("Something went wrong during the upload process");
            }

            UploadResponse r = JsonConvert.DeserializeObject<UploadResponse>(response);
            Console.WriteLine("uploadresponse:" + r.ToString());

            // dirty solution: since we don't know how long the pipeline needs to process the upload, we'll be polling for a result
            // since this is a poc this is a temporary solution, if this gets released this needs to be rewritten (maybe with webhooks)
            //var polling = true;
            //do
            //{
            //    response = client.GetAsync(url + "/" + r.uploadId).Result.Content.ReadAsStringAsync().Result;
            //    if (response != "null")
            //    {
            //        polling = false;
            //    }
            //} while (polling);
            // Because we know that there is a response now, actually execute the request
            //return client.GetAsync(url + "/" + r.uploadId);
            return null;
        }

Ответы [ 2 ]

0 голосов
/ 20 марта 2020

Я заработал это, выполнив это:

                MultipartFormDataContent formdata = new MultipartFormDataContent()
                foreach (var filePath in Files.Get(context))
                {
                    // create filestream content
                    FileStream fs = File.Open(filePath, FileMode.Open, FileAccess.Read, FileShare.Read);
                    HttpContent content = new StreamContent(fs);
                    string name = GetFileName(filePath);
                    content.Headers.Add("Content-Type", GetFileType(name));
                    formdata.Add(content, "files", name);
                }
                // send content to the backend and parse result
                var resultPost = client.PostAsync(url, formdata).Result;
                response = resultPost.Content.ReadAsStringAsync().Result;
                succesfullRequest = resultPost.IsSuccessStatusCode;

По сути, я устанавливаю тип содержимого моего внутреннего содержимого на любой тип файла, а затем устанавливаю тип содержимого моего внешнего содержимого на multipart / данные формы (добавив их к MultiPartFormData)

, поскольку я поддерживаю только ограниченное количество типов файлов, я смог написать простую функцию:

        private string GetFileType(string name)
        {
            char[] charSeparators = new char[] { '.' };
            var splitName = name.Split(charSeparators);
            string extension = splitName[1].ToLower();
            switch (extension)
            {
                case "pdf":
                    return "application/pdf";
                case "png":
                    return "image/png";
                case "doc":
                    return "application/msword";
                case "docx":
                    return "application/vnd.openxmlformats-officedocument.wordprocessingml.document";
                case "txt":
                    return "text/plain";
                case "tif":
                    return "image/tif";
                case "jpg":
                    return "image/jpg";
                case "rtf":
                    return "application/rtf";
                // default == not supported type, we don't set content type
                default:
                    return "";
            }
        }
0 голосов
/ 17 марта 2020

Я считаю, что вам нужно изменить способ использования MultipartFormDataContent ()

, это работает для меня

using (var content = new MultipartFormDataContent())
{
    content.Add(new StreamContent(stream)
    {
        Headers =
        {
            ContentLength = stream.Length,
            ContentType = new MediaTypeHeaderValue([your content type])
        }
    }, "[name ex: file]", "[file name ex: file.jpg]");
}
...