C # kullanarak bir REST api için nasıl arama yapabilirim?


335

Bu şimdiye kadar var kod:

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

        }
    }
}

Sorun, istisna bloğunun tetiklendiğini düşünüyorum (çünkü try-catch'i kaldırdığımda, bir sunucu hatası (500) mesajı alıyorum. Ama catch bloğuna koyduğum Console.Out satırlarını görmüyorum.

Konsolum:

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

Visual Studio 2011 Beta ve .NET 4.5 Beta kullanıyorum.


Ayrıca, tam olarak nerede patladığını görmek için oraya kırılma noktaları koydunuz mu?
NotMe

bu çıkış penceresinden kaynaklanır, ancak konsoldan değil
Serj-Tm

5
MSDN'nin RESTful hizmetleri oluşturma konusunda mükemmel bir makalesi vardı: msdn.microsoft.com/library/dd203052.aspx ... ve RESTful istemcileri: msdn.microsoft.com/en-us/magazine/ee309509.aspx
Lynn Crumbling

@ChrisLively bunun IE ile ne ilgisi var? = \ İstek üzerine patlıyor.GetResponse hattı.
NullVoxPopuli

@TheLindyHop; Kesinlikle hiçbir şey. Yanlış okudum.
NotMe

Yanıtlar:


427

ASP.Net Web API, daha önce sözü edilen WCF Web API'sinin yerini almıştır.

Bu yanıtların çoğu 2012'nin başlarından beri güncellenmiş bir cevap yayınlayacağımı düşündüm ve bu konu "callful service c #" için Google araması yaparken en iyi sonuçlardan biri.

Microsoft'un şu anki kılavuzu, RESTful hizmeti tüketmek için Microsoft ASP.NET Web API İstemci Kitaplıkları'nı kullanmaktır. Bu bir NuGet paketi, Microsoft.AspNet.WebApi.Client olarak mevcuttur. Bu NuGet paketini çözümünüze eklemeniz gerekecek.

ASP.Net Web API İstemci Kitaplığı kullanılarak uygulandığında örneğiniz şöyle görünecektir:

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

Birden fazla istekte bulunmayı planlıyorsanız, HttpClient örneğinizi yeniden kullanmalısınız. Bu durumda HttpClient örneğinde neden bir kullanım ifadesinin kullanılmadığına ilişkin daha fazla ayrıntı için bu soruya ve yanıtlarına bakın: HttpClient ve HttpClientHandler atılmalı mı?

Diğer örnekler de dahil olmak üzere daha fazla ayrıntı için buraya gidin: http://www.asp.net/web-api/overview/web-api-clients/calling-a-web-api-from-a-net-client

Bu blog yayını ayrıca yararlı olabilir: http://johnnycode.com/2012/02/23/consuming-your-own-asp-net-web-api-rest-service/


6
Teşekkürler! Bunun benim için çalışması için WebApi istemci NuGet paketini yüklemem gerekiyordu: Install-Package Microsoft.AspNet.WebApi.Client
Ev.

3
REST entegrasyonunuzu taklit etmeniz gerekiyorsa, istemci kütüphanelerinde bile bu hala kolay değildir. RestSharp'ı deneyin?
Rob Kilisesi

6
Bu cevabı zaten olduğundan daha iyi hale getirmek için, kaynağınızı daha iyi yönetmek için HttpClient bildirimini kullanarak bir ifadeye sarmalısınız :)
Daniel Siebert

7
Kullanmaya çalıştım ama ReadAsAsync () kullanamadım, hata alıyorum "HttpContent 'ReadAsAsync' için bir tanım içermiyor ve uzatma yöntemi yok.
Robert Green MBA

7
@RobertGreenMBA: Uzantı yöntemini almak için ReadAsAsync()bir başvuru ekleyin System.Net.Http.Formatting.dll. (Sezgisel, değil mi?)
Arin

122

Benim önerim RestSharp kullanmak olacaktır . REST hizmetlerini arayabilir ve yanıtları ayrıştırmak için çok az kaynak kodlu POCO nesnelerine atabilirsiniz. Bu, özel hatanızı çözmez, ancak REST hizmetlerine nasıl çağrı yapılacağıyla ilgili genel sorunuza cevap verir. Kodunuzu kullanmak için değiştirmek zorunda kalırsanız, kullanım kolaylığı ve ileriye doğru hareket etme sağlamalıdır. Bu benim sadece 2 sentim

