Jak używać System. Net. HttpClient do publikowania złożonego typu?
Mam niestandardowy typ złożony, z którym chcę pracować przy użyciu Web API.
public class Widget
{
public int ID { get; set; }
public string Name { get; set; }
public decimal Price { get; set; }
}
A oto moja metoda kontrolera web API. Chcę opublikować ten obiekt w ten sposób:
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;
}
}
A teraz chciałbym użyć System. Net. HttpClient, aby wywołać metodę. Nie jestem jednak pewien, jakiego typu obiekt przekazać do metody PostAsync i jak go skonstruować. Oto przykładowy kod klienta.
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();
});
Jak utworzyć obiekt HttpContent w taki sposób, aby web API rozumiesz?
9 answers
Ogólny HttpRequestMessage<T>
został usunięty. To:
new HttpRequestMessage<Widget>(widget)
Nie będzie już działać .
Zamiast z tego postu , ASP.NET zespół dodał kilka nowych połączeń do obsługi tej funkcjonalności:
HttpClient.PostAsJsonAsync<T>(T value) sends “application/json”
HttpClient.PostAsXmlAsync<T>(T value) sends “application/xml”
Tak więc nowy kod (z dunston ) staje się:
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() );
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:34:53
Powinieneś zamiast tego użyć metody SendAsync
, jest to metoda ogólna, która serializuje dane wejściowe do usługi
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() );
Jeśli nie chcesz tworzyć klasy concrete, możesz to zrobić za pomocą klasy 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();
});
Uwaga: musisz dodać id do nullable int (int?
)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-10-28 11:05:12
Zauważ, że jeśli używasz przenośnej biblioteki klas, HttpClient nie będzie miał metody PostAsJsonAsync. Aby opublikować zawartość jako JSON za pomocą przenośnej biblioteki klas, musisz to zrobić:
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());
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-04-15 22:21:25
Jeśli chcesz typów metod wygody wymienionych w innych odpowiedziach, ale potrzebujesz przenośności (a nawet jeśli nie), możesz sprawdzić Flurl [disclosure: jestem autorem]. To (cienko) owija HttpClient
i Json.NET i dodaje trochę płynnego cukru i innych smakołyków, w tym kilka pieczonych pomocników testujących.
Post jako JSON:
var resp = await "http://localhost:44268/api/test".PostJsonAsync(widget);
Lub zakodowany URL:
var resp = await "http://localhost:44268/api/test".PostUrlEncodedAsync(widget);
Oba powyższe przykłady zwracają HttpResponseMessage
, ale Flurl zawiera metody rozszerzenia dla zwracanie innych rzeczy, jeśli tylko chcesz przejść do sedna:
T poco = await url.PostJsonAsync(data).ReceiveJson<T>();
dynamic d = await url.PostUrlEncodedAsync(data).ReceiveJson();
string s = await url.PostUrlEncodedAsync(data).ReceiveString();
Flurl jest dostępny na NuGet:
PM> Install-Package Flurl.Http
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-06-19 14:23:36
Po zbadaniu wielu alternatyw, natknąłem się na inne podejście, odpowiednie dla wersji API 2.0.
(VB.NET to moje ulubione, sooo...)
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
Powodzenia! Dla mnie to się udało (w końcu!).
Pozdrawiam, Piotr
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-08-10 18:27:34
Myślę, że możesz to zrobić:
var client = new HttpClient();
HttpContent content = new Widget();
client.PostAsync<Widget>("http://localhost:44268/api/test", content, new FormUrlEncodedMediaTypeFormatter())
.ContinueWith((postTask) => { postTask.Result.EnsureSuccessStatusCode(); });
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-03-27 12:38:36
Oto kod, z którym skończyłem, oparty na innych odpowiedziach tutaj. Jest to dla HttpPost, który odbiera i odpowiada złożonymi typami:
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));
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-01-26 14:56:41
Na wypadek, gdyby ktoś taki jak ja nie do końca rozumiał, o czym wszyscy wyżej mówią, podaję prosty przykład, który działa dla mnie. Jeśli masz web api którego url jest " http://somesite.com/verifyAddress", jest to metoda post i wymaga podania obiektu adresu. Chcesz wywołać ten api w swoim kodzie. Tutaj, co możesz zrobić.
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;
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-10-24 19:36:35
Wykonaj połączenie serwisowe w ten sposób:
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);
}
I metoda serwisowa taka:
public HttpResponseMessage PutSaveActivationCode(ActivationCodes objAC)
{
}
PutAsJsonAsync zajmuje się Serializacją i deserializacją przez sieć
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-01-14 22:25:51