Laden...

c# JSON Api für Personio

Erstellt von ChrisBa vor 2 Jahren Letzter Beitrag vor 2 Jahren 929 Views
C
ChrisBa Themenstarter:in
54 Beiträge seit 2011
vor 2 Jahren
c# JSON Api für Personio

Hallo zusammen.
Ich muss Daten per Api aus der Software Personio. The People Operating System. ziehen.
Dazu habe ich einen Test-Account bei Personio.de erstellt.

Mein Problem ist, dass ich mit dieser Materie noch gar nichts am Hut habe...

Ich habe dazu folgenden Code in einer Consolenanwendung, der mit den Fehler "401 (Unauthorized)" liefert.
Wie gesagt, ich habe hierzu leider überhaupt keine Ahnung und bin deshalb für jede Hilfe dankbar.
Übrigens, die Variablen client_id & client_secret sind auch die richtigen für meinen Test-Account bei Personio.de. Zudem habe ich einen Screenshot von Personio angeheftet und es gibt auch eine Doku (https://developer.personio.de/reference), die mir nichts bringt.


class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("*** START ***");
            Console.WriteLine("");

            GetPersonen();

            Console.WriteLine("");
            Console.WriteLine("*** END ***");
            Console.ReadLine();
        }

        private const string URL = "https://api.personio.de/v1/company/employees?limit=300&offset=0";
        private static string client_id = "xxxx";
        private static string client_secret = "xxxxxxxx";

        public static async void GetPersonen()
        {
            using (var client = new HttpClient())
            {
                client.BaseAddress = new Uri(URL);
                client.DefaultRequestHeaders.Accept.Clear();
                client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
                client.DefaultRequestHeaders.Add("client_id", client_id);
                client.DefaultRequestHeaders.Add("client_secret", client_secret);

                var responseTask = client.GetAsync("employees");
                responseTask.Wait();

                var result = responseTask.Result;
                if (result.IsSuccessStatusCode)
                {

                    var readTask = result.Content.ReadAsAsync<Person[]>();
                    readTask.Wait();

                    var personen = readTask.Result;

                    foreach (var person in personen)
                    {
                        Console.WriteLine(person.Nachname);
                    }
                }
                else
                {
                    Console.WriteLine("{0} ({1})", (int)result.StatusCode, result.ReasonPhrase);
                }
            }
        }
    }

    public class Person
    {
        public string Vorname
        {
            get;
            set;
        }

        public string Nachname
        {
            get;
            set;
        }
    }

Das Schicksal bevorzugt jene die bereit sind.

16.806 Beiträge seit 2008
vor 2 Jahren

Also erstens: poste keine Credentials in Foren.
Ich habe die Credentials aus Deinem Beitrag gelöscht, Du solltest sie trotzdem zurück setzen.

Mein Problem ist, dass ich mit dieser Materie noch gar nichts am Hut habe...

Das ist völlig normal, aber es bietet sich immer an, dass man erstmal etwas dazu liest, statt blind loszulegen. Das Wissen kommt Dir nicht zugeflogen, das musst Dir schon selbst holen. 🙂
Gerade bei REST APIs gibts fertige Bibliotheken, wie zB. Refit, die einem sehr viel Arbeit und auch die Authentifizierung sowie vor allem die Fehlerbehandlung und Kommunikation abnehmen.

Ansonsten hat Dein Code auch auf den wenigen Code schon viel konzeptionelle Fehler, zB Dein Wait bei einem Task (das kann in der Form Deadlocks und damit in Folge zum Absturz führen), oder das using um den HttpClient.

C
ChrisBa Themenstarter:in
54 Beiträge seit 2011
vor 2 Jahren

Hallo und Danke für die Antwort.
Ich dachte ich kann die Credentials anzeigen, da es sich ja um einen Test-Account handelt....
Über Refit werde ich mich gleich mal schlau machen.
Sonst noch Tipps?

Das Schicksal bevorzugt jene die bereit sind.

16.806 Beiträge seit 2008
vor 2 Jahren

Credentials sind Credentials. Behandle sie als solches, egal von was. 😉

C
ChrisBa Themenstarter:in
54 Beiträge seit 2011
vor 2 Jahren

Hallo, der Support von Personio hat mir nun geschrieben:

Eine API-Request muss durch einen Bearer-Token verifiziert werden, der für jede neue Anfrage im Vorfeld neu abgerufen/generiert werden muss.

Weiter Auskunft oder Hilfe kann er mir dazu aber nicht geben.

Wie mache ich denn so einen Bearer-Token-Verifizierung auf meinen Code bezogen?

Das Schicksal bevorzugt jene die bereit sind.

87 Beiträge seit 2016
vor 2 Jahren
16.806 Beiträge seit 2008
vor 2 Jahren

Wie mache ich denn so einen Bearer-Token-Verifizierung auf meinen Code bezogen?

Sorry, das so deutlich zu sagen, aber den Code kannst wegwerfen 🙂
Nimm ein REST Package (zB Refit), schau in dessen Doku: die haben alle Bearer-Token Support.

