Verbesserte Schnellstartfunktion

Dieser Artikel zeigt, wie Sie den Code in dem Schnellstartartikel umgestalten können, indem Sie wiederverwendbare HttpClient und Fehlerbehandlungsmethoden hinzufügen. Führen Sie die Schritte im Schnellstartartikel durch, um ein neues Visual Studio-Projekt zu erstellen, bevor Sie mit diesem Artikel beginnen. Alternativ können Sie die MSAL-Version des vollständigen Visual Studio-Projekts herunterladen.

Wenn Sie nach diesem verbesserten Schnellstart nicht weiterkommen, können Sie die komplette Lösung herunterladen.

Aktivieren der Übergabe von Anmeldeinformationen in einer Verbindungszeichenfolge

Das Einfügen von Benutzeranmeldeinformationen in Ihren Code ist keine gute Vorgehensweise. Wie Sie die Benutzeranmeldeinformationen erfassen, hängt vom Typ des Clients ab, den Sie erstellen. Für diese Konsolenanwendung werden wir die Anmeldeinformationen innerhalb der App.config-Datei festlegen, da es eine bequeme Möglichkeit ist, die Anmeldeinformationen aus dem Code zu verschieben. Es ist auch die Methode, die in den Web-API-Datenoperationen Samples (C#) verwendet wird, sodass Sie, wenn Sie diese Methode verstehen, leicht sehen können, wie die anderen Web-API-Beispiele funktionieren.

Um die Übergabe dieser Anmeldeinformationen zu ermöglichen, sind drei Schritte erforderlich:

  1. Das System.Configuration.ConfigurationManager NuGet-Paket zum Visual Studio-Projekt hinzufügen
  2. Eine Anwendungskonfigurationsdatei hinzufügen
  3. Eine using-Direktive in Program.cs hinzufügen

Das System.Configuration.ConfigurationManager NuGet-Paket zum Visual Studio-Projekt hinzufügen

  1. Klicken Sie im Projektmappen-Explorer mit der rechten Maustaste auf Abhängigkeiten und wählen Sie im Kontextmenü NuGet-Pakete verwalten aus.
  2. Suchen Sie nach dem NuGet-Paket namens System.Configuration.ConfigurationManager, wählen Sie es aus, und wählen Sie dann Installieren aus.

Das System.Configuration.ConfigurationManager-Paket installieren

Eine Anwendungskonfigurationsdatei hinzufügen

  1. Klicken Sie im Projektmappen-Explorer mit der rechten Maustaste auf das Projekt, und wählen Sie „Hinzufügen > Neues Element“ aus.

  2. Wählen Sie Anwendungskonfigurationsdatei aus.

    Durch diese Schritte wird eine neue Datei mit dem Namen App.config in Ihrem Projekt erstellt.

  3. Öffnen Sie im Lösungs-Explorer die Datei App.config. Sie sollte ungefähr so aussehen:

    <?xml version="1.0" encoding="utf-8" ?>
    <configuration>
    </configuration>
    
  4. Bearbeiten Sie das Element <configuration>, um den Knoten connectionStrings hinzuzufügen, wie unten gezeigt:

    <?xml version="1.0" encoding="utf-8" ?>
       <configuration>
       <!--Online using Microsoft 365-->
       <add name="Connect"
             connectionString="Url=https://yourorg.api.crm.dynamics.com;Username=yourname@yourorg.onmicrosoft.com;Password=mypassword;" />
    </connectionStrings>
    </configuration>
    

Dadurch entsteht eine Verbindungszeichenfolge, die namentlich referenziert werden kann, in diesem Fall Connect, sodass Sie bei Bedarf mehr als eine Verbindung definieren können.

Bearbeiten Sie die Werte für die Verbindungszeichenfolge Url, Username und Password in den connectionString-Parameter so, dass sie mit dem übereinstimmen, was Sie für die Verbindung zu Ihrer Microsoft Dataverse-Testumgebung benötigen.

Hinzufügen von Using-Direktiven zu Program.cs

Fügen Sie oben in Ihrer Program.cs-Datei diese using-Direktive hinzu:

using System.Configuration;

Helfercode hinzufügen

Im Schnellstartbeispiel befindet sich der gesamte Code innerhalb der Datei Program.cs. Wir werden den Code, der sich mit dem Verbinden und Erstellen von HttpClient beschäftigt, in eine separate Datei mit Hilfsmethoden verschieben.

Diese Helfer werden auch in der SampleHelper.cs-Datei verwendet, die von den Web-API-Datenoperationen Samples (C#) verwendet wird. Wenn Sie diese Helfer verstehen, werden Sie verstehen, wie sie in den Beispielen verwendet werden.

  1. Klicken Sie im Projektmappen-Explorer mit der rechten Maustaste auf Ihr Projekt und wählen Sie Hinzufügen > Klasse... aus (oder drücken Sie Shift+Alt+C), um das Dialogfenster Neues Element hinzufügen zu öffnen.

  2. Geben Sie einen Namen für Ihre Klassendatei an. Um dem Muster zu folgen, das von den Web-API-Datenoperationen Samples (C#) verwendet wird, nennen Sie es SampleHelpers.cs.

    Hinweis

    Der Name der Klasse bestimmt, wie Sie auf diese Hilfseigenschaften und Methoden innerhalb Ihres Hauptprogramms verweisen. Die restlichen Anweisungen gehen davon aus, dass Sie die Klasse SampleHelpers benannt haben.

  3. Fügen Sie Ihrer SampleHelpers.cs-Datei den folgenden Code hinzu.

    
    using System;
    using System.Linq;
    using System.Net.Http;
    
    namespace EnhancedQuickStart
    {
    /// <summary>
    /// Shared code for common operations used by many Power Apps samples.
    /// </summary>
    class SampleHelpers
    {
          //These sample application registration values are available for all online instances.
          //You can use these while running sample code, but you should get your own for your own apps
          public static string clientId = "51f81489-12ee-4a9e-aaae-a2591f45987d";
          public static string redirectUrl = "app://58145B91-0C36-4500-8554-080854F2AC97";
    
          /// <summary>
          /// Method used to get a value from the connection string
          /// </summary>
          /// <param name="connectionString"></param>
          /// <param name="parameter"></param>
          /// <returns>The value from the connection string that matches the parameter key value</returns>
          public static string GetParameterValueFromConnectionString(string connectionString, string parameter)
          {
             try
             {
                return connectionString.Split(';').Where(s => s.Trim().StartsWith(parameter)).FirstOrDefault().Split('=')[1];
             }
             catch (Exception)
             {
                return string.Empty;
             }
          }
    
          /// <summary>
          /// Returns an HttpClient configured with an OAuthMessageHandler
          /// </summary>
          /// <param name="connectionString">The connection string to use.</param>
          /// <param name="clientId">The client id to use when authenticating.</param>
          /// <param name="redirectUrl">The redirect Url to use when authenticating</param>
          /// <param name="version">The version of Web API to use. Defaults to version 9.2 </param>
          /// <returns>An HttpClient you can use to perform authenticated operations with the Web API</returns>
          public static HttpClient GetHttpClient(string connectionString, string clientId, string redirectUrl, string version = "v9.2")
          {
             string url = GetParameterValueFromConnectionString(connectionString, "Url");
             string username = GetParameterValueFromConnectionString(connectionString, "Username");
             string password = GetParameterValueFromConnectionString(connectionString, "Password");
             try
             {
                HttpMessageHandler messageHandler = new OAuthMessageHandler(url, clientId, redirectUrl, username, password,
                               new HttpClientHandler());
    
                HttpClient httpClient = new HttpClient(messageHandler)
                {
                      BaseAddress = new Uri(string.Format("{0}/api/data/{1}/", url, version)),
    
                      Timeout = new TimeSpan(0, 2, 0)  //2 minutes
                };
    
                return httpClient;
             }
             catch (Exception)
             {
                throw;
             }
          }
    
          /// <summary> Displays exception information to the console. </summary>
          /// <param name="ex">The exception to output</param>
          public static void DisplayException(Exception ex)
          {
             Console.WriteLine("The application terminated with an error.");
             Console.WriteLine(ex.Message);
             while (ex.InnerException != null)
             {
                Console.WriteLine("\t* {0}", ex.InnerException.Message);
                ex = ex.InnerException;
             }
          }
    }
    }
    
  4. Fügen Sie die Klasse OAuthMessageHandler in einer eigenen Klassendatei mit dem unten angegebenen Code hinzu.

    Diese Klasse stellt sicher, dass das Zugriffstoken bei jeder Ausführung einer Aktion aktualisiert wird. Jeder Zugriffstoken verfällt nach etwa einer Stunde. Diese Klasse implementiert ein DelegatingHandler, das mit dem Authentifizierungskontext der Microsoft-Authentifizierungsbibliothek (MSAL) funktioniert, um die richtige AcquireToken-Variante jedes Mal aufzurufen, wenn ein Vorgang ausgeführt wird, so dass Sie den Ablauf von Token nicht explizit verwalten müssen.

    using Microsoft.Identity.Client;
    using System.Net.Http;
    using System.Net.Http.Headers;
    using System.Security;
    using System.Threading.Tasks;
    
    namespace EnhancedQuickStart
    {
    /// <summary>
    /// Custom HTTP message handler that uses OAuth authentication through
    /// Microsoft Authentication Library (MSAL).
    /// </summary>
    class OAuthMessageHandler : DelegatingHandler
    {
          private AuthenticationHeaderValue authHeader;
    
          public OAuthMessageHandler(string serviceUrl, string clientId, string redirectUrl, string username, string password,
                HttpMessageHandler innerHandler)
             : base(innerHandler)
          {
    
             string apiVersion = "9.2";
             string webApiUrl = $"{serviceUrl}/api/data/v{apiVersion}/";
    
             //Build Microsoft.Identity.Client (MSAL) OAuth Token Request
             var authBuilder = PublicClientApplicationBuilder.Create(clientId)
                            .WithAuthority(AadAuthorityAudience.AzureAdMultipleOrgs)
                            .WithRedirectUri(redirectUrl)
                            .Build();
             var scope = serviceUrl + "//.default";
             string[] scopes = { scope };
    
             AuthenticationResult authBuilderResult;
             if (username != string.Empty && password != string.Empty)
             {
                //Make silent Microsoft.Identity.Client (MSAL) OAuth Token Request
                var securePassword = new SecureString();
                foreach (char ch in password) securePassword.AppendChar(ch);
                authBuilderResult = authBuilder.AcquireTokenByUsernamePassword(scopes, username, securePassword)
                            .ExecuteAsync().Result;
             }
             else
             {
                //Popup authentication dialog box to get token
                authBuilderResult = authBuilder.AcquireTokenInteractive(scopes)
                            .ExecuteAsync().Result;
             }
    
             //Note that an Azure AD access token has finite lifetime, default expiration is 60 minutes.
             authHeader = new AuthenticationHeaderValue("Bearer", authBuilderResult.AccessToken);
          }
    
          protected override Task<HttpResponseMessage> SendAsync(
                   HttpRequestMessage request, System.Threading.CancellationToken cancellationToken)
          {
             request.Headers.Authorization = authHeader;
             return base.SendAsync(request, cancellationToken);
          }
    }
    }
    

Program.cs aktualisieren

Nachdem Sie nun die Änderungen an Aktivieren der Übergabe von Anmeldeinformationen in einer Verbindungszeichenfolge und Helfercode hinzufügen vorgenommen haben, können Sie die Methode Main in der Program.cs-Datei aktualisieren, um nur Folgendes zu enthalten:

using Newtonsoft.Json.Linq;
using System;
using System.Configuration;
using System.Net.Http;

namespace EnhancedQuickStart
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                //Get configuration data from App.config connectionStrings
                string connectionString = ConfigurationManager.ConnectionStrings["Connect"].ConnectionString;

                using (HttpClient client = SampleHelpers.GetHttpClient(connectionString, SampleHelpers.clientId, SampleHelpers.redirectUrl))
                {
                    // Use the WhoAmI function
                    var response = client.GetAsync("WhoAmI").Result;

                    if (response.IsSuccessStatusCode)
                    {
                        //Get the response content and parse it.
                        JObject body = JObject.Parse(response.Content.ReadAsStringAsync().Result);
                        Guid userId = (Guid)body["UserId"];
                        Console.WriteLine("Your UserId is {0}", userId);
                    }
                    else
                    {
                        Console.WriteLine("The request failed with a status of '{0}'",
                                    response.ReasonPhrase);
                    }
                    Console.WriteLine("Press any key to exit.");
                    Console.ReadLine();
                }
            }
            catch (Exception ex)
            {
                SampleHelpers.DisplayException(ex);
                Console.WriteLine("Press any key to exit.");
                Console.ReadLine();
            }
        }
    }
}

