Làm cách nào để thực hiện cuộc gọi đến api REST bằng C #?


333

Đây là mã tôi có cho đến nay:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System;
using System.Net.Http;
using System.Web;
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;
            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);
            }

        }
    }
}

Vấn đề là tôi nghĩ rằng khối ngoại lệ đang được kích hoạt (vì khi tôi gỡ bỏ lệnh thử, tôi nhận được thông báo lỗi máy chủ (500). Nhưng tôi không thấy các dòng Console. Nhưng tôi đã đặt trong khối bắt.

Bảng điều khiển của tôi:

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).

Tôi đang sử dụng Visual Studio 2011 Beta và .NET 4.5 Beta.


Ngoài ra, bạn đã đặt các điểm dừng trong đó để xem chính xác, nó đang nổ tung ở đâu chưa?
NotMe

đây là kết quả từ cửa sổ đầu ra nhưng không phải bàn điều khiển
Serj-Tm

5
MSDN đã có một bài viết tuyệt vời về việc xây dựng các dịch vụ RESTful: msdn.microsoft.com/l Library / dd203052.aspx ... và các khách hàng RESTful: msdn.microsoft.com/en-us/magazine/ee309509.aspx
Lynn Crumbled

@ChrisLively Điều này có liên quan gì với IE? = \ Nó đang nổ tung trên dòng request.GetResponse.
NullVoxPopuli

@TheLindyHop; Hoàn toàn không có gì. Tôi đọc sai.
NotMe

Câu trả lời:


426

API Web ASP.Net đã thay thế API Web WCF đã đề cập trước đó.

Tôi nghĩ rằng tôi đã đăng một câu trả lời cập nhật vì hầu hết các phản hồi này là từ đầu năm 2012 và chủ đề này là một trong những kết quả hàng đầu khi thực hiện tìm kiếm Google cho "dịch vụ nghỉ ngơi c #".

Hướng dẫn hiện tại của Microsoft là sử dụng Thư viện máy khách Microsoft ASP.NET Web API để sử dụng dịch vụ RESTful. Điều này có sẵn dưới dạng gói NuGet, Microsoft.AspNet.WebApi.Client. Bạn sẽ cần thêm gói NuGet này vào giải pháp của mình.

Dưới đây là ví dụ của bạn sẽ trông như thế nào khi được triển khai bằng Thư viện máy khách API Web ASP.Net:

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();
        }
    }
}

Nếu bạn có kế hoạch thực hiện nhiều yêu cầu, bạn nên sử dụng lại ví dụ httpClient của mình. Xem câu hỏi này và câu trả lời của nó để biết thêm chi tiết về lý do tại sao một câu lệnh sử dụng không được sử dụng trong trường hợp HTTPClient trong trường hợp này: Phải sử dụng httpClient và HttpClientHandler?

Để biết thêm chi tiết, bao gồm các ví dụ khác, hãy truy cập tại đây: http://www.asp.net/web-api/overview/web-api-clents/calling-a-web-api-from-a-net-client

Bài đăng trên blog này cũng có thể hữu ích: http://johnnycode.com/2012/02/23/consuming-your-own-asp-net-web-api-rest-service/


6
Cảm ơn! Tôi cần cài đặt gói NuGet của máy khách WebApi để nó hoạt động với tôi: Cài đặt gói Microsoft.AspNet.WebApi.Client
Ev.

3
Nếu bạn cần mô phỏng tích hợp REST của mình, ngay cả với các thư viện máy khách, điều đó vẫn không dễ dàng. Hãy thử RestSharp?
Nhà thờ Rob

6
Để làm cho câu trả lời này thậm chí tốt hơn so với hiện tại, bạn nên gói khai báo httpClient vào một câu lệnh sử dụng để quản lý tốt hơn tài nguyên của mình :)
Daniel Siebert

7
Đã thử sử dụng nhưng không thể sử dụng ReadAsAsync (), gặp lỗi "HttpContent không chứa định nghĩa cho 'ReadAsAsync' và không có phương thức mở rộng.
Robert Green MBA

7
@RobertGreenMBA: Để có được phương thức mở rộng ReadAsAsync(), hãy thêm một tham chiếu đến System.Net.Http.Formatting.dll. (Trực quan, phải không?)
Arin

122

Đề xuất của tôi sẽ là sử dụng RestSharp . Bạn có thể thực hiện các cuộc gọi đến các dịch vụ REST và chuyển chúng thành các đối tượng POCO với rất ít mã soạn sẵn để thực sự phải phân tích cú pháp thông qua phản hồi. Điều này sẽ không giải quyết được lỗi cụ thể của bạn, nhưng trả lời câu hỏi chung của bạn về cách thực hiện cuộc gọi đến dịch vụ REST. Phải thay đổi mã của bạn để sử dụng nó nên trả hết tiền để dễ sử dụng và mạnh mẽ tiến về phía trước. Đó chỉ là 2 xu của tôi

