System.Net.HttpClient를 사용하여 복잡한 형식을 게시하는 방법은 무엇입니까?
Web 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();
});
웹 API가 이해하는 방식으로 HttpContent 개체를 생성하려면 어떻게해야합니까?
원본 HttpRequestMessage<T>
이 제거되었습니다 . 이 :
new HttpRequestMessage<Widget>(widget)
것 이상 작동 전혀 없이도 .
대신 이 게시물 에서 ASP.NET 팀은 이 기능을 지원하기위한 몇 가지 새로운 호출 을 포함했습니다 .
HttpClient.PostAsJsonAsync<T>(T value) sends “application/json”
HttpClient.PostAsXmlAsync<T>(T value) sends “application/xml”
따라서 새 코드 ( from dunston )는 다음과 같습니다.
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();
});
참고 : ID를 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());
If you want the types of convenience methods mentioned in other answers but need portability (or even if you don't), you might want to check out Flurl [disclosure: I'm the author]. It (thinly) wraps HttpClient
and Json.NET and adds some fluent sugar and other goodies, including some baked-in testing helpers.
Post as JSON:
var resp = await "http://localhost:44268/api/test".PostJsonAsync(widget);
or URL-encoded:
var resp = await "http://localhost:44268/api/test".PostUrlEncodedAsync(widget);
Both examples above return an HttpResponseMessage
, but Flurl includes extension methods for returning other things if you just want to cut to the chase:
T poco = await url.PostJsonAsync(data).ReceiveJson<T>();
dynamic d = await url.PostUrlEncodedAsync(data).ReceiveJson();
string s = await url.PostUrlEncodedAsync(data).ReceiveString();
Flurl is available on NuGet:
PM> Install-Package Flurl.Http
After investigating lots of alternatives, I have come across another approach, suitable for the API 2.0 version.
(VB.NET is my favorite, 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
Good luck! For me this worked out (in the end!).
Regards, Peter
I think you can do this:
var client = new HttpClient();
HttpContent content = new Widget();
client.PostAsync<Widget>("http://localhost:44268/api/test", content, new FormUrlEncodedMediaTypeFormatter())
.ContinueWith((postTask) => { postTask.Result.EnsureSuccessStatusCode(); });
This is the code I wound up with, based upon the other answers here. This is for an HttpPost that receives and responds with complex types:
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));
In case someone like me didn't really understand what all above are talking about, I give an easy example which is working for me. If you have a web api which url is "http://somesite.com/verifyAddress", it is a post method and it need you to pass it an address object. You want to call this api in your code. Here what you can do.
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;
}
Make a service call like this:
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);
}
And Service method like this:
public HttpResponseMessage PutSaveActivationCode(ActivationCodes objAC)
{
}
PutAsJsonAsync takes care of Serialization and deserialization over the network
참고URL : https://stackoverflow.com/questions/10304863/how-to-use-system-net-httpclient-to-post-a-complex-type
'developer tip' 카테고리의 다른 글
Windows 7에서 WAMP 및 Skype 충돌을 해결하는 방법은 무엇입니까? (0) | 2020.08.17 |
---|---|
Node.js-현재 파일 이름 가져 오기 (0) | 2020.08.17 |
Mac OS X-EnvironmentError : mysql_config not found (0) | 2020.08.17 |
선언적으로 사용 가능한 화면 너비의 절반에 너비 할당 (0) | 2020.08.17 |
부분 문자열 형식 (0) | 2020.08.17 |