Dies ist weniger Code und Sie haben eine Fehlerbehandlung und die Möglichkeit hinzugefügt, das Zugriffstoken bei jeder Verwendung der HttpClient zu aktualisieren.

Sie werden jedoch sehen, dass JObject rote Wellenlinien darunter hat. Wenn Sie versuchen, dieses Projekt zu erstellen, wird es scheitern.

Der Schnellstart verwendete System.Text.Json, aber dieser Code verwendet NewtonSoft.

NewtonSoft.Json installieren

  1. Klicken Sie mit der rechten Maustaste auf JObject mit den roten Wellenlinien darunter und wählen Sie Schnellaktionen und Refactorings....
  2. Wählen Sie Paket „Newtonsoft.Json“ installieren > Nach aktueller Version suchen und diese installieren aus.

Ausführen des Programms

Drücken Sie F5, um das Programm auszuführen. Genau wie das Schnellstartbeispiel sollte die Ausgabe so aussehen:

Your UserId is 969effb0-98ae-478c-b547-53a2968c2e75
Press any key to exit.

Erstellen von wiederverwendbaren Methoden

Während wir die Gesamtmenge des Codes in der Methode Program.Main reduziert haben, werden Sie kein Programm schreiben, um nur eine Operation aufzurufen, und es ist nicht realistisch, so viel Code zu schreiben, nur um eine einzelne Operation aufzurufen.