Thí dụ:

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; }
    }
}

6
RestSharp và JSON.NET chắc chắn là con đường để đi. Tôi thấy bộ công cụ MS bị thiếu và có khả năng thất bại.
cbuteau

2
Một phiếu bầu khác cho RestSharp vì bạn có thể giả định nó để thử nghiệm nhiều, dễ dàng hơn nhiều so với các thư viện Máy khách WebApi.
Nhà thờ Rob

1
đối với người dùng đơn âm - RestSharp dường như đang sử dụng apis System.Net WebRequest - mà theo kinh nghiệm của tôi không đáng tin cậy như các triển khai .net. ('Ngẫu nhiên' bị treo)
Tom

3
Xin vui lòng có một ví dụ trong câu trả lời này xin vui lòng.
Caltor

2
Việc thiếu một ví dụ làm cho bài đăng này không hữu ích!
smac2020

39

Không liên quan, tôi chắc chắn, nhưng hãy bọc các IDisposableđối tượng của bạn thành các usingkhối để đảm bảo xử lý đúng cách:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System;
using System.Web;
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);
            }

        }
    }
}

4
Câu trả lời hay không sử dụng bất kỳ gói bổ sung nào ngoài môi trường .NET thông thường.
palswim

@Jlie C. Choper..tại sao tôi gặp lỗi 404 trong WebResponse webResponse = request.GetResponse ();
Goh Han

2
Bởi vì tài nguyên không được tìm thấy? Có rất nhiều, NHIỀU lý do để có được 404.
Jesse C. Choper

1
Đây là một giải pháp tuyệt vời @ JesseC.Slicer. Tôi có thể áp dụng mã này để lấy mã thông báo và xem mã từ bảng điều khiển. Bạn có bất cứ lời khuyên nào để tôi sử dụng mã thông báo này để sử dụng để xác thực / đăng nhập không? Tôi muốn sử dụng GET để lấy một số dữ liệu, nhưng chỉ có thể nếu tôi đăng nhập. Tôi có thể tìm hiểu thêm về điều này ở đâu? Cảm ơn!
Paul Laguna

1
Điều này làm việc cho tôi. Cảm ơn bạn!
Shahriar Rahman Zahin

18

Dưới đây là một vài cách khác nhau để gọi API bên ngoài trong C # (cập nhật 2019).

Các cách dựng sẵn của .NET:

  • WebRequest & WebClient - API dài dòng & tài liệu của Microsoft không dễ theo dõi
  • HttpClient - Đứa trẻ mới nhất của .NET trên khối & sử dụng đơn giản hơn nhiều so với ở trên.

Các gói NuGet miễn phí, mã nguồn mở , thực sự có trải nghiệm nhà phát triển tốt hơn nhiều so với các máy khách được tích hợp sẵn của .NET:

  • ServiceStack.Text (1k github sao, 7m tải xuống Nuget) (*) - nhanh, nhẹ và đàn hồi.
  • RestSharp (6 sao github sao, Tải xuống Nuget 23m) (*) - Trình khách API REST và HTTP đơn giản
  • Flurl (sao github 1,7k, tải xuống Nuget 3 m) (*) - một thư viện khách HTTP thông thạo, di động, có thể kiểm tra

Tất cả các gói trên cung cấp trải nghiệm tuyệt vời cho nhà phát triển (tức là API ngắn gọn, dễ dàng) và được duy trì tốt.

(*) vào tháng 8 năm 2019

Ví dụ: Nhận một mục Todo từ API nghỉ ngơi giả bằng ServiceStack.Text. Các thư viện khác có cú pháp rất giống nhau.

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 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; }
    }

}

Chạy ví dụ trên trong ứng dụng .NET Core Console, tạo đầu ra sau.

nhập mô tả hình ảnh ở đây

Cài đặt các gói này bằng NuGet

Install-Package ServiceStack.Text, or

Install-Package RestSharp, or

Install-Package Flurl.Http

17

Vui lòng sử dụng mã dưới đây cho yêu cầu api REST của bạn

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;
            }
        }
    }
}

-1: .net là một nền tảng được quản lý, nhưng HttpClient không được quản lý (có nghĩa là bạn PHẢI sử dụng để nói với nó khi nó có thể loại bỏ các con trỏ không được quản lý đó). Không có nó, mã của bạn sẽ không mở rộng cho một vài người dùng (và, vâng, điều này quan trọng, quan trọng đến mức ngôn ngữ phải có một từ khóa cụ thể để đối phó với nó).
JCKödel

5
@ JCKödel - Bạn không hoàn toàn đúng ở đây và nên đọc stackoverflow.com/a/22561368 này - HttpClient đã được thiết kế để được sử dụng lại cho nhiều cuộc gọi
hB0

