Как использовать System.Net. HttpClient для публикации сложного типа?
у меня есть пользовательский сложный тип, с которым я хочу работать с помощью веб-API.
public class Widget
{
public int ID { get; set; }
public string Name { get; set; }
public decimal Price { get; set; }
}
и вот мой метод контроллера веб-API. Я хочу разместить этот объект так:
public class TestController : ApiController
{
// POST /api/test
public HttpResponseMessage<Widget> Post(Widget widget)
{
widget.ID = 1; // hardcoded for now. TODO: Save to db and return newly created ID
var response = new HttpResponseMessage<Widget>(widget, HttpStatusCode.Created);
response.Headers.Location = new Uri(Request.RequestUri, "/api/test/" + widget.ID.ToString());
return response;
}
}
и теперь я хотел бы использовать System.Net.HttpClient, чтобы сделать вызов метода. Однако я не уверен, какой тип объекта передать в метод PostAsync и как его построить. Вот пример клиентского кода.
var client = new HttpClient();
HttpContent content = new StringContent("???"); // how do I construct the Widget to post?
client.PostAsync("http://localhost:44268/api/test", content).ContinueWith(
(postTask) =>
{
postTask.Result.EnsureSuccessStatusCode();
});
как создать объект HttpContent в a как веб-API это поймет?
9 ответов:
универсальный
HttpRequestMessage<T>была удалены. Это:new HttpRequestMessage<Widget>(widget)будет не работают.
вместо эту статью, ASP.NET команда включила некоторые новые вызовы для поддержки этой функции:
HttpClient.PostAsJsonAsync<T>(T value) sends “application/json” HttpClient.PostAsXmlAsync<T>(T value) sends “application/xml”Итак, новый код (от данстона) приобретает следующий вид:
Widget widget = new Widget() widget.Name = "test" widget.Price = 1; HttpClient client = new HttpClient(); client.BaseAddress = new Uri("http://localhost:44268"); client.PostAsJsonAsync("api/test", widget) .ContinueWith((postTask) => postTask.Result.EnsureSuccessStatusCode() );
вы должны использовать
SendAsyncметод вместо этого, это универсальный метод, который сериализует вход в службуWidget widget = new Widget() widget.Name = "test" widget.Price = 1; HttpClient client = new HttpClient(); client.BaseAddress = new Uri("http://localhost:44268/api/test"); client.SendAsync(new HttpRequestMessage<Widget>(widget)) .ContinueWith((postTask) => postTask.Result.EnsureSuccessStatusCode() );если вы не хотите создавать конкретный класс, вы можете сделать это с помощью
FormUrlEncodedContentклассvar client = new HttpClient(); // This is the postdata var postData = new List<KeyValuePair<string, string>>(); postData.Add(new KeyValuePair<string, string>("Name", "test")); postData.Add(new KeyValuePair<string, string>("Price ", "100")); HttpContent content = new FormUrlEncodedContent(postData); client.PostAsync("http://localhost:44268/api/test", content).ContinueWith( (postTask) => { postTask.Result.EnsureSuccessStatusCode(); });Примечание: вам нужно сделать свой идентификатор для nullable int (
int?)
обратите внимание, что если вы используете портативную библиотеку классов, HttpClient не будет иметь метод PostAsJsonAsync. Чтобы опубликовать содержимое как JSON с помощью портативной библиотеки классов, вам нужно будет сделать следующее:
HttpClient client = new HttpClient(); HttpContent contentPost = new StringContent(argsAsJson, Encoding.UTF8, "application/json"); await client.PostAsync(new Uri(wsUrl), contentPost).ContinueWith( (postTask) => postTask.Result.EnsureSuccessStatusCode());
если вы хотите, чтобы типы методов удобства упоминались в других ответах, но нуждались в переносимости (или даже если вы этого не делаете), вы можете проверить Flurl [раскрытие: я-автор]. Он (тонко) обертывает
HttpClientи Json.NET и добавляет немного свободного сахара и других вкусностей, в том числе некоторые запеченные тестирование помощников.сообщение как JSON:
var resp = await "http://localhost:44268/api/test".PostJsonAsync(widget);или URL-адреса:
var resp = await "http://localhost:44268/api/test".PostUrlEncodedAsync(widget);оба примера выше вернуть
HttpResponseMessage, но Flurl включает методы расширения для возврата других вещей, если вы просто хотите сократить погоню:T poco = await url.PostJsonAsync(data).ReceiveJson<T>(); dynamic d = await url.PostUrlEncodedAsync(data).ReceiveJson(); string s = await url.PostUrlEncodedAsync(data).ReceiveString();Flurl доступен на NuGet:
PM> Install-Package Flurl.Http
изучив множество альтернатив, я столкнулся с другим подходом, подходящим для версии API 2.0.
(VB.NET это мой любимый, ооочень...)
Public Async Function APIPut_Response(ID as Integer, MyWidget as Widget) as Task(Of HttpResponseMessage) Dim DesiredContent as HttpContent = New StringContent(JsonConvert.SerializeObject(MyWidget)) Return Await APIClient.PutAsync(String.Format("api/widget/{0}", ID), DesiredContent) End Functionудачи! Для меня это сработало (в конце концов!).
С уважением, Питер
Я думаю, что вы можете сделать это:
var client = new HttpClient(); HttpContent content = new Widget(); client.PostAsync<Widget>("http://localhost:44268/api/test", content, new FormUrlEncodedMediaTypeFormatter()) .ContinueWith((postTask) => { postTask.Result.EnsureSuccessStatusCode(); });
Это код, который я получил, основываясь на других ответах здесь. Это для HttpPost, который получает и отвечает сложными типами:
Task<HttpResponseMessage> response = httpClient.PostAsJsonAsync( strMyHttpPostURL, new MyComplexObject { Param1 = param1, Param2 = param2}).ContinueWith((postTask) => postTask.Result.EnsureSuccessStatusCode()); //debug: //String s = response.Result.Content.ReadAsStringAsync().Result; MyOtherComplexType moct = (MyOtherComplexType)JsonConvert.DeserializeObject(response.Result.Content.ReadAsStringAsync().Result, typeof(MyOtherComplexType));
в случае, если кто-то вроде меня действительно не понимает, о чем все выше говорят, Я даю простой пример, который работает для меня. Если у вас есть веб-api, url-адрес которого"http://somesite.com/verifyAddress", это метод post, и вам нужно передать ему объект адреса. Вы хотите вызвать этот api в своем коде. Вот что вы можете сделать.
public Address verifyAddress(Address address) { this.client = new HttpClient(); client.BaseAddress = new Uri("http://somesite.com/"); client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); var urlParm = URL + "verifyAddress"; response = client.PostAsJsonAsync(urlParm,address).Result; var dataObjects = response.IsSuccessStatusCode ? response.Content.ReadAsAsync<Address>().Result : null; return dataObjects; }
сделать вызов службы, как это:
public async void SaveActivationCode(ActivationCodes objAC) { var client = new HttpClient(); client.BaseAddress = new Uri(baseAddress); HttpResponseMessage response = await client.PutAsJsonAsync(serviceAddress + "/SaveActivationCode" + "?apiKey=445-65-1216", objAC); }и метод обслуживания, как это:
public HttpResponseMessage PutSaveActivationCode(ActivationCodes objAC) { }PutAsJsonAsync заботится о сериализации и десериализации по сети
Comments