Misal:

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 ve JSON.NET kesinlikle gitmenin yolu. MS araç setinin eksik olduğunu ve muhtemelen başarısız olduğunu buldum.
cbuteau

2
RestSharp için başka bir oy, çünkü WebApi İstemci kitaplıklarından çok daha kolay bir şekilde test etmek için alay edebilirsiniz.
Rob Kilisesi

1
mono kullanıcılar için - RestSharp, System.Net WebRequest apis'i kullanıyor gibi görünüyor - ki bu da benim deneyimime göre .net uygulamaları kadar güvenilir değil. ('rastgele' kilitleniyor)
Tom

3
Bu cevapta bir örnek olması güzel olur.
Caltor

2
Bir örnek eksikliği, bu gönderiyi yararlı değil!
smac2020

39

İlgisiz, eminim, ancak uygun atmayı sağlamak için IDisposablenesnelerinizi usingbloklara sarın :

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
Normal .NET ortamının dışında fazladan paket kullanmayan güzel bir yanıt.
18'de palswim

@Jesse C. Dilimleyici .. neden WebResponse 404 hatasına neden oldum webResponse = request.GetResponse ();
Goh Han

2
Kaynak bulunamadığı için mi? 404 almak için birçok, birçok neden var.
Jesse C. Slicer

1
Bu harika bir çözüm @ JesseC.Slicer. Bir belirteç almak ve konsoldan görmek için bu kodu uygulayabiliyorum. Kimlik doğrulama / giriş için kullanmak üzere bu simgeyi kullanmam için herhangi bir ipucunuz var mı? GET'i bazı verileri çekmek için kullanmak istiyorum, ancak yalnızca giriş yapmışsam yapabilirim. Bununla ilgili daha fazla bilgiyi nereden edinebilirim? Teşekkürler!
Paul Laguna

18

C # (güncellenmiş 2019) içinde harici bir API'yi çağırmanın birkaç farklı yolu.

.NET'in yerleşik yolları:

  • WebRequest & WebClient - ayrıntılı API'lar ve Microsoft'un belgelerini takip etmek çok kolay değil
  • HttpClient - .NET'in bloktaki en yeni çocuğu ve kullanımı yukarıdakinden daha basit.

NET'in yerleşik istemcilerinden çok daha iyi bir geliştirici deneyimine sahip ücretsiz, açık kaynaklı NuGet Paketleri :

  • ServiceStack.Text (1k github yıldız, 7m Nuget indirmeleri) (*) - hızlı, hafif ve esnek.
  • RestSharp (6k github yıldızı, 23m Nuget İndirmeleri) (*) - basit REST ve HTTP API İstemcisi
  • Flurl (1.7k github yıldızı, 3m Nuget İndirmeleri) (*) - akıcı, taşınabilir, test edilebilir bir HTTP istemci kütüphanesi

Yukarıdaki tüm paketler mükemmel bir geliştirici deneyimi sağlar (yani kısa, kolay API) ve iyi korunur.

(*) Ağustos 2019 itibariyle

Örnek: ServiceStack.Text kullanarak bir Fake Rest API'sından bir Todo öğesi alma. Diğer kütüphanelerin sözdizimi çok benzerdir.

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

}

Yukarıdaki örneği bir .NET Core Console uygulamasında çalıştırmak aşağıdaki çıktıyı üretir.

resim açıklamasını buraya girin

NuGet kullanarak bu paketleri kurun

Install-Package ServiceStack.Text, or

Install-Package RestSharp, or

Install-Package Flurl.Http

17

REST API isteğiniz için lütfen aşağıdaki kodu kullanı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 yönetilen bir platformdur, ancak HttpClient yönetilmez (yani yönetilmeyen işaretçileri ne zaman atabileceğini söylemek için kullanmanız GEREKİR). Bu olmadan, kodunuz birkaç kullanıcıya ölçeklenmez (ve evet, bu önemlidir, dilin onunla ilgilenmek için belirli bir anahtar kelimeye sahip olması çok önemlidir).
JCKödel