Personio ist ein personen-bezogener Service - Du unterliegst damit sehr strengen DSGVO Regeln.
Eine Lücke in Deinem Code kann euch (finanziell) extrem weh tun.
Also les besser 1-2 Dokumentationen, bevor Du irgendwas hin klatschst. Dir wird das nicht zugeflogen kommen.
Machs ordentlich. 🙂

C
ChrisBa Themenstarter:in
54 Beiträge seit 2011
vor 2 Jahren

Alles klar. Danke für eure Hilfe.
Das hier ist damit geschlossen.

Das Schicksal bevorzugt jene die bereit sind.

C
ChrisBa Themenstarter:in
54 Beiträge seit 2011
vor 2 Jahren

Jetzt habe ich doch noch einen Nachbrenner....

Also, ich habs jetzt hin bekommen, dass ich die gewünschten Infos als JSON-String erhalte...
Nun stellt sich mir die Frage wie genau ich die richtigen Infos aus dem JSON-String erhalte.

Mein Versuch:


public static void GetPersonen(string token)
        {
            var httpRequest = (HttpWebRequest)WebRequest.Create(string.Format("{0}&client_id={1}&client_secret={2}", EmployeesURL, Client_id, Client_secret));
            httpRequest.Accept = "application/json";
            httpRequest.Headers["Authorization"] = "Bearer " + token;


            var httpResponse = (HttpWebResponse)httpRequest.GetResponse();
            using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
            {
                var jsonData = streamReader.ReadToEnd();

               
                JObject jObject = JObject.Parse(jsonData);

                foreach (var data in jObject["data"])
                {
                    foreach (var attributes in data["attributes"])
                    {
                        var firstname = attributes.SelectToken("first_name");
                        var value = firstname.SelectToken("value");
                        Console.WriteLine(value.Value<string>("value"));
                    }

                }
            }
        }

Aus dem JSON-String, siehe Anhang.

Das Schicksal bevorzugt jene die bereit sind.

P
441 Beiträge seit 2014
vor 2 Jahren

Erstelle dir eine Klasse (dafür gibt es Generatoren, die aus dem JSON C# Code erstellen) und lass es dir in diese deserialisieren.

Das würde dir übrigens auch eine Bibliothek wie Refit abnehmen.

Übrigens: der HttpWebRequest, den du verwendest ist veraltet (auch das würde dir refit abnehmen).

16.806 Beiträge seit 2008
vor 2 Jahren

string.Format("{0}&client_id={1}&client_secret={2}", EmployeesURL, Client_id, Client_secret)

Client Id und Client Secret via GET Parameter...
Genau so entstehen Sicherheitslücken. Herzlichen Glückwunsch 🙂

Edit: wow, das steht sogar als GET in der Dokumentation von Personio.
Ich schreibe denen mal...

C
ChrisBa Themenstarter:in
54 Beiträge seit 2011
vor 2 Jahren

Kann mir bitte jemand helfen?

Ich bekomme den Fehler: "The JSON value could not be converted to System.String. Path: $.success | LineNumber: 0 | BytePositionInLine: 15."
Bei diesem Code:


public static void GetPersonen(string token)
        {
            var httpRequest = (HttpWebRequest)WebRequest.Create(string.Format("{0}&client_id={1}&client_secret={2}", EmployeesURL, Client_id, Client_secret));
            httpRequest.Accept = "application/json";
            httpRequest.Headers["Authorization"] = "Bearer " + token;


            var httpResponse = (HttpWebResponse)httpRequest.GetResponse();
            using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
            {
                var jsonData = streamReader.ReadToEnd();


                var mitarbeiter = System.Text.Json.JsonSerializer.Deserialize<Mitarbeiter>(jsonData);
                Console.WriteLine(mitarbeiter.data.attributes.first_name.value);
            }
        }

Mit diesen Klassen:


public class Mitarbeiter
    {
        public string success { get; set; }
        public Data data { get; set; }
    }

    public class Data 
    {
        public string type { get; set; }
        public Attributes attributes { get; set; }
    }

    public class Attributes
    {
        public string type { get; set; }
        public Id id { get; set; }
        public FirstName first_name { get; set; }
    }

    public class Id
    {
        public string label { get; set; }
        public int value { get; set; }
        public string type { get; set; }
        public string universal_id { get; set; }
    }

    public class FirstName
    {
        public string label { get; set; }
        public string value { get; set; }
        public string type { get; set; }
        public string universal_id { get; set; }
    }

Das Schicksal bevorzugt jene die bereit sind.

187 Beiträge seit 2009
vor 2 Jahren

Kann mir bitte jemand helfen?

Ich bekomme den Fehler: "The JSON value could not be converted to System.String. Path: $.success | LineNumber: 0 | BytePositionInLine: 15."
Bei diesem Code:

  
public class Mitarbeiter  
    {  
        public string success { get; set; }  
        public Data data { get; set; }  
    }  
  

Ändere die Mitarbeiterklasse wie folgt:


public class Mitarbeiter
    {
        public bool success { get; set; }
        public Data data { get; set; }
    }

C
ChrisBa Themenstarter:in
54 Beiträge seit 2011
vor 2 Jahren

Besten Dank für die Hilfe.
Funktioniert nun. Kann geschlossen werden.

Das Schicksal bevorzugt jene die bereit sind.