使用Httpclient的大型视频文件上传在Xamarin.Android上不起作用 [英] Large VIDEO File Upload using Httpclient does not work on Xamarin.Android

查看:144
本文介绍了使用Httpclient的大型视频文件上传在Xamarin.Android上不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

任何帮助或见识将不胜感激.

Any Help or insight would be much appreciated.

我设法获得的是该问题与HTTPS有关,因为在发布到HTTP端点时我能够收到200的回扣,类似于以下线程

What I have managed to obtain is that the issue is related to HTTPS as I am able to receive a 200 back when posting to an HTTP endpoint, similar to the following thread here

当前很难解决以下问题:

Currently having a difficult time trying to resolve the following issue:

我将AndroidClientHandler HttpClient实现以及NativeTLS 1.2+用于SSL/TLS实现

I'm using the AndroidClientHandler HttpClient implementation as well as the NativeTLS 1.2+ for the SSL/TLS Implementation

当我在自己的应用中录制了超过1分钟或超过20MB的视频时,出现以下错误: 无法访问已处置的对象.\ n对象名称: 'System.Net.Sockets.NetworkStream'."

When I record a Video on my app that is longer than 1 min, or larger than 20MB I receive the following error: "Cannot access a disposed object.\nObject name: 'System.Net.Sockets.NetworkStream'."

这是方法

    public async Task<HttpResponseMessage> UploadVideo(string endPoint)
    {
        HttpResponseMessage responseMessage = null;
        try
        {
            //Stopwatch stopWatch = new Stopwatch();

            IList<KeyValuePair<string, string>> formFields = new List<KeyValuePair<string, string>>();
            messageHandlerService = Mvx.Resolve<IMessageHandlerService>();

            //Declare a scope whereby you can use resources and once you leave the scope the resources are disposed of.
            using (StreamReader reader = pathService.GetStreamReaderByPlatform())
            {
                client = await MyHttpClient.GetClientAsync();
                client.Timeout = TimeSpan.FromSeconds(500);

                var bytes = default(byte[]);
                using (var memstream = new MemoryStream())
                {
                    reader.BaseStream.CopyTo(memstream);
                    bytes = memstream.ToArray();

                    using (var content = new MultipartFormDataContent())
                    {
                        var fileContent = new ByteArrayContent(bytes);
                        fileContent.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
                        {
                            FileName = ".mp4",
                        };
                        content.Add(fileContent);
                        content.Add(EncodeFields(formFields));

                        await Policy.Handle<TimeoutException>()
                          .Or<HttpRequestException>()
                          .Or<IOException>()
                          .OrResult<HttpResponseMessage>(r => httpStatusCodesToRetry.Contains(r.StatusCode))
                          .WaitAndRetryAsync
                          (retryCount: 3,
                           sleepDurationProvider: retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt)),
                           onRetry: (ex, time) =>
                           {
                               Debug.WriteLine($"Something went wrong: {ex.Exception.Message}, retrying...");
                           }).ExecuteAsync(async () =>
                        {
                            Debug.WriteLine($"Trying to fetch remote data...");
                            responseMessage = await client.PostAsync(endPoint, content);
                            return responseMessage;
                        });
                    }
                }
            }
        }
        catch (WebException webx)
        {

            if (responseMessage == null)
            {
                responseMessage = new HttpResponseMessage();
            }

            responseMessage.StatusCode = HttpStatusCode.InternalServerError;
            responseMessage.ReasonPhrase = string.Format("RestHttpClient.SendRequest failed: {0}", webx);
        }
        catch (Exception ex)
        {
            if (responseMessage == null)
            {
                responseMessage = new HttpResponseMessage();
            }

            responseMessage.StatusCode = HttpStatusCode.InternalServerError;
            responseMessage.ReasonPhrase = string.Format("RestHttpClient.SendRequest failed: {0}", ex);
        }

        return responseMessage;
    }


下面是堆栈跟踪:


Below is the Stack Trace:

"位于System.Net.WebConnectionStream.EndWrite(System.IAsyncResult r)[0x000b8],位于< 5a97d41d36694fb19855c17429527b10>:0 \ n,位于System.IO.Stream +<> c.b__53_1(System.IO.Stream流,System.IAsyncResult asyncResult)[0x00000]在(包装委托调用)System.Func 3[System.IO.Stream,System.IAsyncResult,System.Threading.Tasks.VoidTaskResult].invoke_TResult_T1_T2(System.IO.Stream,System.IAsyncResult)\n at System.Threading.Tasks.TaskFactory 1 + FromAsyncTrimPromise 1[TResult,TInstance].Complete (TInstance thisRef, System.Func 3 [T1,T2,TResult]上为0 \ n,endMethod,System.IAsyncResult asyncResult,System.布尔值requireSynchronization)在:0中的[0x00000] \ n ---从上一次引发异常的位置开始的堆栈跟踪--- \ n在System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()中在[0x0000c]在System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(System.Threading.Tasks.Task任务)[0x00028]上,位于System \\ Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(System.Threading.Tasks.Task任务)[0x0003e] ],位于System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd::0 \ n中(System.Threading.Tasks.Task任务)[0x00008]位于System.Runtime.Compi,位于:0 \ n lerServices.ConfiguredTaskAwaitable + ConfiguredTaskAwaiter.GetResult()[0x00000]在System.Net.Http.MultipartContent + d__8.MoveNext()在<996a681f30a44cd685a4da54e11956e2>:0的\ n中:: 0 \ n--堆栈跟踪结束从之前引发异常的位置开始--- \ n在System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(System.Threading.Tasks.Task System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(System.Threading.Tasks.Task task)中的[0x0003e] [0x0003e](System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd(System.Threading.Tasks.Task task)[0x00028] in:0 \ n .Threading.Tasks.Task任务)[0x00008]在System.Runtime.CompilerServices.ConfiguredTaskAwaitable + ConfiguredTaskAwaiter.GetResult()在:0 \ n在System.Net.Http.HttpClientHandler + d__64.MoveNext ()[0x0036e]在< 996a681f30a44cd685a4da54e11956e2>:0 \ n --- previ中的堆栈跟踪结束在System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()处抛出异常的位置--- \ n,在System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(System.Threading.Tasks.Task任务:0 \ n处为[0x0000c] )[0x0003e]在System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(System.Threading.Tasks.Task任务)的[0x00028]在[\ 0.n.System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd(System. Threading.Tasks.Task任务)[0x00008]在System.Runtime.CompilerServices.ConfiguredTaskAwaitable 1+ConfiguredTaskAwaiter[TResult].GetResult () [0x00000] in <f32579baafc1404fa37ba3ec1abdc0bd>:0 \n at System.Net.Http.HttpClient+<SendAsyncWorker>d__49.MoveNext () [0x000ca] in <996a681f30a44cd685a4da54e11956e2>:0 \n--- End of stack trace from previous location where exception was thrown ---\n at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x0000c] in <f32579baafc1404fa37ba3ec1abdc0bd>:0 \n at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (System.Threading.Tasks.Task task) [0x0003e] in <f32579baafc1404fa37ba3ec1abdc0bd>:0 \n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Threading.Tasks.Task task) [0x00028] in <f32579baafc1404fa37ba3ec1abdc0bd>:0 \n at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd (System.Threading.Tasks.Task task) [0x00008] in <f32579baafc1404fa37ba3ec1abdc0bd>:0 \n at System.Runtime.CompilerServices.TaskAwaiter 1处为:0 \ n …