Dieser Abschnitt zeigt, wie Sie dies ändern können:

var response = client.GetAsync("WhoAmI").Result;

if (response.IsSuccessStatusCode)
{
  //Get the response content and parse it.
  JObject body = JObject.Parse(response.Content.ReadAsStringAsync().Result);
  Guid userId = (Guid)body["UserId"];
  Console.WriteLine("Your UserId is {0}", userId);
}
else
{
  Console.WriteLine("The request failed with a status of '{0}'",
      response.ReasonPhrase);
}

für dies:

WhoAmIResponse response = WhoAmI(client);
      Console.WriteLine("Your system user ID is: {0}", response.UserId);

Bevor Sie beginnen, ist es eine gute Idee, die Web-API-Referenz aufzurufen und diese Artikel zu überprüfen:

Beachten Sie, wie die WhoAmI-Funktion ein WhoAmIResponse ComplexType zurückgibt und WhoAmIResponse ComplexType drei GUID-Eigenschaften enthält: BusinessUnitId, UserId und OrganizationId;

Der Code, den wir hinzufügen werden, besteht einfach darin, die Funktion in eine wiederverwendbare Methode zu modellieren, die ein HttpClient als Parameter akzeptiert.

Hinweis

Wie Sie das genau machen, ist eine Frage der persönlichen Präferenz. Dieses Design wird wegen seiner relativen Einfachheit angeboten.

