Как изменить Content-Type во Flurl?
У меня есть приложение.NET Core 2.0 WebApi, в которое я добавил пакет NuGet "Flurl.Http" (версия 2.1.0) в мой проект.
Я пытаюсь использовать Flurl, чтобы сделать простой вызов REST API для одной из конечных точек Api Visual Studio Team Services (VSTS).
Однако конкретная конечная точка API VSTS, которую я вызываю, требует, чтобы тип контента был установлен на "application/json-patch+json" вместо типичного "application/json".
В моем вызове Flurl я использую метод WithHeader(), чтобы попытаться установить Content-Type в заголовке запроса, но он не работает. Flurl, похоже, не позволяет мне переопределить стандартный или стандартный Content-Type, встроенный в метод PostJsonAsync.
Кто-нибудь знает, как изменить Content-Type запроса с помощью Flurl? Или как правильно переопределить поведение по умолчанию для Content-Type в конфигурации Flurl?
Заранее спасибо!
Мой код:
public bool CreateNewBug(NewBugRequest newBugRequest)
{
return _apiUrlToCreateNewBug.WithHeader("Authorization", "Basic Base64PersonalAccessTokenGoesHere")
.WithHeader("Content-Type", "application/json-patch+json")
.PostJsonAsync(newBugRequest.Fields)
.Result
.IsSuccessStatusCode;
}
(Этот код работает, но ответ от API VSTS заключается в том, что Content-Type недопустим и его необходимо изменить на "application/json-patch+json", что я и попытался установить в заголовке.)
3 ответа
ОБНОВЛЕНИЕ: ошибка исправлена с Flurl.Http 2.3.1, поэтому этот обходной путь больше не требуется.
Короткий ответ: я думаю, что вы обнаружили ошибку. PostJsonAsync
действительно устанавливает заголовок Content-Type, но я думаю, что он должен оставить его в покое, если вы уже установили его самостоятельно. Если бы вы могли сообщить об этом здесь, я бы смог исправить это в следующем выпуске.
Обходной путь довольно прост. Вам просто нужно сделать пару дополнительных шагов, чтобы создать контент, а затем опубликовать его, используя PostAsync
вместо PostJsonAsync
,
var json = FlurlHttp.GlobalSettings.JsonSerializer.Serialize(newBugRequest.Fields);
var content = new CapturedStringContent(json, Encoding.UTF8, "application/json-patch+json");
return _apiUrlToCreateNewBug
.WithHeader("Authorization", "Basic Base64PersonalAccessTokenGoesHere")
.PostAsync(content);
Если вам нужно сделать это много, вы можете заключить это в метод расширения (PostJsonPatchAsync
или аналогичный), так что вы можете назвать это свободно. Смотрите здесь для правильного способа сделать это.
Новый ответ: Обновление до последней версии Flurl.Http. Эта проблема была исправлена в 2.3.1, поэтому код, размещенный в вопросе (самый чистый подход), теперь должен работать так, как ожидалось.
Я смог понять это и найти рабочее решение моей проблемы.
Вот обновленная версия моего рабочего кода:
public HttpResponseMessage CreateNewBug(NewBugRequest newBugRequest)
{
return _apiUrlToCreateNewBug.AllowAnyHttpStatus()
.WithBasicAuth("", _personalAccessTokenForBasicAuth)
.PostAsync(new StringContent(JsonConvert.SerializeObject(newBugRequest.Fields), Encoding.UTF8, "application/json-patch+json"))
.Result;
}
Метод PostAsync принимает объект HttpContent. HttpContent - абстрактный класс. Как только я выяснил все конкретные классы, которые реализуют абстрактный класс HttpContent, я выбрал тот, который лучше всего подходит для моей ситуации, и подключил его к методу PostAsync.
В этом случае класс StringContent лучше всего подходил мне. Один из конструкторов StringContent принимает Content-Type в качестве одного из своих параметров. Так что я передал свой собственный Content-Type, и все заработало, как и ожидалось.