" at System.Net.WebConnectionStream.EndWrite (System.IAsyncResult r) [0x000b8] in <5a97d41d36694fb19855c17429527b10>:0 \n at System.IO.Stream+<>c.b__53_1 (System.IO.Stream stream, System.IAsyncResult asyncResult) [0x00000] in :0 \n at (wrapper delegate-invoke) System.Func3[System.IO.Stream,System.IAsyncResult,System.Threading.Tasks.VoidTaskResult].invoke_TResult_T1_T2(System.IO.Stream,System.IAsyncResult)\n at System.Threading.Tasks.TaskFactory1+FromAsyncTrimPromise1[TResult,TInstance].Complete (TInstance thisRef, System.Func3[T1,T2,TResult] endMethod, System.IAsyncResult asyncResult, System.Boolean requiresSynchronization) [0x00000] in :0 \n--- End of stack trace from previous location where exception was thrown ---\n at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x0000c] in :0 \n at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (System.Threading.Tasks.Task task) [0x0003e] in :0 \n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Threading.Tasks.Task task) [0x00028] in :0 \n at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd (System.Threading.Tasks.Task task) [0x00008] in :0 \n at System.Runtime.CompilerServices.ConfiguredTaskAwaitable+ConfiguredTaskAwaiter.GetResult () [0x00000] in :0 \n at System.Net.Http.MultipartContent+d__8.MoveNext () [0x0025d] in <996a681f30a44cd685a4da54e11956e2>:0 \n--- End of stack trace from previous location where exception was thrown ---\n at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x0000c] in :0 \n at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (System.Threading.Tasks.Task task) [0x0003e] in :0 \n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Threading.Tasks.Task task) [0x00028] in :0 \n at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd (System.Threading.Tasks.Task task) [0x00008] in :0 \n at System.Runtime.CompilerServices.ConfiguredTaskAwaitable+ConfiguredTaskAwaiter.GetResult () [0x00000] in :0 \n at System.Net.Http.HttpClientHandler+d__64.MoveNext () [0x0036e] in <996a681f30a44cd685a4da54e11956e2>:0 \n--- End of stack trace from previous location where exception was thrown ---\n at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x0000c] in :0 \n at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (System.Threading.Tasks.Task task) [0x0003e] in :0 \n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Threading.Tasks.Task task) [0x00028] in :0 \n at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd (System.Threading.Tasks.Task task) [0x00008] in :0 \n at System.Runtime.CompilerServices.ConfiguredTaskAwaitable1+ConfiguredTaskAwaiter[TResult].GetResult () [0x00000] in <f32579baafc1404fa37ba3ec1abdc0bd>:0 \n at System.Net.Http.HttpClient+<SendAsyncWorker>d__49.MoveNext () [0x000ca] in <996a681f30a44cd685a4da54e11956e2>:0 \n--- End of stack trace from previous location where exception was thrown ---\n at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x0000c] in <f32579baafc1404fa37ba3ec1abdc0bd>:0 \n at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (System.Threading.Tasks.Task task) [0x0003e] in <f32579baafc1404fa37ba3ec1abdc0bd>:0 \n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Threading.Tasks.Task task) [0x00028] in <f32579baafc1404fa37ba3ec1abdc0bd>:0 \n at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd (System.Threading.Tasks.Task task) [0x00008] in <f32579baafc1404fa37ba3ec1abdc0bd>:0 \n at System.Runtime.CompilerServices.TaskAwaiter1 …

推荐答案

我已经通过在Xamarin.Android的项目构建设置"中设置一些标志来解决了该问题.

I have resolved the issue by setting some flags in the Project Build Settings within Xamarin.Android.

文档相反建议,通过设置以下配置,我可以使用HTTPS将文件发布到我的服务器上.在使用本机TLS 1.2+时,大于20MB的上传会崩溃...是的,我们的服务器支持TLS 1.2

Contrary to what the Docs suggest, setting the following configuration allows for me to POST the file to my server using HTTPS. While using the Native TLS 1.2+ crashes on uploads larger than 20MB...yes our server supports TLS 1.2

这篇关于使用Httpclient的大型视频文件上传在Xamarin.Android上不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