Führen Sie in Ihrem Visual Studio-Projekt die folgenden Schritte aus:

  1. Bearbeiten Sie die Klasse Program, um sie zu einer Teilklasse zu machen.

    Oben angekommen, ändern Sie dies:

    class Program

    Und profitieren Sie von:

    partial class Program

  2. Erstellen Sie eine neue Klassendatei mit dem Namen ProgramMethods.cs

    Ändern Sie dies unter ProgramMethods.cs:

    class ProgramMethods

    Und profitieren Sie von:

    partial class Program

    Auf diese Weise ist die Klasse Program in der Datei ProgramMethods.cs nur eine Erweiterung der ursprünglichen Klasse Program in der Datei Program.cs.

  3. Fügen Sie Folgendes mithilfe der Direktiven an den Anfang der ProgramMethods.cs-Datei ein.

    using Newtonsoft.Json.Linq;
    using System;
    using System.Net.Http;
    
  4. Fügen Sie die folgende Methode zur Klasse Program in der ProgramMethods.cs-Datei hinzu.

    public static WhoAmIResponse WhoAmI(HttpClient client) {
      WhoAmIResponse returnValue = new WhoAmIResponse();
      //Send the WhoAmI request to the Web API using a GET request.
      HttpResponseMessage response = client.GetAsync("WhoAmI",
              HttpCompletionOption.ResponseHeadersRead).Result;
      if (response.IsSuccessStatusCode)
      {
          //Get the response content and parse it.
          JObject body = JObject.Parse(response.Content.ReadAsStringAsync().Result);
          returnValue.BusinessUnitId = (Guid)body["BusinessUnitId"];
          returnValue.UserId = (Guid)body["UserId"];
          returnValue.OrganizationId = (Guid)body["OrganizationId"];
      }
      else
      {
          throw new Exception(string.Format("The WhoAmI request failed with a status of '{0}'",
                  response.ReasonPhrase));
      }
      return returnValue;
    }
    
  5. Füge die folgende Klasse außerhalb der Klasse Program hinzu, aber innerhalb des Namensraums der Datei ProgramMethods.cs.

    public class WhoAmIResponse
    {
        public Guid BusinessUnitId { get; set; }
        public Guid UserId { get; set; }
        public Guid OrganizationId { get; set; }
    }
    
  6. Bei der Methode Program.Main in der Programm.cs-Originaldatei:

    Ersetzen Sie dies:

    var response = client.GetAsync("WhoAmI").Result;
    
    if (response.IsSuccessStatusCode)
    {
      //Get the response content and parse it.
      JObject body = JObject.Parse(response.Content.ReadAsStringAsync().Result);
      Guid userId = (Guid)body["UserId"];
      Console.WriteLine("Your UserId is {0}", userId);
    }
    else
    {
      Console.WriteLine("The request failed with a status of '{0}'",
                  response.ReasonPhrase);
    }
    

    Damit:

    WhoAmIResponse response = WhoAmI(client);
    Console.WriteLine("Your system user ID is: {0}", response.UserId);
    
  7. Drücken Sie F5, um das Beispiel auszuführen, und Sie sollten die gleichen Ergebnisse wie zuvor erhalten.

