Неверный HttpStatusCode
Мы используем внешний API отдыха (Vimeo) для загрузки видео с телефона на сервер. Одним из шагов при выполнении этой операции является проверка количества загруженных байтов. Для этого необходимо выполнить запрос PUT на определенный URL с заголовками:
- Авторизация на предъявителя d4559ba...
- Контент-байты */*
Ответ от API:
- 200 Ok - если загрузка завершена
- 308 Resume Incomplete - с заголовком Range (например, Range bytes=0-1000), дающим информацию о том, сколько байт было загружено
Проблема в том, что перечисление HttpStatusCode ( https://developer.xamarin.com/api/type/System.Net.HttpStatusCode/) в Xamarin не содержит значение 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);
Проблема является базовой.SendAsync генерирует исключение, и следующая строка кода (если оператор) не достигнута. Должен ли я использовать делегирующий обработчик другим способом?
Изменить: я пытался использовать 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 не может его прочитать. Есть ли другой способ добавить этот заголовок?
2 ответа
Вы можете положить try - catch
' вокруг PutAsync
это и проверить код состояния. Если это 308 обрабатывать этот случай.
Если вы используете HttpWebRequest, вы можете установить для HttpWebRequest.AllowAutoRedirect значение false, чтобы избежать этого исключения. Я не пробовал HttpClient.AllowAutoRedirect, но он может работать.
Если вы используете библиотеку PCL, вам нужно использовать отражение или внедрение зависимости, чтобы получить доступ к свойству.