Java.Net.ProtocolException: 尝试将文件作为字节流上传时出现意外的流结尾

huangapple go评论68阅读模式
英文:

Java.Net.ProtocolException: unexpected end of stream when trying to upload file as a byte stream

问题

我有一个图像文件,我正在尝试使用http API将其上传到数据库。每次我尝试上传时,都会收到相同的错误:
[monodroid] 不捕获类型为 Java.Net.ProtocolException 的异常,来自方法“Read”。这将在将来的版本中更改。
意外的流末端

以下是我的代码:

使用了GT_MI.API;
using System;
using System.Collections.Generic;
using System.IO;
using System.Net.Http.Headers;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using System.Diagnostics;
using Newtonsoft.Json;

namespace ShorelogApp.API.Misc
{

    public class SaveSeas : ApiBase<RequestBase, SaveSeas.Response>
    {

        public class Response : ResponseBase
        {
            public string Path { get; set; }
            public string FileName { get; set; }
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="file">表示二进制编码文件的字节数组</param>
        /// <returns></returns>
        public async Task<Response> SaveFileAsync(byte[] file)
        {
            HttpResponseMessage httpResponseMessage = null;

            try
            {
                // 构造具有 16 秒超时的 HttpClient 和 Uri
                var httpClient = new HttpClient()
                {

                    Timeout = TimeSpan.FromSeconds(16)
                };

                var uri = new Uri($"{ApiManager.BaseUrl}/seas/save_seas");
                Debug.WriteLine($"URL: {uri.AbsoluteUri}");

                if (string.IsNullOrEmpty(ApiManager.Token) == false)
                {
                    Debug.WriteLine($"[Token]: {ApiManager.Token}");
                    httpClient.DefaultRequestHeaders.Add("token", ApiManager.Token);
                }
                
                // 使用字节数组内容类型
                ByteArrayContent content = new ByteArrayContent(file);
                content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream"); //"application/octet-stream"
                content.Headers.ContentLength = file.Length;
                httpResponseMessage = await httpClient.PostAsync(uri, content);
                
                httpResponseMessage.EnsureSuccessStatusCode();
                var httpResponseBody = await httpResponseMessage.Content.ReadAsStringAsync();
                Debug.WriteLine($"Response Data: {httpResponseBody}");

                var resultJson = JsonConvert.DeserializeObject<Response>(httpResponseBody, jsonSerializerSettings);

                Debug.WriteLine($"Response Json:\n{JsonConvert.SerializeObject(resultJson, Formatting.Indented)}");

                return resultJson;
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                return HandleException(httpResponseMessage, ex);
            }
        }
    }
}

我尝试添加了一个包含文件大小的内容头,因为我读到有时候这个错误是由于后端将请求体识别为错误大小而引起的,但这没有起作用。我尝试在上传之前压缩文件,因为我认为它可能太大了,但这也没有起作用。我尝试将文件作为字符串通过 JSON 上传,也尝试将其作为 ByteArrayContent 类型上传,但我始终收到相同的错误。
英文:

I have an image file that I am trying to upload to a database using a http API. every time I try uploading I get the same error:

[monodroid] Not wrapping exception of type Java.Net.ProtocolException from method `Read`. This will change in a future release.
unexpected end of stream

Here is my code

using GT_MI.API;
using System;
using System.Collections.Generic;
using System.IO;
using System.Net.Http.Headers;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using System.Diagnostics;
using Newtonsoft.Json;

namespace ShorelogApp.API.Misc
{

    public class SaveSeas : ApiBase<RequestBase, SaveSeas.Response>
    {

        public class Response : ResponseBase
        {
            public string Path { get; set; }
            public string FileName { get; set; }
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="file">Byte array representing binary encoded file</param>
        /// <returns></returns>
        public async Task<Response> SaveFileAsync(byte[] file)
        {
            HttpResponseMessage httpResponseMessage = null;

            try
            {
                // Construct the HttpClient and Uri, with a timeout of 16 seconds
                var httpClient = new HttpClient()
                {

                    Timeout = TimeSpan.FromSeconds(16)
                };

                var uri = new Uri($"{ApiManager.BaseUrl}/seas/save_seas");
                Debug.WriteLine($"URL: {uri.AbsoluteUri}");

                if (string.IsNullOrEmpty(ApiManager.Token) == false)
                {
                    Debug.WriteLine($"[Token]: {ApiManager.Token}");
                    httpClient.DefaultRequestHeaders.Add("token", ApiManager.Token);
                }
                
                // using byte array content type
                ByteArrayContent content = new ByteArrayContent(file);
                content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream"); //"application/octet-stream"
                content.Headers.ContentLength = file.Length;
                httpResponseMessage = await httpClient.PostAsync(uri, content);
                
                
                httpResponseMessage.EnsureSuccessStatusCode();
                var httpResponseBody = await httpResponseMessage.Content.ReadAsStringAsync();
                Debug.WriteLine($"Response Data: {httpResponseBody}");

                var resultJson = JsonConvert.DeserializeObject<Response>(httpResponseBody, jsonSerializerSettings);

                Debug.WriteLine($"Response Json:\n{JsonConvert.SerializeObject(resultJson, Formatting.Indented)}");

                return resultJson;
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                return HandleException(httpResponseMessage, ex);
            }
        }
    }
}

I have tried adding a content header with the size of the file, as I read that sometimes this error is caused by the request body being recognised as the wrong size on the backend, but it didn't work
I tried compressing the file before uploading it, as I thought it might just be too big, but that didn't work.
I tried uploading the file as a string through JSON and uploading it as a ByteArrayContent type, but I always get the same error.

答案1

得分: 0

I got it working, by changing the httpContent type to a MultipartFormDataContent it worked, so the request now looks like:

MultipartFormDataContent content = new MultipartFormDataContent();

ByteArrayContent fileContent = new ByteArrayContent(file);
fileContent.Headers.ContentType = new MediaTypeHeaderValue("image/png");
content.Add(fileContent, "file");
//ByteArrayContent content = new ByteArrayContent(file);

httpResponseMessage = await httpClient.PostAsync(uri, content);

This gets past the end of stream error.

英文:

I got it working, by changing the httpContent type to a MultipartFormDataContent it worked, so the request now looks like

                MultipartFormDataContent content = new MultipartFormDataContent();

                ByteArrayContent fileContent = new ByteArrayContent(file);
                fileContent.Headers.ContentType = new MediaTypeHeaderValue("image/png");
                content.Add(fileContent, "file");
                //ByteArrayContent content = new ByteArrayContent(file);

                httpResponseMessage = await httpClient.PostAsync(uri, content);

This gets past the end of stream error.

huangapple
  • 本文由 发表于 2023年2月26日 20:22:02
  • 转载请务必保留本文链接:https://go.coder-hub.com/75571941.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定