C#을 사용하여 REST API로 통화하려면 어떻게 해야 합니까?
제가 지금까지 가지고 있는 코드는 다음과 같습니다.
public class Class1
{
private const string URL = "https://sub.domain.com/objects.json?api_key=123";
private const string DATA = @"{""object"":{""name"":""Name""}}";
static void Main(string[] args)
{
Class1.CreateObject();
}
private static void CreateObject()
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(URL);
request.Method = "POST";
request.ContentType = "application/json";
request.ContentLength = DATA.Length;
StreamWriter requestWriter = new StreamWriter(request.GetRequestStream(), System.Text.Encoding.ASCII);
requestWriter.Write(DATA);
requestWriter.Close();
try {
WebResponse webResponse = request.GetResponse();
Stream webStream = webResponse.GetResponseStream();
StreamReader responseReader = new StreamReader(webStream);
string response = responseReader.ReadToEnd();
Console.Out.WriteLine(response);
responseReader.Close();
} catch (Exception e) {
Console.Out.WriteLine("-----------------");
Console.Out.WriteLine(e.Message);
}
}
}
문제는 예외 블록이 트리거되고 있다고 생각한다는 것입니다(Try-catch를 제거하면 서버 오류(500) 메시지가 표시되기 때문입니다).콘솔이 보이지 않습니다.아웃라인은 캐치 블록에 넣었습니다.
내 콘솔:
The thread 'vshost.NotifyLoad' (0x1a20) has exited with code 0 (0x0).
The thread '<No Name>' (0x1988) has exited with code 0 (0x0).
The thread 'vshost.LoadReference' (0x1710) has exited with code 0 (0x0).
'ConsoleApplication1.vshost.exe' (Managed (v4.0.30319)): Loaded 'c:\users\l. preston sego iii\documents\visual studio 11\Projects\ConsoleApplication1\ConsoleApplication1\bin\Debug\ConsoleApplication1.exe', Symbols loaded.
'ConsoleApplication1.vshost.exe' (Managed (v4.0.30319)): Loaded 'C:\Windows\Microsoft.Net\assembly\GAC_MSIL\System.Configuration\v4.0_4.0.0.0__b03f5f7f11d50a3a\System.Configuration.dll', Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
A first chance exception of type 'System.Net.WebException' occurred in System.dll
The thread 'vshost.RunParkingWindow' (0x184c) has exited with code 0 (0x0).
The thread '<No Name>' (0x1810) has exited with code 0 (0x0).
The program '[2780] ConsoleApplication1.vshost.exe: Program Trace' has exited with code 0 (0x0).
The program '[2780] ConsoleApplication1.vshost.exe: Managed (v4.0.30319)' has exited with code 0 (0x0).
ASP.NET 웹 API는 앞에서 언급한 WCF 웹 API를 대체했습니다.
이러한 응답이 대부분 2012년 초의 것이기 때문에 업데이트된 답변을 올리려고 생각했는데, 이 스레드는 구글에서 "call restful service C#"을 검색할 때 상위 결과 중 하나입니다.
Microsoft의 현재 지침은 Microsoft ASP.NET Web API Client Libraries를 사용하여 RESTful 서비스를 사용하는 것입니다.이것은 Microsoft의 NuGet 패키지로 제공됩니다.AsNet.WebApi.클라이언트. 이 NuGet 패키지를 솔루션에 추가해야 합니다.
다음은 ASP.NET Web API 클라이언트 라이브러리를 사용하여 구현할 때의 예제입니다.
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Net.Http.Headers;
namespace ConsoleProgram
{
public class DataObject
{
public string Name { get; set; }
}
public class Class1
{
private const string URL = "https://sub.domain.com/objects.json";
private string urlParameters = "?api_key=123";
static void Main(string[] args)
{
HttpClient client = new HttpClient();
client.BaseAddress = new Uri(URL);
// Add an Accept header for JSON format.
client.DefaultRequestHeaders.Accept.Add(
new MediaTypeWithQualityHeaderValue("application/json"));
// List data response.
HttpResponseMessage response = client.GetAsync(urlParameters).Result; // Blocking call! Program will wait here until a response is received or a timeout occurs.
if (response.IsSuccessStatusCode)
{
// Parse the response body.
var dataObjects = response.Content.ReadAsAsync<IEnumerable<DataObject>>().Result; //Make sure to add a reference to System.Net.Http.Formatting.dll
foreach (var d in dataObjects)
{
Console.WriteLine("{0}", d.Name);
}
}
else
{
Console.WriteLine("{0} ({1})", (int)response.StatusCode, response.ReasonPhrase);
}
// Make any other calls using HttpClient here.
// Dispose once all HttpClient calls are complete. This is not necessary if the containing object will be disposed of; for example in this case the HttpClient instance will be disposed automatically when the application terminates so the following call is superfluous.
client.Dispose();
}
}
}
여러 번 요청할 경우 HttpClient 인스턴스를 다시 사용해야 합니다.이 경우 HttpClient 인스턴스에서 사용 문이 사용되지 않은 이유에 대한 자세한 내용은 다음 질문과 답변을 참조하십시오.요청 사이에 HttpClient와 HttpClientHandler를 배치해야 합니까?
다른 예를 포함한 자세한 내용은 .NET 클라이언트에서 웹 API 호출(C#)을 참조하십시오.
이 블로그 게시물도 유용할 수 있습니다: HttpClient를 사용하여 ASP.NET 웹 API REST 서비스 사용
제 제안은 RestSharp를 사용하는 것입니다.REST 서비스에 전화를 걸고 응답을 구문 분석하기 위해 보일러 플레이트 코드가 거의 없는 POCO 개체에 캐스트하도록 할 수 있습니다.이렇게 하면 특정 오류가 해결되지는 않지만 REST 서비스에 전화를 거는 방법에 대한 전반적인 질문에 답할 수 있습니다.코드를 사용하기 위해 코드를 변경해야 하는 경우 사용 편의성과 견고성이 향상될 것입니다.하지만 그것은 내 2센트에 불과합니다.
예:
namespace RestSharpThingy
{
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Reflection;
using RestSharp;
public static class Program
{
public static void Main()
{
Uri baseUrl = new Uri("https://httpbin.org/");
IRestClient client = new RestClient(baseUrl);
IRestRequest request = new RestRequest("get", Method.GET) { Credentials = new NetworkCredential("testUser", "P455w0rd") };
request.AddHeader("Authorization", "Bearer qaPmk9Vw8o7r7UOiX-3b-8Z_6r3w0Iu2pecwJ3x7CngjPp2fN3c61Q_5VU3y0rc-vPpkTKuaOI2eRs3bMyA5ucKKzY1thMFoM0wjnReEYeMGyq3JfZ-OIko1if3NmIj79ZSpNotLL2734ts2jGBjw8-uUgKet7jQAaq-qf5aIDwzUo0bnGosEj_UkFxiJKXPPlF2L4iNJSlBqRYrhw08RK1SzB4tf18Airb80WVy1Kewx2NGq5zCC-SCzvJW-mlOtjIDBAQ5intqaRkwRaSyjJ_MagxJF_CLc4BNUYC3hC2ejQDoTE6HYMWMcg0mbyWghMFpOw3gqyfAGjr6LPJcIly__aJ5__iyt-BTkOnMpDAZLTjzx4qDHMPWeND-TlzKWXjVb5yMv5Q6Jg6UmETWbuxyTdvGTJFzanUg1HWzPr7gSs6GLEv9VDTMiC8a5sNcGyLcHBIJo8mErrZrIssHvbT8ZUPWtyJaujKvdgazqsrad9CO3iRsZWQJ3lpvdQwucCsyjoRVoj_mXYhz3JK3wfOjLff16Gy1NLbj4gmOhBBRb8rJnUXnP7rBHs00FAk59BIpKLIPIyMgYBApDCut8V55AgXtGs4MgFFiJKbuaKxq8cdMYEVBTzDJ-S1IR5d6eiTGusD5aFlUkAs9NV_nFw");
request.AddParameter("clientId", 123);
IRestResponse<RootObject> response = client.Execute<RootObject>(request);
if (response.IsSuccessful)
{
response.Data.Write();
}
else
{
Console.WriteLine(response.ErrorMessage);
}
Console.WriteLine();
string path = Assembly.GetExecutingAssembly().Location;
string name = Path.GetFileName(path);
request = new RestRequest("post", Method.POST);
request.AddFile(name, File.ReadAllBytes(path), name, "application/octet-stream");
response = client.Execute<RootObject>(request);
if (response.IsSuccessful)
{
response.Data.Write();
}
else
{
Console.WriteLine(response.ErrorMessage);
}
Console.ReadLine();
}
private static void Write(this RootObject rootObject)
{
Console.WriteLine("clientId: " + rootObject.args.clientId);
Console.WriteLine("Accept: " + rootObject.headers.Accept);
Console.WriteLine("AcceptEncoding: " + rootObject.headers.AcceptEncoding);
Console.WriteLine("AcceptLanguage: " + rootObject.headers.AcceptLanguage);
Console.WriteLine("Authorization: " + rootObject.headers.Authorization);
Console.WriteLine("Connection: " + rootObject.headers.Connection);
Console.WriteLine("Dnt: " + rootObject.headers.Dnt);
Console.WriteLine("Host: " + rootObject.headers.Host);
Console.WriteLine("Origin: " + rootObject.headers.Origin);
Console.WriteLine("Referer: " + rootObject.headers.Referer);
Console.WriteLine("UserAgent: " + rootObject.headers.UserAgent);
Console.WriteLine("origin: " + rootObject.origin);
Console.WriteLine("url: " + rootObject.url);
Console.WriteLine("data: " + rootObject.data);
Console.WriteLine("files: ");
foreach (KeyValuePair<string, string> kvp in rootObject.files ?? Enumerable.Empty<KeyValuePair<string, string>>())
{
Console.WriteLine("\t" + kvp.Key + ": " + kvp.Value);
}
}
}
public class Args
{
public string ClientId { get; set; }
}
public class Headers
{
public string Accept { get; set; }
public string AcceptEncoding { get; set; }
public string AcceptLanguage { get; set; }
public string Authorization { get; set; }
public string Connection { get; set; }
public string Dnt { get; set; }
public string Host { get; set; }
public string Origin { get; set; }
public string Referer { get; set; }
public string UserAgent { get; set; }
}
public class RootObject
{
public Args args { get; set; }
public Headers Headers { get; set; }
public string Origin { get; set; }
public string Url { get; set; }
public string Data { get; set; }
public Dictionary<string, string> Files { get; set; }
}
}
관련이 없습니다, 저는 확신합니다, 하지만 당신의 것을 포장하세요.IDisposable
에 있는 .using
적절한 폐기를 보장하기 위한 블록:
using System;
using System.Net;
using System.IO;
namespace ConsoleProgram
{
public class Class1
{
private const string URL = "https://sub.domain.com/objects.json?api_key=123";
private const string DATA = @"{""object"":{""name"":""Name""}}";
static void Main(string[] args)
{
Class1.CreateObject();
}
private static void CreateObject()
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(URL);
request.Method = "POST";
request.ContentType = "application/json";
request.ContentLength = DATA.Length;
using (Stream webStream = request.GetRequestStream())
using (StreamWriter requestWriter = new StreamWriter(webStream, System.Text.Encoding.ASCII))
{
requestWriter.Write(DATA);
}
try
{
WebResponse webResponse = request.GetResponse();
using (Stream webStream = webResponse.GetResponseStream() ?? Stream.Null)
using (StreamReader responseReader = new StreamReader(webStream))
{
string response = responseReader.ReadToEnd();
Console.Out.WriteLine(response);
}
}
catch (Exception e)
{
Console.Out.WriteLine("-----------------");
Console.Out.WriteLine(e.Message);
}
}
}
}
다음은 C#(2019년 업데이트)에서 외부 API를 호출하는 몇 가지 방법입니다.
.NET의 기본 제공 방식:
- WebRequest & WebClient - 자세한 API와 Microsoft의 문서는 따라하기가 매우 쉽지 않습니다.
- HttpClient - .NET의 새로운 아이는 위에서보다 훨씬 더 사용하기 쉽습니다.
솔직히 훨씬 더 나은 개발자 경험을 가진 무료 오픈 소스 NuGet 패키지.NET의 기본 제공 클라이언트:
- 서비스 스택.텍스트(GitHub 별 1,000개, NuGet 다운로드 700만 건) - 빠르고 가볍고 탄력적입니다.
- RestSharp (GitHub 스타 6,000명, NuGet 다운로드 2,300만 건) (*) - 단순 REST 및 HTTP API 클라이언트
- Flurl(1,700 GitHub 별, 300만 NuGet 다운로드) - 유창하고 휴대성이 뛰어나고 테스트 가능한 HTTP 클라이언트 라이브러리
위의 모든 패키지는 훌륭한 개발자 경험(즉, 간결하고 쉬운 API)을 제공하며 잘 유지됩니다.
(*) 2019년 8월 기준
예: ServiceStack을 사용하여 Fake Rest API에서 Todo 항목 가져오기.텍스트. 다른 라이브러리의 구문은 매우 유사합니다.
class Program
{
static void Main(string[] args)
{
// Fake rest API
string url = "https://jsonplaceholder.typicode.com/todos/1";
// GET data from API & map to POCO
var todo = url.GetJsonFromUrl().FromJson<Todo>();
// Print the result to screen
todo.PrintDump();
}
public class Todo
{
public int UserId { get; set; }
public int Id { get; set; }
public string Title { get; set; }
public bool Completed { get; set; }
}
}
.NET Core Console 앱에서 위의 예제를 실행하면 다음과 같은 출력이 생성됩니다.
NuGet을 사용하여 이러한 패키지 설치
Install-Package ServiceStack.Text, or
Install-Package RestSharp, or
Install-Package Flurl.Http
using Newtonsoft.Json;
using System;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using System.Configuration;
namespace WebApp
{
public static class HttpHelper
{
// In my case this is https://localhost:44366/
private static readonly string apiBasicUri = ConfigurationManager.AppSettings["apiBasicUri"];
public static async Task Post<T>(string url, T contentValue)
{
using (var client = new HttpClient())
{
client.BaseAddress = new Uri(apiBasicUri);
var content = new StringContent(JsonConvert.SerializeObject(contentValue), Encoding.UTF8, "application/json");
var result = await client.PostAsync(url, content);
result.EnsureSuccessStatusCode();
}
}
public static async Task Put<T>(string url, T stringValue)
{
using (var client = new HttpClient())
{
client.BaseAddress = new Uri(apiBasicUri);
var content = new StringContent(JsonConvert.SerializeObject(stringValue), Encoding.UTF8, "application/json");
var result = await client.PutAsync(url, content);
result.EnsureSuccessStatusCode();
}
}
public static async Task<T> Get<T>(string url)
{
using (var client = new HttpClient())
{
client.BaseAddress = new Uri(apiBasicUri);
var result = await client.GetAsync(url);
result.EnsureSuccessStatusCode();
string resultContentString = await result.Content.ReadAsStringAsync();
T resultContent = JsonConvert.DeserializeObject<T>(resultContentString);
return resultContent;
}
}
public static async Task Delete(string url)
{
using (var client = new HttpClient())
{
client.BaseAddress = new Uri(apiBasicUri);
var result = await client.DeleteAsync(url);
result.EnsureSuccessStatusCode();
}
}
}
}
게시하려면 다음과 같은 방법을 사용합니다.
await HttpHelper.Post<Setting>($"/api/values/{id}", setting);
삭제 예:
await HttpHelper.Delete($"/api/values/{id}");
목록을 가져오는 예:
List<ClaimTerm> claimTerms = await HttpHelper.Get<List<ClaimTerm>>("/api/values/");
하나만 가져오는 예:
ClaimTerm processedClaimImage = await HttpHelper.Get<ClaimTerm>($"/api/values/{id}");
REST API 요청에는 다음 코드를 사용하십시오.
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Text;
using System.Json;
namespace ConsoleApplication2
{
class Program
{
private const string URL = "https://XXXX/rest/api/2/component";
private const string DATA = @"{
""name"": ""Component 2"",
""description"": ""This is a JIRA component"",
""leadUserName"": ""xx"",
""assigneeType"": ""PROJECT_LEAD"",
""isAssigneeTypeValid"": false,
""project"": ""TP""}";
static void Main(string[] args)
{
AddComponent();
}
private static void AddComponent()
{
System.Net.Http.HttpClient client = new System.Net.Http.HttpClient();
client.BaseAddress = new System.Uri(URL);
byte[] cred = UTF8Encoding.UTF8.GetBytes("username:password");
client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Basic", Convert.ToBase64String(cred));
client.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));
System.Net.Http.HttpContent content = new StringContent(DATA, UTF8Encoding.UTF8, "application/json");
HttpResponseMessage messge = client.PostAsync(URL, content).Result;
string description = string.Empty;
if (messge.IsSuccessStatusCode)
{
string result = messge.Content.ReadAsStringAsync().Result;
description = result;
}
}
}
}
.NET 4.5 또는 .NET Core 사용 시 REST API 호출
달소프트를 추천합니다.RestClient(주의:제가 만들었습니다.그 이유는 동적 타이핑을 사용하기 때문에 직렬화/직렬화 해제를 포함하여 모든 것을 한 번의 유창한 통화로 마무리할 수 있기 때문입니다.다음은 작동하는 PUT 예제입니다.
dynamic client = new RestClient("http://jsonplaceholder.typicode.com");
var post = new Post { title = "foo", body = "bar", userId = 10 };
var result = await client.Posts(1).Put(post);
가져오기:
// GET JSON Response
public WeatherResponseModel GET(string url) {
WeatherResponseModel model = new WeatherResponseModel();
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
try {
WebResponse response = request.GetResponse();
using(Stream responseStream = response.GetResponseStream()) {
StreamReader reader = new StreamReader(responseStream, Encoding.UTF8);
model = JsonConvert.DeserializeObject < WeatherResponseModel > (reader.ReadToEnd());
}
} catch (WebException ex) {
WebResponse errorResponse = ex.Response;
using(Stream responseStream = errorResponse.GetResponseStream()) {
StreamReader reader = new StreamReader(responseStream, Encoding.GetEncoding("utf-8"));
String errorText = reader.ReadToEnd();
// Log errorText
}
throw;
}
return model;
}
게시물:
// POST a JSON string
void POST(string url, string jsonContent) {
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
request.Method = "POST";
System.Text.UTF8Encoding encoding = new System.Text.UTF8Encoding();
Byte[]byteArray = encoding.GetBytes(jsonContent);
request.ContentLength = byteArray.Length;
request.ContentType = @ "application/json";
using(Stream dataStream = request.GetRequestStream()) {
dataStream.Write(byteArray, 0, byteArray.Length);
}
long length = 0;
try {
using(HttpWebResponse response = (HttpWebResponse)request.GetResponse()) {
// Got response
length = response.ContentLength;
}
} catch (WebException ex) {
WebResponse errorResponse = ex.Response;
using(Stream responseStream = errorResponse.GetResponseStream()) {
StreamReader reader = new StreamReader(responseStream, Encoding.GetEncoding("utf-8"));
String errorText = reader.ReadToEnd();
// Log errorText
}
throw;
}
}
참고: JSON을 직렬화하고 원하는 대로 만들기 위해 Newtonsoft를 사용했습니다.Json NuGet 패키지.
.NET에서 REST 서비스로 전화를 거는 방법은 Refit를 확인하십시오.매우 사용하기 쉽다는 것을 알게 되었습니다.
장착: .NET Core, Xamarin 및 .NET용 자동 유형 안전 REST 라이브러리
Refit는 Square의 Retrofit 라이브러리에서 영감을 많이 받은 라이브러리이며 REST API를 라이브 인터페이스로 전환합니다.
public interface IGitHubApi {
[Get("/users/{user}")]
Task<User> GetUser(string user);
}
// The RestService class generates an implementation of IGitHubApi
// that uses HttpClient to make its calls:
var gitHubApi = RestService.For<IGitHubApi>("https://api.github.com");
var octocat = await gitHubApi.GetUser("octocat");
이것은 확실히 작동하는 예제 코드입니다.REST 서비스에서 객체 집합을 읽는 데 하루가 걸렸습니다.
RootObject는 REST 서비스에서 읽고 있는 개체의 유형입니다.
string url = @"http://restcountries.eu/rest/v1";
DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(IEnumerable<RootObject>));
WebClient syncClient = new WebClient();
string content = syncClient.DownloadString(url);
using (MemoryStream memo = new MemoryStream(Encoding.Unicode.GetBytes(content)))
{
IEnumerable<RootObject> countries = (IEnumerable<RootObject>)serializer.ReadObject(memo);
}
Console.Read();
저는 웹 API 2.0을 사용하여 이 간단한 방법으로 했습니다.UseDefaultCredentials를 제거할 수 있습니다.저는 그것을 저만의 사용 사례로 사용했습니다.
List<YourObject> listObjects = new List<YourObject>();
string response = "";
using (var client = new WebClient() { UseDefaultCredentials = true })
{
response = client.DownloadString(apiUrl);
}
listObjects = JsonConvert.DeserializeObject<List<YourObject>>(response);
return listObjects;
var TakingRequset = WebRequest.Create("http://xxx.acv.com/MethodName/Get");
TakingRequset.Method = "POST";
TakingRequset.ContentType = "text/xml;charset=utf-8";
TakingRequset.PreAuthenticate = true;
//---Serving Request path query
var PAQ = TakingRequset.RequestUri.PathAndQuery;
//---creating your xml as per the host reqirement
string xmlroot=@"<root><childnodes>passing parameters</childnodes></root>";
string xmlroot2=@"<root><childnodes>passing parameters</childnodes></root>";
//---Adding Headers as requested by host
xmlroot2 = (xmlroot2 + "XXX---");
//---Adding Headers Value as requested by host
// var RequestheaderVales = Method(xmlroot2);
WebProxy proxy = new WebProxy("XXXXX-----llll", 8080);
proxy.Credentials = new NetworkCredential("XXX---uuuu", "XXX----", "XXXX----");
System.Net.WebRequest.DefaultWebProxy = proxy;
// Adding The Request into Headers
TakingRequset.Headers.Add("xxx", "Any Request Variable ");
TakingRequset.Headers.Add("xxx", "Any Request Variable");
byte[] byteData = Encoding.UTF8.GetBytes(xmlroot);
TakingRequset.ContentLength = byteData.Length;
using (Stream postStream = TakingRequset.GetRequestStream())
{
postStream.Write(byteData, 0, byteData.Length);
postStream.Close();
}
StreamReader stredr = new StreamReader(TakingRequset.GetResponse().GetResponseStream());
string response = stredr.ReadToEnd();
여기에 표시된 답변은 HttpClient를 직접 사용하고 이를 폐기할 것을 제안합니다.이 방법은 사용할 수 있지만 올바르게 사용하지 않으면 HttpClient 문제가 발생하기 쉽습니다.
HttpClient를 사용할 경우 HttpClient의 생성/폐기를 공장 패턴을 사용하는 타사 라이브러리로 넘기는 것이 좋습니다.RestClient.넷은 그런 라이브러리 중 하나입니다.
매우 기본적인 HttpClient 공장과 함께 제공되므로 소켓 소모 문제를 겪지 않습니다.
public class DefaultHttpClientFactory : IHttpClientFactory, IDisposable
{
#region Fields
private bool disposed;
private readonly ConcurrentDictionary<string, Lazy<HttpClient>> _httpClients;
private readonly Func<string, Lazy<HttpClient>> _createClientFunc;
#endregion
#region Constructor
public DefaultHttpClientFactory() : this(null)
{
}
public DefaultHttpClientFactory(Func<string, Lazy<HttpClient>> createClientFunc)
{
_createClientFunc = createClientFunc;
_httpClients = new ConcurrentDictionary<string, Lazy<HttpClient>>();
if (_createClientFunc != null) return;
_createClientFunc = name =>
{
return new Lazy<HttpClient>(() => new HttpClient(), LazyThreadSafetyMode.ExecutionAndPublication);
};
}
#endregion
#region Implementation
public HttpClient CreateClient(string name)
{
if (name == null)
{
throw new ArgumentNullException(nameof(name));
}
return _httpClients.GetOrAdd(name, _createClientFunc).Value;
}
public void Dispose()
{
if (disposed) return;
disposed = true;
foreach (var name in _httpClients.Keys)
{
_httpClients[name].Value.Dispose();
}
}
#endregion
}
그러나 Microsoft의 IHtpClientFactory 구현은 다음과 같은 최신 기능에도 사용할 수 있습니다.
var serviceCollection = new ServiceCollection();
var baseUri = new Uri("http://www.test.com");
serviceCollection.AddSingleton(typeof(ISerializationAdapter), typeof(NewtonsoftSerializationAdapter));
serviceCollection.AddSingleton(typeof(ILogger), typeof(ConsoleLogger));
serviceCollection.AddSingleton(typeof(IClient), typeof(Client));
serviceCollection.AddDependencyInjectionMapping();
serviceCollection.AddTransient<TestHandler>();
//Make sure the HttpClient is named the same as the Rest Client
serviceCollection.AddSingleton<IClient>(x => new Client(name: clientName, httpClientFactory: x.GetRequiredService<IHttpClientFactory>()));
serviceCollection.AddHttpClient(clientName, (c) => { c.BaseAddress = baseUri; })
.AddHttpMessageHandler<TestHandler>();
var serviceProvider = serviceCollection.BuildServiceProvider();
var client = serviceProvider.GetService<IClient>();
await client.GetAsync<object>();
RestClient.Net은 종속성 주입, 조롱, IoC 컨테이너, 유닛 테스트 가능성을 고려하며 무엇보다 빠릅니다.저는 여기저기 찾아다녔고 비슷한 능력으로 일하는 것으로 보이는 유일한 고객은 Flurlurl.Http.
우리는 말을 쉽게 사용하기 시작했습니다.훌륭합니다.
https://github.com/jonnii/SpeakEasy
// create a client
var client = HttpClient.Create("http://example.com/api");
// get some companies!
var companies = client.Get("companies").OnOk().As<List<Company>>();
// upload a company, with validation error support
client.Post(company, "companies")
.On(HttpStatusCode.BadRequest, (List<ValidationError> errors) => {
Console.WriteLine("Ruh Roh, you have {0} validation errors", errors.Count());
})
.On(HttpStatusCode.Created, () => Console.WriteLine("Holy moly you win!"));
// update a company
client.Put(company, "company/:id", new { id = "awesome-sauce" })
.OnOk(() => Console.WriteLine("Company updated"));
// run a search
client.Get("images/:category", new { category = "cats", breed = "omg the cutest", size = "kittens" })
.OnOk().As<List<Image>>();
// make an asynchronous request
var response = await client.GetAsync("companies/:id", new { id = 5 })
response.OnOk(UpdateCompaniesCallback)
Visual Studio 11 베타를 사용하고 있으므로 최신 버전과 최고의 버전을 사용하고 싶을 것입니다.새 웹 API에는 이에 대한 클래스가 포함되어 있습니다.
HttpClient: http://wcf.codeplex.com/wikipage?title=WCF%20HTTP 를 참조하십시오.
HTTP GET 요청
string api = this.configuration["getApiUrl"];//Read from Iconfiguration object injected
public async Task<HttpResponseMessage> GetAsync(string api, ILogger log, params dynamic[] parameters)
{
log.LogInformation($"Get Token");
var token = await GetTokenAsync(this.configuration["ClientId"], this.configuration["AppKey"]).ConfigureAwait(false);
using (var client = new HttpClient())
{
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(BearerTokenName, token);
var apiBaseUrl = this.configuration["BaseUrl"];
client.BaseAddress = new Uri(apiBaseUrl);
var apiUrl = ConstructUrl(api, parameters);
var result = await client.GetAsync(apiUrl).ConfigureAwait(false);
if (result.StatusCode == System.Net.HttpStatusCode.OK)
{
return result;
}
else
{
throw new HttpResponseException(new HttpResponseMessage(result.StatusCode) { Content = new StringContent(result.ReasonPhrase) });
}
}
}
- 아래와 같이 HttpResponseMessage에서 문자열 읽기
var client = await this.httpClientService.GetAsync(url, logger, Convert.ToInt32(Id, CultureInfo.InvariantCulture)).ConfigureAwait(false);
var response = await client.Content.ReadAsStringAsync();
HTTP POST 요청
public async Task<string> PostAsync(string api, string contentValue, ILogger logger)
{
var token = await GetTokenAsync(this.configuration["ClientId"], this.configuration["AppKey"]).ConfigureAwait(false);
using (var client = new HttpClient())
{
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(BearerTokenName, token);
client.BaseAddress = new Uri(resource);
var content = new StringContent(contentValue, Encoding.UTF8, MediaTypeNames.Application.Json);
var result = await client.PostAsync(new Uri(api, UriKind.Relative), content).ConfigureAwait(false);
if (result.StatusCode == System.Net.HttpStatusCode.OK)
{
return await result.Content.ReadAsStringAsync();
}
else
{
throw new HttpResponseException(new HttpResponseMessage(result.StatusCode) { Content = new StringContent(result.ReasonPhrase) });
}
}
}
var response = await this.httpClientService.PostAsync(this.configuration["getDetails"], content, this.configuration["ApiBaseUrl"], logger).ConfigureAwait(false);
catch (System.Web.Http.HttpResponseException httpException)
{
if (httpException.Response.StatusCode == HttpStatusCode.Unauthorized)
{
logger.LogError($"Failed To Update", httpException);
}
else
{
throw;
}
}
return response;
첫 번째 단계는 HTTP 클라이언트에 대한 도우미 클래스를 만드는 것입니다.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;
namespace callApi.Helpers
{
public class CallApi
{
private readonly Uri BaseUrlUri;
private HttpClient client = new HttpClient();
public CallApi(string baseUrl)
{
BaseUrlUri = new Uri(baseUrl);
client.BaseAddress = BaseUrlUri;
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(
new MediaTypeWithQualityHeaderValue("application/json"));
}
public HttpClient getClient()
{
return client;
}
public HttpClient getClientWithBearer(string token)
{
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
return client;
}
}
}
그러면 코드에 이 클래스를 사용할 수 있습니다.
위 클래스를 사용하여 베어러 없이 REST API를 호출하는 방법의 예입니다.
// GET API/values
[HttpGet]
public async Task<ActionResult<string>> postNoBearerAsync(string email, string password,string baseUrl, string action)
{
var request = new LoginRequest
{
email = email,
password = password
};
var callApi = new CallApi(baseUrl);
var client = callApi.getClient();
HttpResponseMessage response = await client.PostAsJsonAsync(action, request);
if (response.IsSuccessStatusCode)
return Ok(await response.Content.ReadAsAsync<string>());
else
return NotFound();
}
베어러가 필요한 REST API를 호출하는 방법의 예입니다.
// GET API/values
[HttpGet]
public async Task<ActionResult<string>> getUseBearerAsync(string token, string baseUrl, string action)
{
var callApi = new CallApi(baseUrl);
var client = callApi.getClient();
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
HttpResponseMessage response = await client.GetAsync(action);
if (response.IsSuccessStatusCode)
{
return Ok(await response.Content.ReadAsStringAsync());
}
else
return NotFound();
}
작동 방법에 대한 작업 예제를 보려면 아래 리포지토리를 참조할 수도 있습니다.
https://github.com/mokh223/callApi
언급URL : https://stackoverflow.com/questions/9620278/how-do-i-make-calls-to-a-rest-api-using-c
'programing' 카테고리의 다른 글
이클립스 Tomcat 7 빈 서버 이름 추가 (0) | 2023.05.17 |
---|---|
NSA 속성 문자열은 어떻게 사용합니까? (0) | 2023.05.17 |
Xcode에서 서명 ID 문제를 해결할 수 없습니다. (0) | 2023.05.17 |
구성 요소가 NgModule의 일부가 아니거나 모듈을 모듈로 가져오지 않았습니다. (0) | 2023.05.17 |
Conda를 사용하여 python 3.8로 업그레이드 (0) | 2023.05.17 |