Problembehandlung

Wenn Sie Probleme beim Ausführen dieses Beispiels haben, können Sie alle Power Apps Beispiele aus dem GitHub-Repository unter https://github.com/Microsoft/PowerApps-Samples herunterladen.

Wichtig

Alle Beispiele im GitHub-Repository sind so konfiguriert, dass sie eine gemeinsame App.config verwenden, die sich unter PowerApps Beispiele: cds\App.config befinden. Wenn Sie Ihre Verbindungszeichenfolge festlegen, müssen Sie diese Datei bearbeiten. Wenn Sie dies tun, können Sie alle Samples ausführen, ohne Ihre Anmeldeinformationen erneut festzulegen.

Erstellen eines Template-Projekts

Bevor Sie diesen Artikel verlassen, sollten Sie darüber nachdenken, das Projekt als Projektvorlage zu speichern. Sie können die Vorlage dann wieder für zukünftige Lernprojekte verwenden und sich etwas Zeit und Aufwand bei der Erstellung neue Projekte ersparen. Wählen Sie dazu im Menü Datei die Option Exportvorlage, aus, während das Projekt in Microsoft Visual Studio geöffnet ist. Befolgen Sie Anweisungen des Vorlagenexportassistenten zum Erstellen der Vorlage.

Nächste Schritte

Verwenden Sie die folgenden Ressourcen, um mehr zu erfahren:

Hinweis

Können Sie uns Ihre Präferenzen für die Dokumentationssprache mitteilen? Nehmen Sie an einer kurzen Umfrage teil. (Beachten Sie, dass diese Umfrage auf Englisch ist.)

Die Umfrage dauert etwa sieben Minuten. Es werden keine personenbezogenen Daten erhoben. (Datenschutzbestimmungen).