5
JCKödel @ - Kesinlikle burada değiliz ve bu okumalı stackoverflow.com/a/22561368 - HttpClient olacak şekilde tasarlanmıştır birden aramalar için tekrar kullanılan
hB0

1
Evet @ JCKödel lütfen bu makaleyi okuyun stackoverflow.com/questions/15705092/…
Nathan

11

Çözümümü ASP.NET Core'da paylaşmak istiyorum

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

Göndermek için şöyle bir şey kullanın:

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

Silme örneği:

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

Liste almak için örnek:

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

Yalnızca bir tane almak için örnek:

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

2
Httpclient'i bir kullanım bloğunun içinde kullanmamalısınız, bu gerçekten güzel bir kod parçası. bkz. aspnetmonsters.com/2016/08/2016-08-27-httpclientwrong
Myke Black

9

.NET 4.5 veya .NET Core kullanırken REST API çağırma güncelleştirmesi

DalSoft.RestClient (uyarı ben yarattım) öneririm . Bunun nedeni, dinamik yazmayı kullanmasıdır, her şeyi serileştirme / serileştirme de dahil olmak üzere bir akıcı çağrıda tamamlayabilirsiniz. Aşağıda çalışan bir PUT örneği verilmiştir:

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

ALMAK:

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

İLETİ:

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

Not: JSON serileştirmek ve desirialze için Newtonsoft.Json NuGet paketini kullandım.


4

.Net adresinden geri kalan hizmetlere çağrı yapmak için Refit'e göz atın. Kullanımı çok kolay buldum: https://github.com/paulcbetts/refit

Takma: .NET Core, Xamarin ve .NET için otomatik tür güvenli REST kitaplığı

Refit, Square'in Retrofit kütüphanesinden büyük ölçüde esinlenen bir kütüphanedir ve REST API'nizi canlı bir arayüze dönüştürür:

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

Refit'in bunu başarmak için yansıma kullanıp kullanmadığını biliyor musunuz? Bilgileri hiçbir yerde bulamıyorum.
tfrascaroli

özür dilerim @tfrascaroli elden emin değilim.
patrickbadley

2

Bu, kesin olarak çalışan bir örnek koddur. Dinlenme hizmetinden bir dizi nesneyi okumak bunu yapmak için bir günümü aldı:

RootObject, geri kalan hizmetten okuduğum nesnenin türüdür.

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

Web Api 2.0 ile bu basit şekilde yaptım. UseDefaultCredentials.'i kaldırabilirsiniz. Kendi kullanım durumlarım için kullandım.

            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

Burada işaretlenen cevap HttpClient'in doğrudan kullanılmasını ve atılmasını önermektedir. Bu işe yarayabilir, ancak doğru kullanmazsanız HttpClient ile ilgili sorunlara rastlamak oldukça kolaydır . HttpClient'i kullanacaksanız, HttpClients'ın oluşturulmasını / atılmasını fabrika modelini kullanan bir 3. taraf kütüphanesine teslim etmeniz daha iyi olur. RestClient.Net böyle bir kütüphanedir.

Çok basit bir HttpClient fabrikası ile birlikte gelir, böylece soket tükenme problemine girmezsiniz,

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
}

Ancak Microsoft'un IHttpClientFactory uygulaması da en yeni ve en harika uygulamalar için kullanılabilir:

    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, bağımlılık enjeksiyonu, alay, IoC kapları, birim test edilebilirliğini hesaba katar ve her şeyden önce hızlıdır. Ben avlandım ve benzer bir kapasitede çalışıyor gibi görünen sadece diğer müşteri Flurl.Http


-2

ilk adım http istemcisi için yardımcı sınıf oluşturmaktır.

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

    }
}

Sonra bu sınıfı kodunuzda kullanabilirsiniz.

Bu, yukarıdaki sınıfı kullanarak taşıyıcı olmadan geri kalan API'yi nasıl çağırdığınızın bir örneğidir.

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

bu, taşıyıcı gerektiren diğer API'leri nasıl çağırabileceğinizin bir örneğidir.

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

nasıl çalıştığına dair çalışma örneğini görmek istiyorsanız aşağıdaki repoya da başvurabilirsiniz.

https://github.com/mokh223/callApi

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.