it-swarm.com.de

Wie telefoniere ich mit einem REST API mit C #?

Dies ist der Code, den ich bisher habe:

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

        }
    }
}

Das Problem ist, dass ich denke, dass der Ausnahmeblock ausgelöst wird (da ich beim Entfernen des Try-Catchs eine Fehlermeldung über einen Serverfehler (500) bekomme.) Ich sehe jedoch nicht die Console.Out-Zeilen, die ich in den catch-Block stecke.

Meine Konsole:

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

Ich verwende Visual Studio 2011 Beta und .NET 4.5 Beta.

253
NullVoxPopuli

Die ASP.Net-Web-API hat die zuvor erwähnte WCF-Web-API ersetzt.

Ich dachte, ich würde eine aktualisierte Antwort posten, da die meisten dieser Antworten von Anfang 2012 stammen. Dieser Thread ist eines der Top-Ergebnisse bei einer Google-Suche nach "Call Restful Service c #".

Derzeit wird empfohlen, die Microsoft ASP.NET-Web-API-Clientbibliotheken zu verwenden, um einen RESTful-Dienst in Anspruch zu nehmen. Dies ist als NuGet-Paket Microsoft.AspNet.WebApi.Client verfügbar. Sie müssen dieses NuGet-Paket zu Ihrer Lösung hinzufügen.

So würde Ihr Beispiel aussehen, wenn es mit der ASP.Net Web API-Clientbibliothek implementiert wird:

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

Wenn Sie mehrere Anforderungen planen, sollten Sie Ihre HttpClient-Instanz erneut verwenden. In dieser Frage und ihren Antworten finden Sie weitere Informationen dazu, warum in diesem Fall keine using-Anweisung für die HttpClient-Instanz verwendet wurde: Müssen HttpClient und HttpClientHandler entsorgt werden?

Weitere Einzelheiten und andere Beispiele finden Sie hier: http://www.asp.net/web-api/overview/web-api-clients/calling-a-web-api-from-a-net-client

Dieser Blogbeitrag kann auch nützlich sein: http://johnnycode.com/2012/02/23/consuming-your-own-asp-net-web-api-rest-service/

350
Brian Swift

Mein Vorschlag wäre die Verwendung von RestSharp . Sie können REST - Dienste aufrufen und diese in POCO-Objekte mit sehr wenig Zusatzcode umwandeln lassen, um die Antwort tatsächlich analysieren zu müssen. Dies löst Ihren speziellen Fehler nicht, sondern beantwortet Ihre allgemeine Frage, wie Anrufe an REST - Dienste getätigt werden sollen. Wenn Sie Ihren Code ändern müssen, um ihn zu verwenden, sollten sich die Benutzerfreundlichkeit und Robustheit in der Zukunft auszahlen. Das ist nur meine 2 Cent

107
Justin Pihony

Ich bin mir sicher, es ist nicht verwandt, aber wickeln Sie Ihre IDisposable-Objekte in using-Blöcke ein, um eine ordnungsgemäße Entsorgung sicherzustellen:

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

        }
    }
}
28
Jesse C. Slicer

Bitte verwenden Sie den folgenden Code für Ihre REST - API-Anfrage

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

Update zum Aufrufen einer REST - API bei Verwendung von .NET 4.5 oder .NET Core 

Ich würde vorschlagen, DalSoft.RestClient (Achtung, ich habe es erstellt). Der Grund dafür ist, dass durch dynamische Eingabe alles in einem fließenden Anruf zusammengefasst wird, einschließlich Serialisierung/Deserialisierung. Unten ist ein funktionierendes PUT-Beispiel:

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

Check out Refit für das Tätigen von Anrufen von .net zu den Ruhezustandsdiensten. Ich fand es sehr einfach zu bedienen: https://github.com/paulcbetts/refit

Refit: Die automatische typsichere REST -Bibliothek für .NET Core, Xamarin und .NETZ

Refit ist eine Bibliothek, die stark von der Retrofit-Bibliothek von Square und .__ inspiriert ist. Es verwandelt Ihre REST - API in eine Live-Schnittstelle:

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

ERHALTEN:

// 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:

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

Hinweis: Um JSON zu serialisieren und desirialze zu verwenden, habe ich das Paket Newtonsoft.Json NuGet verwendet.

3
JerryGoyal

Hier einige verschiedene Möglichkeiten zum Aufrufen einer externen API in C # (aktualisiert 2019).

. NET integrierte Möglichkeiten:

  • WebRequest & WebClient - Ausführliche APIs & Die Dokumentation von Microsoft ist nicht sehr einfach zu befolgen
  • HttpClient - .NETs neuestes Kind im Block & viel einfacher zu bedienen als oben.

Kostenlose Open-Source-NuGet-Pakete , die offen gesagt eine viel bessere Entwicklererfahrung aufweisen als die in .NET integrierten Clients:

  • ServiceStack.Text (1k Github-Stars, 7m Nuget-Downloads) (*) - schnell, leicht und belastbar.
  • RestSharp (6.000 Github-Sterne, 23 Millionen Nuget-Downloads) (*) - einfacher REST und HTTP-API-Client
  • Flurl (1.7k Github-Sterne, 3m Nuget-Downloads) (*) - Eine fließende, portable, testbare HTTP-Client-Bibliothek

Alle oben genannten Pakete bieten eine hervorragende Entwicklererfahrung (dh eine übersichtliche, einfache API) und sind gut gepflegt.

(*) Stand August 2019

Beispiel: Abrufen eines Todo-Elements von einer Fake Rest-API mithilfe von ServiceStack.Text. Die anderen Bibliotheken haben eine sehr ähnliche Syntax.

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

}

Wenn Sie das obige Beispiel in einer .NET Core Console-App ausführen, wird die folgende Ausgabe erstellt.

enter image description here

Installiere diese Pakete mit NuGet

Install-Package ServiceStack.Text, or

Install-Package RestSharp, or

Install-Package Flurl.Http
3
Mark H

Dies ist ein Beispielcode, der sicher funktioniert. Es dauerte einen Tag, bis ich einen Satz von Objekten aus dem Rest-Service gelesen hatte:

RootObject ist der Typ des Objekts, das Im vom Rest-Service liest. 

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
user4064093

Ich möchte meine Lösung in ASP.NET Core freigeben

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

Um einen Beitrag zu posten, verwenden Sie Folgendes:

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

Beispiel zum Löschen:

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

Beispiel für eine Liste:

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

Beispiel, um nur einen zu erhalten:

ClaimTerm processedClaimImage = await HttpHelper.Get<ClaimTerm>($"/api/values/{id}");
1
Raskolnikov
    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 [email protected]"<root><childnodes>passing parameters</childnodes></root>";
    string [email protected]"<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
rajendra lenka

Ich habe es auf diese einfache Weise mit Web Api 2.0 ... gemacht.

            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
MNF

Da Sie Visual Studio 11 Beta verwenden, sollten Sie das Neueste und Beste verwenden. Die neue Web-API enthält hierfür Klassen.

Siehe HttpClient: http://wcf.codeplex.com/wikipage?title=WCF%20HTTP

0
dice