【问题标题】:Invalid HttpStatusCode无效的 HttpStatusCode
【发布时间】:2017-06-09 12:26:03
【问题描述】:

我们正在使用外部 rest API (Vimeo) 将视频从手机上传到服务器。执行此操作的步骤之一是检查已上传了多少字节。为此,应在带有标头的特定 URL 上执行 PUT 请求:
- 授权持有人 d4559ba...
- 内容范围字节 */*

来自 API 的响应是:
- 200 OK - 如果上传完成
- 308 Resume Incomplete - 带有 Range 标头(例如 Range bytes=0-1000),提供已上传多少字节的信息

问题是 Xamarin 中的枚举 HttpStatusCode (https://developer.xamarin.com/api/type/System.Net.HttpStatusCode/) 不包含值 308,因此在调用 client.PutAsync 期间抛出异常: {System.Net.WebException:无效状态代码:308 ---> System.Net.ProtocolViolationException:无效状态代码:308 在 System.Net.HttpWebRequest.Redirect ... }

知道如何解决这个错误吗?这是我们正在使用的 C# 代码:

        var client = new HttpClient(new NativeMessageHandler() { AutomaticDecompression = DecompressionMethods.Deflate });
        var uri = new Uri(url);

        client.DefaultRequestHeaders.Add("Authorization", string.Format("Bearer {0}", Constants.VimeoToken));

        var stringContent = new StringContent("");
        stringContent.Headers.Add("Content-Range", "bytes */*");

        var httpResponse = await client.PutAsync(uri, stringContent);
        return httpResponse;

编辑: 我尝试将 DelegatingHandler 与此代码一起使用:

    public class MyDelegatingHandler : DelegatingHandler
    {
        public MyDelegatingHandler(HttpMessageHandler innerHandler) : base(innerHandler) { }
        protected async override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
        {
            var response = await base.SendAsync(request, cancellationToken);
            if (!response.IsSuccessStatusCode && response.StatusCode == (HttpStatusCode)308) //This line of code is never reached
            {
            }
            return response;
        }
    }
    var client = new HttpClient(new MyDelegatingHandler(new NativeMessageHandler() { AutomaticDecompression = DecompressionMethods.Deflate }));
    HttpRequestMessage message = new HttpRequestMessage(HttpMethod.Put, url);
    var stringContent = new StringContent("");
    stringContent.Headers.Add("Content-Range", "bytes */*");
    message.Content = stringContent;
    CancellationToken cancellationToken = new CancellationToken();
    var response = await client.SendAsync(message, cancellationToken);

问题是 base.SendAsync 抛出异常并且没有到达下一行代码(if 语句)。我应该以其他方式使用委托处理程序吗?

编辑:我尝试在此代码中使用 RestSharp:

        RestClient client = new RestClient(url);
        var request = new RestRequest("", Method.PUT);
        request.AddHeader("Authorization", string.Format("Bearer {0}", Constants.VimeoToken));
        request.AddHeader("Content-Range", "bytes */*");
        var response = await client.Execute(request);

通过此请求,我收到错误的状态代码,这意味着请求未正确创建。也许 Content-Range 标头未正确添加,Vimeo 服务器无法读取它。还有其他方法可以添加此标头吗?

【问题讨论】:

  • 创建一个 DelegatingHandler 并将其与客户端一起使用,以便在不崩溃的情况下处理 308 状态代码..
  • 你用的是什么原生的NativeMessageHandler?我对使用HttpClient 和本机NSUrlSessionAndroidClientHandler 设置为HttpClient 实现的308s 没有任何问题...
  • NativeMessageHandler 是 ModernHttpClient 的一部分,它在 Android 上使用 OkHttp,在 iOS 上使用 NSURLSession 或 AFNetworking。如果我更改消息处理程序,它仍将使用不包含 308 的 HttpStatusCode。
  • @Nkosi:我尝试使用 DelegatingHandler,但我不知道如何正确处理 308 状态代码而不会炸毁。你能分享一些代码吗?

标签: c# xamarin xamarin.forms vimeo-api http-status-code-308


【解决方案1】:

您可以将try - catch' 放在PutAsync 周围并检查状态码。如果是 308 处理这种情况。

【讨论】:

  • 我试过了,但在那种情况下,我不知道如何读取包含 Range 标头和已上传字节数的响应。
  • 可能是的。你能推荐一下吗?
  • 我尝试使用 RestSharp。请查看已编辑的问题。
【解决方案2】:

如果您使用 HttpWebRequest,您可以将 HttpWebRequest.AllowAutoRedirect 设置为 false 以避免此异常。我还没有尝试过 HttpClient.AllowAutoRedirect 但它可能会起作用。

如果您使用的是 PCL 库,则需要使用反射或依赖注入来访问该属性。

【讨论】:

    猜你喜欢
    • 2020-02-12
    • 1970-01-01
    • 1970-01-01
    • 2020-02-07
    • 1970-01-01
    • 1970-01-01
    • 2013-10-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多