1
Có @ JCKödel vui lòng đọc bài viết này stackoverflow.com/questions/15705092/iêu
Nathan

11

Tôi muốn chia sẻ giải pháp của tôi trong ASP.NET Core

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();
            }
        }
    }
}

Để đăng sử dụng một cái gì đó như thế này:

await HttpHelper.Post<Setting>($"/api/values/{id}", setting);

Ví dụ để xóa:

await HttpHelper.Delete($"/api/values/{id}");

Ví dụ để lấy danh sách:

List<ClaimTerm> claimTerms = await HttpHelper.Get<List<ClaimTerm>>("/api/values/");

Ví dụ để chỉ có một:

ClaimTerm processedClaimImage = await HttpHelper.Get<ClaimTerm>($"/api/values/{id}");

2
Đó là một đoạn mã thực sự hay, mặc dù bạn không nên sử dụng httpclient trong một khối sử dụng. xem aspnetmonsters.com/2016/08/2016-08-27-httpclientwrong
Myke Black

9

Cập nhật để gọi API REST khi sử dụng .NET 4.5 hoặc .NET Core

Tôi sẽ đề nghị DalSoft.RestClient ( hãy cẩn thận tôi đã tạo ra nó). Lý do là bởi vì nó sử dụng kiểu gõ động, bạn có thể kết thúc mọi thứ trong một cuộc gọi trôi chảy bao gồm cả tuần tự hóa / khử nối tiếp. Dưới đây là một ví dụ PUT hoạt động:

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);

5

ĐƯỢC:

// 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;
}

BÀI ĐĂNG:

// 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;
    }
}

Lưu ý: Để tuần tự hóa và giải nén JSON, tôi đã sử dụng gói Newtonsoft.Json NuGet.


4

Kiểm tra Refit để thực hiện cuộc gọi đến các dịch vụ nghỉ ngơi từ .net. Tôi thấy nó rất dễ sử dụng: https://github.com/paulcbetts/refit

Refit: Thư viện REST tự động loại an toàn cho .NET Core, Xamarin và .NET

Refit là một thư viện được truyền cảm hứng rất nhiều từ thư viện Retrofit của Square và nó biến API REST của bạn thành một giao diện trực tiếp:

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");

Bạn có biết nếu Refit sử dụng sự phản chiếu để đạt được điều này? Tôi không thể tìm thấy thông tin ở bất cứ đâu.
tfrascaroli

xin lỗi @tfrascaroli Tôi không chắc tay.
patrickbadley

2

Đây là một mã ví dụ hoạt động chắc chắn. Phải mất một ngày để tôi đọc được một bộ đối tượng từ dịch vụ Rest:

RootObject là loại đối tượng tôi đọc từ dịch vụ còn lại.

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();

1
    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();

1

Tôi đã làm điều đó theo cách đơn giản này, với web Api 2.0. Bạn có thể xóa UseDefaultCredentials. Tôi đã sử dụng nó cho các trường hợp sử dụng của riêng tôi.

            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 ;


0

Câu trả lời được đánh dấu ở đây gợi ý sử dụng trực tiếp httpClient và việc xử lý nó. Điều này có thể hoạt động, nhưng nó khá dễ gặp phải các vấn đề với HttpClient nếu bạn không sử dụng đúng cách. Nếu bạn sẽ sử dụng HttpClient, tốt hơn hết là bạn nên bàn giao việc tạo / xử lý các HTTPCl cho thư viện bên thứ 3 sử dụng mẫu nhà máy. RestClient.Net là một trong những thư viện như vậy.

Nó đi kèm với một nhà máy httpClient rất cơ bản để bạn không gặp phải vấn đề cạn kiệt ổ cắm,

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
}

Nhưng triển khai IHttpClientFactory của Microsoft cũng có thể được sử dụng cho lần mới nhất và lớn nhất:

    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 đưa vào tài khoản tiêm phụ thuộc, chế nhạo, bộ chứa IoC, khả năng kiểm tra đơn vị, và trên hết là nhanh chóng. Tôi đã săn lùng xung quanh và khách hàng duy nhất khác có vẻ hoạt động với công suất tương tự là Flurl.Http


-2

Bước đầu tiên là tạo lớp trình trợ giúp cho máy khách 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;
        }

    }
}

Sau đó, bạn có thể sử dụng lớp này trong mã của bạn.

đây là một ví dụ về cách bạn gọi api còn lại mà không có người sử dụng lớp trên.

// 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();
}

đây là một ví dụ về cách bạn có thể gọi api còn lại yêu cầu người mang.

// 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();
}

bạn cũng có thể tham khảo repo dưới đây nếu bạn muốn xem ví dụ hoạt động về cách thức hoạt động của nó.

https://github.com/mokh223/callApi

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.