Verwenden des verwalteten Clients für Azure Mobile AppsHow to use the managed client for Azure Mobile Apps

Hinweis

Visual Studio App Center unterstützt End-to-End- und integrierte Dienste, die für die Entwicklung mobiler Apps von zentraler Bedeutung sind.Visual Studio App Center supports end to end and integrated services central to mobile app development. Entwickler können Build-, Test- und Verteilungsdienste nutzen, um eine Pipeline für Continuous Integration und Delivery einzurichten.Developers can use Build, Test and Distribute services to set up Continuous Integration and Delivery pipeline. Nach der Bereitstellung der App können Entwickler den Status und die Nutzung ihrer App mithilfe der Analyse- und Diagnosedienste überwachen und mit Benutzern über den Pushdienst interagieren.Once the app is deployed, developers can monitor the status and usage of their app using the Analytics and Diagnostics services, and engage with users using the Push service. Entwickler können auch den Authentifizierungsdienst nutzen, um ihre Benutzer zu authentifizieren, und den Datendienst, um App-Daten dauerhaft in der Cloud zu speichern und zu synchronisieren.Developers can also leverage Auth to authenticate their users and Data service to persist and sync app data in the cloud.

Falls Sie Clouddienste in Ihre mobile Anwendung integrieren möchten, sollten Sie sich noch heute für App Center registrieren.If you are looking to integrate cloud services in your mobile application, sign up with App Center today.

ÜbersichtOverview

In dieser Anleitung wird die Ausführung gängiger Aufgaben mithilfe der verwalteten Clientbibliothek für Mobile App Service-Apps unter Azure in Windows- und Xamarin-Apps beschrieben.This guide shows you how to perform common scenarios using the managed client library for Azure App Service Mobile Apps for Windows and Xamarin apps. Wenn Sie keine Erfahrungen mit Mobile Apps haben, sollten Sie eventuell zunächst das Tutorial Erstellen einer Windows-App absolvieren.If you are new to Mobile Apps, you should consider first completing the Azure Mobile Apps quickstart tutorial. In diesem Handbuch konzentrieren wir uns auf das clientseitige verwaltete SDK.In this guide, we focus on the client-side managed SDK. Weitere Informationen zu den serverseitigen SDKs für Mobile Apps finden Sie in der Dokumentation zum .NET Server SDK oder Node.js Server SDK.To learn more about the server-side SDKs for Mobile Apps, see the documentation for the .NET Server SDK or the Node.js Server SDK.

ReferenzdokumentationReference documentation

Die Referenzdokumentation für das Client-SDK finden Sie hier: .NET-Client-Referenz für Azure Mobile Apps.The reference documentation for the client SDK is located here: Azure Mobile Apps .NET client reference. Sie finden auch mehrere Clientbeispiele im GitHub-Repository „Azure Samples“(Azure Beispiele).You can also find several client samples in the Azure-Samples GitHub repository.

Unterstützte PlattformenSupported Platforms

Die .NET-Plattform unterstützt die folgenden Plattformen:The .NET Platform supports the following platforms:

  • Xamarin Android-Releases für API 19 bis 24 (KitKat bis Nougat)Xamarin Android releases for API 19 through 24 (KitKat through Nougat)
  • Xamarin iOS-Releases für iOS-Versionen 8.0 und höherXamarin iOS releases for iOS versions 8.0 and later
  • Universelle Windows-PlattformUniversal Windows Platform
  • Windows Phone 8.1Windows Phone 8.1
  • Windows Phone 8.0 außer für Silverlight-AnwendungenWindows Phone 8.0 except for Silverlight applications

Die Authentifizierung für den „Serverfluss“ verwendet eine Webansicht für die dargestellte Benutzeroberfläche.The "server-flow" authentication uses a WebView for the presented UI. Wenn das Gerät keine Benutzeroberfläche in Form einer Webansicht darstellen kann, sind andere Authentifizierungsmethoden erforderlich.If the device is not able to present a WebView UI, then other methods of authentication are needed. Dieses SDK eignet sich daher nicht für Geräte vom Typ „Überwachung“ oder für ähnlich eingeschränkte Geräte.This SDK is thus not suitable for Watch-type or similarly restricted devices.

Einrichtung und VoraussetzungenSetup and Prerequisites

Es wird davon ausgegangen, dass Sie Ihr Mobile App-Back-End-Projekt bereits erstellt und veröffentlicht haben und dass es mindestens eine Tabelle enthält.We assume that you have already created and published your Mobile App backend project, which includes at least one table. Der Code in diesem Thema verwendet eine Tabelle mit dem Namen TodoItem und den folgenden Spalten: Id, Text und Complete.In the code used in this topic, the table is named TodoItem and it has the following columns: Id, Text, and Complete. Dies ist die gleiche Tabelle, die Sie beim Durcharbeiten des Schnellstarttutorials für Azure Mobile Appserstellt haben.This table is the same table created when you complete the Azure Mobile Apps quickstart.

Der entsprechende typisierte clientseitige Typ in C# ist die folgende Klasse:The corresponding typed client-side type in C# is the following class:

public class TodoItem
{
    public string Id { get; set; }

    [JsonProperty(PropertyName = "text")]
    public string Text { get; set; }

    [JsonProperty(PropertyName = "complete")]
    public bool Complete { get; set; }
}

Das JsonPropertyAttribute wird verwendet, um die PropertyName-Zuordnung zwischen dem Clientfeld und dem Tabellenfeld zu definieren.The JsonPropertyAttribute is used to define the PropertyName mapping between the client field and the table field.

Informationen zum Erstellen von Tabellen in Ihrem Mobile Apps-Back-End finden Sie im Thema zum .NET Server SDK oder zum Node.js Server SDK.To learn how to create tables in your Mobile Apps backend, see the .NET Server SDK topic or the Node.js Server SDK topic. Wenn Sie Ihr Mobile App-Back-End im Azure-Portal mithilfe des Schnellstarts erstellt haben, können Sie auch die Einstellung Einfache Tabellen im Azure-Portalverwenden.If you created your Mobile App backend in the Azure portal using the QuickStart, you can also use the Easy tables setting in the Azure portal.

Gewusst wie: Installieren des SDK-Pakets für verwaltete ClientsHow to: Install the managed client SDK package

Verwenden Sie eine der folgenden Methoden, um das SDK-Paket für verwaltete Clients für Mobile Apps von NuGetzu installieren:Use one of the following methods to install the managed client SDK package for Mobile Apps from NuGet:

  • Visual Studio: Klicken Sie mit der rechten Maustaste auf Ihr Projekt, klicken Sie auf NuGet-Pakete verwalten, suchen Sie nach dem Microsoft.Azure.Mobile.Client-Paket, und klicken Sie anschließend auf Installieren.Visual Studio Right-click your project, click Manage NuGet Packages, search for the Microsoft.Azure.Mobile.Client package, then click Install.
  • Xamarin Studio: Klicken Sie mit der rechten Maustaste auf Ihr Projekt, klicken Sie auf Hinzufügen > NuGet-Pakete hinzufügen, suchen Sie nach dem Microsoft.Azure.Mobile.Client-Paket, und klicken Sie dann auf Paket hinzufügen.Xamarin Studio Right-click your project, click Add > Add NuGet Packages, search for the Microsoft.Azure.Mobile.Client package, and then click Add Package.

Denken Sie daran, in der Datei Ihrer Hauptaktivität die folgende using -Anweisung hinzuzufügen:In your main activity file, remember to add the following using statement:

using Microsoft.WindowsAzure.MobileServices;

Hinweis

Beachten Sie, dass alle Unterstützungspakete, auf die in Ihrem Android-Projekt verwiesen wird, die gleiche Version aufweisen müssen.Please note that all the support packages referenced in your Android project must have the same version. Das SDK hat eine Xamarin.Android.Support.CustomTabs-Abhängigkeit für die Android-Plattform. Wenn also Ihr Projekt neuere Unterstützungspakete verwendet, müssen Sie dieses Paket direkt mit der erforderlichen Version installieren, um Konflikte zu vermeiden.The SDK has Xamarin.Android.Support.CustomTabs dependency for Android platform, so if your project uses newer support packages you need to install this package with required version directly to avoid conflicts.

Vorgehensweise: Arbeiten mit Debugsymbolen in Visual StudioHow to: Work with debug symbols in Visual Studio

Die Symbole für den Namespace „Microsoft.Azure.Mobile“ sind unter SymbolSourceverfügbar.The symbols for the Microsoft.Azure.Mobile namespace are available on SymbolSource. Integrieren Sie SymbolSource gemäß den SymbolSource-Anweisungen in Visual Studio.Refer to the SymbolSource instructions to integrate SymbolSource with Visual Studio.

Erstellen des Mobile Apps-ClientsCreate the Mobile Apps client

Der folgende Code erstellt das MobileServiceClient -Objekt, das für den Zugriff auf Ihr Mobile App-Back-End verwendet wird.The following code creates the MobileServiceClient object that is used to access your Mobile App backend.

var client = new MobileServiceClient("MOBILE_APP_URL");

Ersetzen Sie im obigen Code MOBILE_APP_URL durch die URL des Mobile App-Back-Ends. Sie finden die URL auf dem Blatt für das Mobile App-Back-End im Azure-Portal.In the preceding code, replace MOBILE_APP_URL with the URL of the Mobile App backend, which is found in the blade for your Mobile App backend in the Azure portal. Beim MobileServiceClient-Objekt muss es sich um ein Singleton-Objekt handeln.The MobileServiceClient object should be a singleton.

Arbeiten mit TabellenWork with Tables

Der folgende Abschnitt enthält Informationen zum Suchen und Abrufen von Datensätzen sowie Ändern der Daten in der Tabelle.The following section details how to search and retrieve records and modify the data within the table. Die folgenden Themen werden behandelt:The following topics are covered:

Vorgehensweise: Erstellen eines TabellenverweisesHow to: Create a table reference

Jeglicher Code zum Abrufen oder Ändern von Daten in einer Back-End-Tabelle ruft Funktionen des MobileServiceTable -Objekts auf.All the code that accesses or modifies data in a backend table calls functions on the MobileServiceTable object. Rufen Sie einen Verweis auf die Tabelle ab, indem Sie wie folgt die Methode GetTable aufrufen:Obtain a reference to the table by calling the GetTable method, as follows:

IMobileServiceTable<TodoItem> todoTable = client.GetTable<TodoItem>();

Das zurückgegebene Objekt verwendet das typisierte Serialisierungsmodell.The returned object uses the typed serialization model. Ein nicht typisiertes Serialisierungsmodell wird ebenfalls unterstützt.An untyped serialization model is also supported. Das folgende Beispiel erstellt einen Verweis auf eine nicht typisierte Tabelle:The following example creates a reference to an untyped table:

// Get an untyped table reference
IMobileServiceTable untypedTodoTable = client.GetTable("TodoItem");

Bei nicht typisierten Abfragen müssen Sie die zugrunde liegende OData-Abfragezeichenfolge angeben.In untyped queries, you must specify the underlying OData query string.

Vorgehensweise: Abfragen von Daten aus Ihrer mobilen AppHow to: Query data from your Mobile App

Dieser Abschnitt beschreibt, wie Sie Abfragen an Ihr Mobile App-Back-End stellen können. Dies umfasst folgende Funktionen:This section describes how to issue queries to the Mobile App backend, which includes the following functionality:

Hinweis

Es wird die Verwendung einer servergesteuerten Seitengröße erzwungen, um zu verhindern, dass alle Zeilen zurückgegeben werden.A server-driven page size is enforced to prevent all rows from being returned. Durch Paging wird verhindert, dass Standardabfragen für große Datensätze den Dienst negativ beeinflussen.Paging keeps default requests for large data sets from negatively impacting the service. Verwenden Sie die Methoden Skip und Take, um mehr als 50 Zeilen zurückzugeben, wie unter Seitenweises Zurückgeben von Daten beschrieben.To return more than 50 rows, use the Skip and Take method, as described in Return data in pages.

Vorgehensweise: Filtern zurückgegebener DatenHow to: Filter returned data

Der folgende Code zeigt, wie Sie Daten mithilfe einer Where -Klausel in einer Abfrage filtern.The following code illustrates how to filter data by including a Where clause in a query. Die Abfrage gibt alle Elemente aus todoTable zurück, deren Complete-Eigenschaft gleich false ist.It returns all items from todoTable whose Complete property is equal to false. Die Where -Funktion wendet ein Zeilenfilterungsprädikat auf die Tabellenabfrage an.The Where function applies a row filtering predicate to the query against the table.

// This query filters out completed TodoItems and items without a timestamp.
List<TodoItem> items = await todoTable
    .Where(todoItem => todoItem.Complete == false)
    .ToListAsync();

Sie können den URI der an das Back-End gesendeten Anforderung anzeigen, indem Sie Software zur Überprüfung von Nachrichten verwenden, z. B. Browserentwicklertools oder Fiddler.You can view the URI of the request sent to the backend by using message inspection software, such as browser developer tools or Fiddler. Beachten Sie im Anforderungs-URI, dass die Abfragezeichenfolge verändert ist:If you look at the request URI, notice that the query string is modified:

GET /tables/todoitem?$filter=(complete+eq+false) HTTP/1.1

Diese OData-Anforderung wird vom Server-SDK in eine SQL-Abfrage übersetzt:This OData request is translated into an SQL query by the Server SDK:

SELECT *
    FROM TodoItem
    WHERE ISNULL(complete, 0) = 0

Die an die Where -Methode übergebene Funktion kann beliebig viele Bedingungen enthalten.The function that is passed to the Where method can have an arbitrary number of conditions.

// This query filters out completed TodoItems where Text isn't null
List<TodoItem> items = await todoTable
    .Where(todoItem => todoItem.Complete == false && todoItem.Text != null)
    .ToListAsync();

Dieses Beispiel würde vom Server-SDK in eine SQL-Abfrage übersetzt:This example would be translated into an SQL query by the Server SDK:

SELECT *
    FROM TodoItem
    WHERE ISNULL(complete, 0) = 0
          AND ISNULL(text, 0) = 0

Diese Abfrage kann auch in mehrere Klauseln aufgeteilt werden:This query can also be split into multiple clauses:

List<TodoItem> items = await todoTable
    .Where(todoItem => todoItem.Complete == false)
    .Where(todoItem => todoItem.Text != null)
    .ToListAsync();

Beide Methoden sind äquivalent und können frei austauschbar verwendet werden.The two methods are equivalent and may be used interchangeably. Die erste Option — Verketten mehrerer Prädikate in einer Abfrage — ist kompakter und wird daher empfohlen.The former option—of concatenating multiple predicates in one query—is more compact and recommended.

Die Where -Klausel unterstützt Vorgänge, die in die OData-Teilmenge übersetzt werden können.The Where clause supports operations that be translated into the OData subset. Folgende Vorgänge sind möglich:Operations include:

  • Relationale Operatoren (==, !=, <, <=, >, >=)Relational operators (==, !=, <, <=, >, >=),
  • Arithmetische Operatoren (+, -, /, *, %)Arithmetic operators (+, -, /, *, %),
  • Zahlengenauigkeit (Math.Floor, Math.Ceiling)Number precision (Math.Floor, Math.Ceiling),
  • Zeichenfolgenfunktionen (Length, Substring, Replace, IndexOf, StartsWith, EndsWith)String functions (Length, Substring, Replace, IndexOf, StartsWith, EndsWith),
  • Datumseigenschaften (Year, Month, Day, Hour, Minute, Second)Date properties (Year, Month, Day, Hour, Minute, Second),
  • Zugriff auf Eigenschaften eines ObjektsAccess properties of an object, and
  • Ausdrücke, die beliebige dieser Vorgänge kombinierenExpressions combining any of these operations.

Wenn Sie wissen möchten, was das Server-SDK unterstützt, lesen Sie die OData v3-Dokumentation.When considering what the Server SDK supports, you can consider the OData v3 Documentation.

Vorgehensweise: Sortieren zurückgegebener DatenHow to: Sort returned data

Der folgende Code zeigt, wie Sie Daten mithilfe einer OrderBy- oder einer OrderByDescending-Klausel in einer Abfrage sortieren können.The following code illustrates how to sort data by including an OrderBy or OrderByDescending function in the query. Die Abfrage gibt Elemente aus der Tabelle todoTable aufsteigend sortiert nach dem Text-Feld zurück.It returns items from todoTable sorted ascending by the Text field.

// Sort items in ascending order by Text field
MobileServiceTableQuery<TodoItem> query = todoTable
                .OrderBy(todoItem => todoItem.Text)
List<TodoItem> items = await query.ToListAsync();

// Sort items in descending order by Text field
MobileServiceTableQuery<TodoItem> query = todoTable
                .OrderByDescending(todoItem => todoItem.Text)
List<TodoItem> items = await query.ToListAsync();

Vorgehensweise: Seitenweises Zurückgeben von DatenHow to: Return data in pages

Standardmäßig gibt das Back-End nur die ersten 50 Zeilen zurück.By default, the backend returns only the first 50 rows. Sie können die Take -Methode aufrufen, um die Anzahl der zurückgegebenen Zeilen zu erhöhen.You can increase the number of returned rows by calling the Take method. Verwenden Sie Take zusammen mit der Skip -Methode, um eine bestimmte "Seite" des gesamten Datasets anzufordern, das von der Abfrage zurückgegeben wird.Use Take along with the Skip method to request a specific "page" of the total dataset returned by the query. Die folgende Abfrage liefert die ersten drei Elemente aus der Tabelle zurück.The following query, when executed, returns the top three items in the table.

// Define a filtered query that returns the top 3 items.
MobileServiceTableQuery<TodoItem> query = todoTable.Take(3);
List<TodoItem> items = await query.ToListAsync();

Die folgende geänderte Abfrage überspringt die ersten drei Ergebnisse und gibt die nächsten drei Ergebnisse zurück.The following revised query skips the first three results and returns the next three results. Diese Abfrage erzeugt die zweite „Seite“ der Daten für eine Seitengröße von drei Elementen.This query produces the second "page" of data, where the page size is three items.

// Define a filtered query that skips the top 3 items and returns the next 3 items.
MobileServiceTableQuery<TodoItem> query = todoTable.Skip(3).Take(3);
List<TodoItem> items = await query.ToListAsync();

Die IncludeTotalCount -Methode ruft die Gesamtanzahl für alle Datensätze ab, die bei Ignorieren aller angegebenen Paging-/Limit-Klauseln zurückgegeben worden wären:The IncludeTotalCount method requests the total count for all the records that would have been returned, ignoring any paging/limit clause specified:

query = query.IncludeTotalCount();

In tatsächlichen Apps können Sie ähnliche Abfragen wie im vorherigen Beispiel mit einem Pagingsteuerelement oder einer vergleichbaren Benutzeroberfläche ausführen, um zwischen Seiten zu navigieren.In a real world app, you can use queries similar to the preceding example with a pager control or comparable UI to navigate between pages.

Hinweis

Um die Begrenzung auf 50 Zeilen in einem Mobile App-Back-End zu überschreiben, müssen Sie EnableQueryAttribute auf die öffentliche GET-Methode anwenden und das Pagingverhalten festlegen.To override the 50-row limit in a Mobile App backend, you must also apply the EnableQueryAttribute to the public GET method and specify the paging behavior. Bei Anwendung des Attributs auf die Methode wird durch Folgendes die maximale Anzahl zurückgegebener Zeilen auf 1000 beschränkt:When applied to the method, the following sets the maximum returned rows to 1000:

[EnableQuery(MaxTop=1000)]

Vorgehensweise: Auswählen bestimmter SpaltenHow to: Select specific columns

Sie können angeben, welche Eigenschaften im Ergebnis enthalten sein sollen, indem Sie eine Select -Klausel zu Ihrer Abfrage hinzufügen.You can specify which set of properties to include in the results by adding a Select clause to your query. Der folgende Code zeigt, wie Sie nur ein Feld auswählen oder auch mehrere Felder auswählen und formatieren können:For example, the following code shows how to select just one field and also how to select and format multiple fields:

// Select one field -- just the Text
MobileServiceTableQuery<TodoItem> query = todoTable
                .Select(todoItem => todoItem.Text);
List<string> items = await query.ToListAsync();

// Select multiple fields -- both Complete and Text info
MobileServiceTableQuery<TodoItem> query = todoTable
                .Select(todoItem => string.Format("{0} -- {1}",
                    todoItem.Text.PadRight(30), todoItem.Complete ?
                    "Now complete!" : "Incomplete!"));
List<string> items = await query.ToListAsync();

Alle bisher beschriebenen Funktionen sind additiv, wir können also damit fortfahren, sie zu verketten.All the functions described so far are additive, so we can keep chaining them. Jeder verkettete Aufruf betrifft einen größeren Teil der Abfrage.Each chained call affects more of the query. Ein weiteres Beispiel:One more example:

MobileServiceTableQuery<TodoItem> query = todoTable
                .Where(todoItem => todoItem.Complete == false)
                .Select(todoItem => todoItem.Text)
                .Skip(3).
                .Take(3);
List<string> items = await query.ToListAsync();

Vorgehensweise: Abrufen von Daten nach IDHow to: Look up data by ID

Die LookupAsync -Funktion kann verwendet werden, um Objekte mit einer bestimmten ID aus der Datenbank abzufragen.The LookupAsync function can be used to look up objects from the database with a particular ID.

// This query filters out the item with the ID of 37BBF396-11F0-4B39-85C8-B319C729AF6D
TodoItem item = await todoTable.LookupAsync("37BBF396-11F0-4B39-85C8-B319C729AF6D");

Vorgehensweise: Ausführen nicht typisierter AbfragenHow to: Execute untyped queries

Beim Ausführen einer Abfrage mit einem nicht typisierten Tabellenobjekt müssen Sie die OData-Abfragezeichenfolge durch Aufruf von ReadAsyncexplizit angeben, wie im folgenden Beispiel veranschaulicht:When executing a query using an untyped table object, you must explicitly specify the OData query string by calling ReadAsync, as in the following example:

// Lookup untyped data using OData
JToken untypedItems = await untypedTodoTable.ReadAsync("$filter=complete eq 0&$orderby=text");

Sie erhalten JSON-Werte zurück, die Sie wie einen Eigenschaftenbehälter verwenden können.You get back JSON values that you can use like a property bag. Weitere Informationen zu JToken und Newtonsoft Json.NET finden Sie unter Json.NET .For more information on JToken and Newtonsoft Json.NET, see the Json.NET site.

Vorgehensweise: Einfügen von Daten in ein Mobile App-Back-EndHow to: Insert data into a Mobile App backend

Alle Clienttypen müssen einen Member mit dem Namen Id enthalten. Dies ist standardmäßig eine Zeichenfolge.All client types must contain a member named Id, which is by default a string. Diese Id ist für die Durchführung von CRUD-Vorgängen und die Offlinesynchronisierung erforderlich. Der folgende Code zeigt, wie Sie mit der InsertAsync-Methode neue Zeilen in eine Tabelle einfügen.This Id is required to perform CRUD operations and for offline sync. The following code illustrates how to use the InsertAsync method to insert new rows into a table. Der Parameter enthält die einzufügenden Daten als .NET-Objekt.The parameter contains the data to be inserted as a .NET object.

await todoTable.InsertAsync(todoItem);

Wenn während einer Einfügung kein eindeutiger benutzerdefinierter ID-Wert in das todoItem eingeschlossen wird, wird vom Server eine GUID generiert.If a unique custom ID value is not included in the todoItem during an insert, a GUID is generated by the server. Sie können die generierte ID abrufen, indem Sie das Objekt nach Rückgabe des Aufrufs untersuchen.You can retrieve the generated Id by inspecting the object after the call returns.

Zum Einfügen von nicht typisierten Daten können Sie Json.NET verwenden:To insert untyped data, you may take advantage of Json.NET:

JObject jo = new JObject();
jo.Add("Text", "Hello World");
jo.Add("Complete", false);
var inserted = await table.InsertAsync(jo);

Das folgende Beispiel verwendet eine E-Mail-Adresse als eindeutige ID-Zeichenfolge:Here is an example using an email address as a unique string id:

JObject jo = new JObject();
jo.Add("id", "myemail@emaildomain.com");
jo.Add("Text", "Hello World");
jo.Add("Complete", false);
var inserted = await table.InsertAsync(jo);

Arbeiten mit ID-WertenWorking with ID values

Mobile Apps unterstützt eindeutige benutzerdefinierte Zeichenfolgenwerte für die Spalte id der Tabelle.Mobile Apps supports unique custom string values for the table's id column. Mit einem Zeichenfolgenwert können Anwendungen benutzerdefinierte Werte wie E-Mail-Adressen oder Benutzernamen für die ID verwenden.A string value allows applications to use custom values such as email addresses or user names for the ID. Zeichenfolgen-IDs bieten Ihnen die folgenden Vorteile:String IDs provide you with the following benefits:

  • IDs werden ohne Roundtrip zur Datenbank generiert.IDs are generated without making a round trip to the database.
  • Datensätze aus unterschiedlichen Tabellen oder Datenbanken lassen sich leichter zusammenführen.Records are easier to merge from different tables or databases.
  • ID-Werte lassen sich möglicherweise leichter in die Anwendungslogik integrieren.IDs values can integrate better with an application's logic.

Wenn der ID-Wert einer Zeichenfolge für keine eingefügten Datensätze festgelegt ist, generiert das Mobile App-Back-End einen eindeutigen Wert für die ID.When a string ID value is not set on an inserted record, the Mobile App backend generates a unique value for the ID. Sie können die Guid.NewGuid -Methode verwenden, um eigene ID-Werte entweder auf dem Client oder im Back-End zu generieren.You can use the Guid.NewGuid method to generate your own ID values, either on the client or in the backend.

JObject jo = new JObject();
jo.Add("id", Guid.NewGuid().ToString("N"));

Vorgehensweise: Ändern von Daten in einem Mobile App-Back-EndHow to: Modify data in a Mobile App backend

Der folgende Code zeigt, wie Sie mit der UpdateAsync -Methode einen vorhandenen Datensatz, der die gleiche ID aufweist, mit neuen Daten aktualisieren können.The following code illustrates how to use the UpdateAsync method to update an existing record with the same ID with new information. Der Parameter enthält die zu aktualisierenden Daten als .NET-Objekt.The parameter contains the data to be updated as a .NET object.

await todoTable.UpdateAsync(todoItem);

Zum Aktualisieren von nicht typisierten Daten können Sie Json.NET wie folgt verwenden:To update untyped data, you may take advantage of Json.NET as follows:

JObject jo = new JObject();
jo.Add("id", "37BBF396-11F0-4B39-85C8-B319C729AF6D");
jo.Add("Text", "Hello World");
jo.Add("Complete", false);
var inserted = await table.UpdateAsync(jo);

Beim Ausführen eines Updates muss ein id -Feld angegeben werden.An id field must be specified when making an update. Das Back-End verwendet das id -Feld, um die zu aktualisierende Zeile zu identifizieren.The backend uses the id field to identify which row to update. Sie können das id-Feld aus dem Ergebnis des InsertAsync-Aufrufs abrufen.The id field can be obtained from the result of the InsertAsync call. Wenn Sie versuchen, ein Element ohne Angabe des id-Werts zu aktualisieren, wird eine ArgumentException ausgelöst.An ArgumentException is raised if you try to update an item without providing the id value.

Vorgehensweise: Löschen von Daten in einem Mobile App-Back-EndHow to: Delete data in a Mobile App backend

Der folgende Code zeigt, wie Sie vorhandene Instanzen mit der DeleteAsync -Methode löschen können.The following code illustrates how to use the DeleteAsync method to delete an existing instance. Die Instanz wird durch das id-Feld identifiziert, das im todoItem festgelegt ist.The instance is identified by the id field set on the todoItem.

await todoTable.DeleteAsync(todoItem);

Zum Löschen von nicht typisierten Daten können Sie Json.NET wie folgt verwenden:To delete untyped data, you may take advantage of Json.NET as follows:

JObject jo = new JObject();
jo.Add("id", "37BBF396-11F0-4B39-85C8-B319C729AF6D");
await table.DeleteAsync(jo);

Bei einer Löschanforderung müssen Sie eine ID angeben.When you make a delete request, an ID must be specified. Andere Eigenschaften werden nicht an den Dienst übergeben oder vom Dienst ignoriert.Other properties are not passed to the service or are ignored at the service. Das Ergebnis eines DeleteAsync-Aufrufs lautet normalerweise null.The result of a DeleteAsync call is usually null. Sie erhalten die zu übergebende ID im Ergebnis des InsertAsync -Aufrufs.The ID to pass in can be obtained from the result of the InsertAsync call. Es wird eine MobileServiceInvalidOperationException ausgelöst, wenn Sie versuchen, ein Element ohne Angabe des id-Felds zu löschen.A MobileServiceInvalidOperationException is thrown when you try to delete an item without specifying the id field.

Vorgehensweise: Verwenden der optimistischen Parallelität zur Lösung von KonfliktenHow to: Use Optimistic Concurrency for conflict resolution

Zwei oder mehr Clients können gleichzeitig versuchen, das gleiche Element zu bearbeiten.Two or more clients may write changes to the same item at the same time. Ohne Konflikterkennung würde der letzte Schreibvorgang alle vorherigen Aktualisierungen überschreiben.Without conflict detection, the last write would overwrite any previous updates. Steuerung für optimistische Parallelität nimmt an, dass jede Transaktion Commits ausführen kann und sperrt daher keine Ressourcen.Optimistic concurrency control assumes that each transaction can commit and therefore does not use any resource locking. Vor dem Commit einer Transaktion prüft die Steuerung für optimistische Parallelität, ob die Daten von einer anderen Transaktion geändert wurden.Before committing a transaction, optimistic concurrency control verifies that no other transaction has modified the data. Falls die Daten geändert wurden, wird für die Transaktion, die den Commit durchführen sollte, ein Rollback durchgeführt.If the data has been modified, the committing transaction is rolled back.

Mobile Apps unterstützt die Steuerung für optimistische Parallelität, indem Änderungen an Elementen in der Spalte version mit den Systemeigenschaften nachverfolgt werden, die für jede Tabelle im Mobile App-Back-End definiert wird.Mobile Apps supports optimistic concurrency control by tracking changes to each item using the version system property column that is defined for each table in your Mobile App backend. Bei jeder Aktualisierung eines Datensatzes wird die version -Eigenschaft des entsprechenden Datensatzes von Mobile Apps auf einen neuen Wert festgelegt.Each time a record is updated, Mobile Apps sets the version property for that record to a new value. Bei jeder Aktualisierungsanforderung wird die version -Eigenschaft des in der Anforderung enthaltenen Datensatzes mit der Eigenschaft des Datensatzes auf dem Server verglichen.During each update request, the version property of the record included with the request is compared to the same property for the record on the server. Wenn die mit der Anforderung übergebene Version nicht mit dem Back-End übereinstimmt, löst die Clientbibliothek eine MobileServicePreconditionFailedException<T> -Ausnahme aus.If the version passed with the request does not match the backend, then the client library raises a MobileServicePreconditionFailedException<T> exception. Der in der Ausnahme enthaltene Typ ist der Datensatz des Back-Ends, der die Serverversion des entsprechenden Datensatzes enthält.The type included with the exception is the record from the backend containing the servers version of the record. Anschließend kann die Anwendung anhand dieser Informationen entscheiden, ob die Updateanforderung erneut mit dem korrekten version -Wert vom Back-End ausgeführt werden soll, um Commits für die Änderungen auszuführen.The application can then use this information to decide whether to execute the update request again with the correct version value from the backend to commit changes.

Definieren Sie eine Spalte in der Tabellenklasse für die version -Systemeigenschaft, um die optimistische Parallelität zu aktivieren.Define a column on the table class for the version system property to enable optimistic concurrency. Beispiel:For example:

public class TodoItem
{
    public string Id { get; set; }

    [JsonProperty(PropertyName = "text")]
    public string Text { get; set; }

    [JsonProperty(PropertyName = "complete")]
    public bool Complete { get; set; }

    // *** Enable Optimistic Concurrency *** //
    [JsonProperty(PropertyName = "version")]
    public string Version { set; get; }
}

Anwendungen, die nicht typisierte Tabellen verwenden, können die optimistische Nebenläufigkeit aktivieren, indem sie das Version-Flag in den SystemProperties der Tabelle wie folgt festlegen.Applications using untyped tables enable optimistic concurrency by setting the Version flag on the SystemProperties of the table as follows.

//Enable optimistic concurrency by retrieving version
todoTable.SystemProperties |= MobileServiceSystemProperties.Version;

Zusätzlich zum Aktivieren der optimistischen Parallelität müssen Sie beim Aufrufen von UpdateAsync auch die MobileServicePreconditionFailedException<T>-Ausnahme im Code abfangen.In addition to enabling optimistic concurrency, you must also catch the MobileServicePreconditionFailedException<T> exception in your code when calling UpdateAsync. Lösen Sie den Konflikt durch Anwenden der richtigen version auf den aktualisierten Datensatz, und rufen Sie UpdateAsync mit dem aufgelösten Datensatz auf.Resolve the conflict by applying the correct version to the updated record and call UpdateAsync with the resolved record. Der folgende Code zeigt, wie ein erkannter Schreibkonflikt gelöst werden kann:The following code shows how to resolve a write conflict once detected:

private async void UpdateToDoItem(TodoItem item)
{
    MobileServicePreconditionFailedException<TodoItem> exception = null;

    try
    {
        //update at the remote table
        await todoTable.UpdateAsync(item);
    }
    catch (MobileServicePreconditionFailedException<TodoItem> writeException)
    {
        exception = writeException;
    }

    if (exception != null)
    {
        // Conflict detected, the item has changed since the last query
        // Resolve the conflict between the local and server item
        await ResolveConflict(item, exception.Item);
    }
}


private async Task ResolveConflict(TodoItem localItem, TodoItem serverItem)
{
    //Ask user to choose the resolution between versions
    MessageDialog msgDialog = new MessageDialog(
        String.Format("Server Text: \"{0}\" \nLocal Text: \"{1}\"\n",
        serverItem.Text, localItem.Text),
        "CONFLICT DETECTED - Select a resolution:");

    UICommand localBtn = new UICommand("Commit Local Text");
    UICommand ServerBtn = new UICommand("Leave Server Text");
    msgDialog.Commands.Add(localBtn);
    msgDialog.Commands.Add(ServerBtn);

    localBtn.Invoked = async (IUICommand command) =>
    {
        // To resolve the conflict, update the version of the item being committed. Otherwise, you will keep
        // catching a MobileServicePreConditionFailedException.
        localItem.Version = serverItem.Version;

        // Updating recursively here just in case another change happened while the user was making a decision
        UpdateToDoItem(localItem);
    };

    ServerBtn.Invoked = async (IUICommand command) =>
    {
        RefreshTodoItems();
    };

    await msgDialog.ShowAsync();
}

Weitere Informationen finden Sie im Thema Offlinedatensynchronisierung in Azure Mobile Apps .For more information, see the Offline Data Sync in Azure Mobile Apps topic.

Vorgehensweise: Binden von Mobile Apps-Daten an eine Windows-BenutzeroberflächeHow to: Bind Mobile Apps data to a Windows user interface

In diesem Abschnitt wird das Anzeigen zurückgegebener Datenobjekte mithilfe von UI-Elementen in einer Windows-App beschrieben.This section shows how to display returned data objects using UI elements in a Windows app. Der folgende Beispielcode wird mit einer Abfrage für unvollständige Elemente an die Quelle der Liste gebunden.The following example code binds to the source of the list with a query for incomplete items. Die MobileServiceCollection erstellt eine Bindungssammlung, die Mobile Apps unterstützt.The MobileServiceCollection creates a Mobile Apps-aware binding collection.

// This query filters out completed TodoItems.
MobileServiceCollection<TodoItem, TodoItem> items = await todoTable
    .Where(todoItem => todoItem.Complete == false)
    .ToCollectionAsync();

// itemsControl is an IEnumerable that could be bound to a UI list control
IEnumerable itemsControl  = items;

// Bind this to a ListBox
ListBox lb = new ListBox();
lb.ItemsSource = items;

Einige Steuerelemente in der verwalteten Laufzeit unterstützen eine Schnittstelle namens ISupportIncrementalLoading.Some controls in the managed runtime support an interface called ISupportIncrementalLoading. Mit dieser Schnittstelle können Steuerelemente weitere Daten anfordern, wenn ein Benutzer blättert.This interface allows controls to request extra data when the user scrolls. MobileServiceIncrementalLoadingCollectionbietet integrierte Unterstützung für diese Schnittstelle für universelle Windows-Apps und verarbeitet die Aufrufe dieser Steuerelemente automatisch.There is built-in support for this interface for universal Windows apps via MobileServiceIncrementalLoadingCollection, which automatically handles the calls from the controls. Verwenden Sie MobileServiceIncrementalLoadingCollection folgendermaßen in Windows-Apps:Use MobileServiceIncrementalLoadingCollection in Windows apps as follows:

MobileServiceIncrementalLoadingCollection<TodoItem,TodoItem> items;
items = todoTable.Where(todoItem => todoItem.Complete == false).ToIncrementalLoadingCollection();

ListBox lb = new ListBox();
lb.ItemsSource = items;

Um die neue Sammlung in Windows Phone 8- und Silverlight-Apps zu nutzen, verwenden Sie die ToCollection-Erweiterungsmethoden für IMobileServiceTableQuery<T> und IMobileServiceTable<T>.To use the new collection on Windows Phone 8 and "Silverlight" apps, use the ToCollection extension methods on IMobileServiceTableQuery<T> and IMobileServiceTable<T>. Zum Laden von Daten rufen Sie LoadMoreItemsAsync()auf.To load data, call LoadMoreItemsAsync().

MobileServiceCollection<TodoItem, TodoItem> items = todoTable.Where(todoItem => todoItem.Complete==false).ToCollection();
await items.LoadMoreItemsAsync();

Wenn Sie die durch den Aufruf von ToCollectionAsync bzw. ToCollection erstellte Sammlung verwenden, erhalten Sie eine Sammlung, die an UI-Steuerelemente gebunden werden kann.When you use the collection created by calling ToCollectionAsync or ToCollection, you get a collection that can be bound to UI controls. Diese Sammlung unterstützt das Paging.This collection is paging-aware. Da die Sammlung Daten aus dem Netzwerk lädt, tritt bei Ladevorgängen manchmal ein Fehler auf.Since the collection is loading data from the network, loading sometimes fails. Zur Behandlung solcher Fehler überschreiben Sie die OnException-Methode für MobileServiceIncrementalLoadingCollection, um Ausnahmen zu behandeln, die aus Aufrufen von LoadMoreItemsAsync entstehen.To handle such failures, override the OnException method on MobileServiceIncrementalLoadingCollection to handle exceptions resulting from calls to LoadMoreItemsAsync.

Stellen Sie sich vor, Ihre Tabelle hat viele Felder, aber Sie möchten nur einen Teil der Felder in Ihrem Steuerelement anzeigen.Consider if your table has many fields but you only want to display some of them in your control. Folgen Sie der Anleitung im vorherigen AbschnittAuswählen bestimmter Spalten, um bestimmte Spalten für die Anzeige auf der Benutzeroberfläche auszuwählen.You may use the guidance in the preceding section "Select specific columns" to select specific columns to display in the UI.

Ändern der SeitengrößeChange the Page size

Azure Mobile Apps gibt standardmäßig maximal 50 Elemente pro Anforderung zurück.Azure Mobile Apps returns a maximum of 50 items per request by default. Sie können die Paginggröße ändern, indem Sie die maximale Seitengröße sowohl auf dem Client als auch auf dem Server erhöhen.You can change the paging size by increasing the maximum page size on both the client and server. Um die angeforderte Seitengröße zu erhöhen, geben Sie PullOptions an, wenn Sie PullAsync() verwenden:To increase the requested page size, specify PullOptions when using PullAsync():

PullOptions pullOptions = new PullOptions
    {
        MaxPageSize = 100
    };

Wenn Sie die PageSize auf dem Server auf einen Wert gleich oder größer 100 festgelegt haben, gibt eine Anforderung bis zu 100 Elemente zurück.Assuming you have made the PageSize equal to or greater than 100 within the server, a request returns up to 100 items.

Mit Offlinetabellen arbeitenWork with Offline Tables

Offlinetabellen verwenden eine lokalen SQLite-Speicher zum Speichern von Daten für die Offline-Verwendung.Offline tables use a local SQLite store to store data for use when offline. Alle Tabellenvorgänge werden gegen den lokalen SQLite-Speicher statt den Remote-Serverspeicher ausgeführt.All table operations are done against the local SQLite store instead of the remote server store. Um eine Offlinetabelle zu erstellen, müssen Sie zuerst das Projekt vorbereiten:To create an offline table, first prepare your project:

  1. Klicken Sie in Visual Studio mit der rechten Maustaste auf die Projektmappe, und klicken Sie dann auf NuGet-Pakete verwalten für Projektmappe... . Suchen Sie anschließend nach dem NuGet-Paket Microsoft.Azure.Mobile.Client.SQLiteStore, und installieren Sie es für alle Projekte der Projektmappe.In Visual Studio, right-click the solution > Manage NuGet Packages for Solution..., then search for and install the Microsoft.Azure.Mobile.Client.SQLiteStore NuGet package for all projects in the solution.

  2. (Optional) Um Windows-Geräte zu unterstützen, können Sie eines der folgenden SQLite-Laufzeitpakete installieren:(Optional) To support Windows devices, install one of the following SQLite runtime packages:

  3. (Optional).(Optional). Klicken Sie bei Windows-Geräten auf Verweise > Verweis hinzufügen... , erweitern Sie den Ordner Windows, und wählen Sie Erweiterungen. Aktivieren Sie anschließend das richtige SDK SQLite für Windows zusammen mit dem SDK Visual C++ 2013 Runtime for Windows.For Windows devices, click References > Add Reference..., expand the Windows folder > Extensions, then enable the appropriate SQLite for Windows SDK along with the Visual C++ 2013 Runtime for Windows SDK. Die Namen der SQLite-SDKs unterscheiden sich bei den einzelnen Windows-Plattformen.The SQLite SDK names vary slightly with each Windows platform.

Bevor ein Tabellenverweis erstellt werden, muss der lokale Speicher vorbereitet werden:Before a table reference can be created, the local store must be prepared:

var store = new MobileServiceSQLiteStore(Constants.OfflineDbPath);
store.DefineTable<TodoItem>();

//Initializes the SyncContext using the default IMobileServiceSyncHandler.
await this.client.SyncContext.InitializeAsync(store);

Die Speicherinitialisierung erfolgt normalerweise sofort nach dem Erstellen des Clients.Store initialization is normally done immediately after the client is created. Der OfflineDbPath sollte ein geeigneter Dateiname für die Verwendung auf allen Plattformen sein, die Sie unterstützen.The OfflineDbPath should be a filename suitable for use on all platforms that you support. Wenn der Pfad ein vollqualifizierter Pfad ist (d. h. er beginnt mit einem Schrägstrich), dann wird der Pfad verwendet.If the path is a fully qualified path (that is, it starts with a slash), then that path is used. Wenn der Pfad nicht vollqualifiziert ist, wird die Datei in einem plattformspezifischen Verzeichnis platziert.If the path is not fully qualified, the file is placed in a platform-specific location.

  • Bei IOS- und Android-Geräten ist der Standardpfad der Ordner „Persönliche Dateien“.For iOS and Android devices, the default path is the "Personal Files" folder.
  • Bei Windows-Geräten ist der Standardpfad der anwendungsspezifische Ordner „AppData“.For Windows devices, the default path is the application-specific "AppData" folder.

Ein Tabellenverweis kann mit der GetSyncTable<>-Methode:abgerufen werden:A table reference can be obtained using the GetSyncTable<> method:

var table = client.GetSyncTable<TodoItem>();

Für die Verwendung einer Offlinetabelle müssen Sie sich nicht authentifizieren.You do not need to authenticate to use an offline table. Sie müssen sich nur authentifizieren, wenn Sie mit dem Back-End-Dienst kommunizieren.You only need to authenticate when you are communicating with the backend service.

Synchronisieren einer OfflinetabelleSyncing an Offline Table

Offlinetabellen werden nicht standardmäßig mit dem Back-End synchronisiert.Offline tables are not synchronized with the backend by default. Die Synchronisierung ist in zwei Bereiche unterteilt.Synchronization is split into two pieces. Sie können Änderungen separat vom Herunterladen neuer Elemente übertragen.You can push changes separately from downloading new items. Hier sehen Sie eine typische Synchronisierungsmethode:Here is a typical sync method:

public async Task SyncAsync()
{
    ReadOnlyCollection<MobileServiceTableOperationError> syncErrors = null;

    try
    {
        await this.client.SyncContext.PushAsync();

        await this.todoTable.PullAsync(
            //The first parameter is a query name that is used internally by the client SDK to implement incremental sync.
            //Use a different query name for each unique query in your program
            "allTodoItems",
            this.todoTable.CreateQuery());
    }
    catch (MobileServicePushFailedException exc)
    {
        if (exc.PushResult != null)
        {
            syncErrors = exc.PushResult.Errors;
        }
    }

    // Simple error/conflict handling. A real application would handle the various errors like network conditions,
    // server conflicts and others via the IMobileServiceSyncHandler.
    if (syncErrors != null)
    {
        foreach (var error in syncErrors)
        {
            if (error.OperationKind == MobileServiceTableOperationKind.Update && error.Result != null)
            {
                //Update failed, reverting to server's copy.
                await error.CancelAndUpdateItemAsync(error.Result);
            }
            else
            {
                // Discard local change.
                await error.CancelAndDiscardItemAsync();
            }

            Debug.WriteLine(@"Error executing sync operation. Item: {0} ({1}). Operation discarded.", error.TableName, error.Item["id"]);
        }
    }
}

Wenn das erste Argument für PullAsync null ist, wird die inkrementelle Synchronisierung nicht verwendet.If the first argument to PullAsync is null, then incremental sync is not used. Jeder Synchronisierungsvorgang ruft alle Datensätze ab.Each sync operation retrieves all records.

Das SDK führt vor dem Abrufen von Datensätzen eine implizite PushAsync() durch.The SDK performs an implicit PushAsync() before pulling records.

Die Konfliktbehandlung erfolgt über eine PullAsync()-Methode.Conflict handling happens on a PullAsync() method. Sie können Konflikte ebenso behandeln wie Onlinetabellen.You can deal with conflicts in the same way as online tables. Der Konflikt entsteht, wenn PullAsync() statt „insert“, „update“ oder „delete“ aufgerufen wird.The conflict is produced when PullAsync() is called instead of during the insert, update, or delete. Wenn mehrere Konflikte auftreten, werden sie in eine MobileServicePushFailedException gebündelt.If multiple conflicts happen, they are bundled into a single MobileServicePushFailedException. Behandeln Sie jeden Fehler einzeln.Handle each failure separately.

Arbeiten mit einer benutzerdefinierten APIWork with a custom API

Mit einer benutzerdefinierten API können Sie benutzerdefinierte Endpunkte definieren, die Serverfunktionen zur Verfügung stellen, welche keinem Einfüge-, Aktualisierungs-, Lösch- oder Lesevorgang zugeordnet sind.A custom API enables you to define custom endpoints that expose server functionality that does not map to an insert, update, delete, or read operation. Durch die Verwendung einer benutzerdefinierten API erhalten Sie mehr Kontrolle über das Messaging, einschließlich Lesen und Einstellen der HTTP-Nachrichten-Header sowie Definieren eines von JSON abweichenden Nachrichtentextformats.By using a custom API, you can have more control over messaging, including reading and setting HTTP message headers and defining a message body format other than JSON.

Sie rufen eine benutzerdefinierte API auf, indem Sie auf dem Client eine der InvokeApiAsync -Methoden aufrufen.You call a custom API by calling one of the InvokeApiAsync methods on the client. Mit der folgenden Codezeile wird beispielsweise eine POST-Anforderung an die completeAll -API im Back-End gesendet:For example, the following line of code sends a POST request to the completeAll API on the backend:

var result = await client.InvokeApiAsync<MarkAllResult>("completeAll", System.Net.Http.HttpMethod.Post, null);

Diese Form ist ein typisierter Methodenaufruf, der erfordert, dass der MarkAllResult-Rückgabetyp definiert ist.This form is a typed method call and requires that the MarkAllResult return type is defined. Typisierte und nicht typisierte Methoden werden unterstützt.Both typed and untyped methods are supported.

Die InvokeApiAsync()-Methode stellt „/api/“ der API voran, die Sie aufrufen möchten, sofern diese API nicht mit einem Schrägstrich „/“ beginnt.The InvokeApiAsync() method prepends '/api/' to the API that you wish to call unless the API starts with a '/'. Beispiel:For example:

  • InvokeApiAsync("completeAll",...) ruft /api/completeAll auf dem Back-End auf.InvokeApiAsync("completeAll",...) calls /api/completeAll on the backend
  • InvokeApiAsync("/.auth/me",...) ruft /.auth/me auf dem Back-End auf.InvokeApiAsync("/.auth/me",...) calls /.auth/me on the backend

Sie können mit InvokeApiAsync jede WebAPI aufrufen, einschließlich WebAPIs, die nicht in Azure Mobile Apps definiert sind.You can use InvokeApiAsync to call any WebAPI, including those WebAPIs that are not defined with Azure Mobile Apps. Bei Verwendung von InvokeApiAsync() werden die entsprechenden Header, einschließlich der Authentifizierungsheader, mit der Anforderung gesendet.When you use InvokeApiAsync(), the appropriate headers, including authentication headers, are sent with the request.

Authentifizieren von BenutzernAuthenticate users

Mobile Apps unterstützt die Authentifizierung und Autorisierung von App-Benutzern mithilfe verschiedener externer Identitätsanbieter: Facebook, Google, Microsoft-Konto, Twitter und Azure Active Directory.Mobile Apps supports authenticating and authorizing app users using various external identity providers: Facebook, Google, Microsoft Account, Twitter, and Azure Active Directory. Sie können Berechtigungen für Tabellen vergeben, um den Zugriff auf bestimmte Operationen auf authentifizierte Benutzer zu beschränken.You can set permissions on tables to restrict access for specific operations to only authenticated users. Außerdem können Sie die Identität authentifizierter Benutzer verwenden, um Autorisierungsregeln in Serverskripts zu implementieren.You can also use the identity of authenticated users to implement authorization rules in server scripts. Weitere Informationen finden Sie im Lernprogramm Hinzufügen von Authentifizierung zur App.For more information, see the tutorial Add authentication to your app.

Zwei Authentifizierungsflüsse werden unterstützt: vom Client verwalteter und vom Server verwalteter Fluss.Two authentication flows are supported: client-managed and server-managed flow. Der vom Server verwaltete Fluss bietet die einfachste Authentifizierungsform, da in diesem Fall die Authentifizierungs-Webschnittstelle des Anbieters verwendet wird.The server-managed flow provides the simplest authentication experience, as it relies on the provider's web authentication interface. Der vom Client verwaltete Fluss ermöglicht eine tiefere Integration mit gerätespezifischen Fähigkeiten, da in diesem Fall anbieterspezifische und gerätespezifische SDKs verwendet werden.The client-managed flow allows for deeper integration with device-specific capabilities as it relies on provider-specific device-specific SDKs.

Hinweis

In Ihren Produktions-Apps sollten Sie einen vom Client verwalteten Fluss nutzen.We recommend using a client-managed flow in your production apps.

Zum Einrichten der Authentifizierung müssen Sie Ihre App bei mindestens einem Identitätsanbieter registrieren.To set up authentication, you must register your app with one or more identity providers. Der Identitätsanbieter generiert eine Client-ID und einen geheimen Clientschlüssel für Ihre App.The identity provider generates a client ID and a client secret for your app. Diese Werte werden in Ihrem Back-End festgelegt, um die Authentifizierung/Autorisierung über Azure App Service zu aktivieren.These values are then set in your backend to enable Azure App Service authentication/authorization. Weitere Informationen finden Sie in den detaillierten Anweisungen im Tutorial Hinzufügen von Authentifizierung zur App.For more information, follow the detailed instructions in the tutorial Add authentication to your app.

In diesem Abschnitt werden die folgenden Themen behandelt:The following topics are covered in this section:

Vom Client verwaltete AuthentifizierungClient-managed authentication

Ihre App kann den Identitätsanbieter unabhängig kontaktieren und das zurückgegebene Token bei der Anmeldung bei Ihrem Back-End vorlegen.Your app can independently contact the identity provider and then provide the returned token during login with your backend. Mit diesem Clientfluss können Sie die einmalige Anmeldung für Ihre Benutzer implementieren oder zusätzliche Benutzerdaten vom Identitätsanbieter abrufen.This client flow enables you to provide a single sign-on experience for users or to retrieve additional user data from the identity provider. Da das Identitätsanbieter-SDK ein intuitiveres Benutzererlebnis und zusätzliche Anpassungsoptionen bietet, ist die Clientflussauthentifizierung dem Serverfluss vorzuziehen.Client flow authentication is preferred to using a server flow as the identity provider SDK provides a more native UX feel and allows for additional customization.

Für die folgenden clientflussbezogenen Authentifizierungsmuster werden Beispiele bereitgestellt:Examples are provided for the following client-flow authentication patterns:

Authentifizieren von Benutzern mit der Active Directory Authentication LibraryAuthenticate users with the Active Directory Authentication Library

Nutzen Sie die Active Directory-Authentifizierungsbibliothek (Active Directory Authentication Library, ADAL), um die Benutzerauthentifizierung auf dem Client mithilfe der Azure Active Directory-Authentifizierung einzuleiten.You can use the Active Directory Authentication Library (ADAL) to initiate user authentication from the client using Azure Active Directory authentication.

  1. Konfigurieren Sie Ihr mobiles App-Back-End für die AAD-Anmeldung, indem Sie die im Tutorial Konfigurieren von App Service für eine Active Directory-Anmeldung beschriebenen Schritte ausführen.Configure your mobile app backend for AAD sign-on by following the How to configure App Service for Active Directory login tutorial. Schließen Sie auch den optionalen Schritt zur Registrierung einer nativen Clientanwendung ab.Make sure to complete the optional step of registering a native client application.

  2. Öffnen Sie Ihr Projekt in Visual Studio oder Xamarin Studio, und fügen Sie einen Verweis auf das NuGet-Paket Microsoft.IdentityModel.Clients.ActiveDirectory hinzu.In Visual Studio or Xamarin Studio, open your project and add a reference to the Microsoft.IdentityModel.Clients.ActiveDirectory NuGet package. Nehmen Sie in die Suche auch Vorabversionen auf.When searching, include pre-release versions.

  3. Fügen Sie je nach verwendeter Plattform den folgenden Code zu Ihrer Anwendung hinzu.Add the following code to your application, according to the platform you are using. Nehmen Sie dabei die folgenden Änderungen vor:In each, make the following replacements:

    • Ersetzen Sie INSERT-AUTHORITY-HERE durch den Namen des Mandanten, in dem Sie Ihre Anwendung bereitgestellt haben.Replace INSERT-AUTHORITY-HERE with the name of the tenant in which you provisioned your application. Das Format muss https://login.microsoftonline.com/contoso.onmicrosoft.com sein.The format should be https://login.microsoftonline.com/contoso.onmicrosoft.com. Sie können diesen Wert im Azure-Portal in Ihrer Azure Active Directory-Instanz auf der Registerkarte „Domäne“ kopieren.This value can be copied from the Domain tab in your Azure Active Directory in the Azure portal.

    • Ersetzen Sie INSERT-RESOURCE-ID-HERE durch die Client-ID für Ihr mobiles App-Back-End.Replace INSERT-RESOURCE-ID-HERE with the client ID for your mobile app backend. Sie können die Client-ID im Portal auf der Registerkarte Erweitert unter Azure Active Directory-Einstellungen abrufen.You can obtain the client ID from the Advanced tab under Azure Active Directory Settings in the portal.

    • Ersetzen Sie INSERT-CLIENT-ID-HERE durch die Client-ID, die Sie aus der nativen Clientanwendung kopiert haben.Replace INSERT-CLIENT-ID-HERE with the client ID you copied from the native client application.

    • Ersetzen Sie mithilfe des HTTPS-Schemas INSERT-REDIRECT-URI-HERE durch den Endpunkt /.auth/login/done Ihrer Website.Replace INSERT-REDIRECT-URI-HERE with your site's /.auth/login/done endpoint, using the HTTPS scheme. Dieser Wert sollte https://contoso.azurewebsites.net/.auth/login/done ähnlich sein.This value should be similar to https://contoso.azurewebsites.net/.auth/login/done.

      Der für jede Plattform erforderliche Code:The code needed for each platform follows:

      Windows:Windows:

      private MobileServiceUser user;
      private async Task AuthenticateAsync()
      {
      
         string authority = "INSERT-AUTHORITY-HERE";
         string resourceId = "INSERT-RESOURCE-ID-HERE";
         string clientId = "INSERT-CLIENT-ID-HERE";
         string redirectUri = "INSERT-REDIRECT-URI-HERE";
         while (user == null)
         {
             string message;
             try
             {
                 AuthenticationContext ac = new AuthenticationContext(authority);
                 AuthenticationResult ar = await ac.AcquireTokenAsync(resourceId, clientId,
                     new Uri(redirectUri), new PlatformParameters(PromptBehavior.Auto, false) );
                 JObject payload = new JObject();
                 payload["access_token"] = ar.AccessToken;
                 user = await App.MobileService.LoginAsync(
                     MobileServiceAuthenticationProvider.WindowsAzureActiveDirectory, payload);
                 message = string.Format("You are now logged in - {0}", user.UserId);
             }
             catch (InvalidOperationException)
             {
                 message = "You must log in. Login Required";
             }
             var dialog = new MessageDialog(message);
             dialog.Commands.Add(new UICommand("OK"));
             await dialog.ShowAsync();
         }
      }
      

      Xamarin.iOSXamarin.iOS

      private MobileServiceUser user;
      private async Task AuthenticateAsync(UIViewController view)
      {
      
         string authority = "INSERT-AUTHORITY-HERE";
         string resourceId = "INSERT-RESOURCE-ID-HERE";
         string clientId = "INSERT-CLIENT-ID-HERE";
         string redirectUri = "INSERT-REDIRECT-URI-HERE";
         try
         {
             AuthenticationContext ac = new AuthenticationContext(authority);
             AuthenticationResult ar = await ac.AcquireTokenAsync(resourceId, clientId,
                 new Uri(redirectUri), new PlatformParameters(view));
             JObject payload = new JObject();
             payload["access_token"] = ar.AccessToken;
             user = await client.LoginAsync(
                 MobileServiceAuthenticationProvider.WindowsAzureActiveDirectory, payload);
         }
         catch (Exception ex)
         {
             Console.Error.WriteLine(@"ERROR - AUTHENTICATION FAILED {0}", ex.Message);
         }
      }
      

      Xamarin.AndroidXamarin.Android

      private MobileServiceUser user;
      private async Task AuthenticateAsync()
      {
      
         string authority = "INSERT-AUTHORITY-HERE";
         string resourceId = "INSERT-RESOURCE-ID-HERE";
         string clientId = "INSERT-CLIENT-ID-HERE";
         string redirectUri = "INSERT-REDIRECT-URI-HERE";
         try
         {
             AuthenticationContext ac = new AuthenticationContext(authority);
             AuthenticationResult ar = await ac.AcquireTokenAsync(resourceId, clientId,
                 new Uri(redirectUri), new PlatformParameters(this));
             JObject payload = new JObject();
             payload["access_token"] = ar.AccessToken;
             user = await client.LoginAsync(
                 MobileServiceAuthenticationProvider.WindowsAzureActiveDirectory, payload);
         }
         catch (Exception ex)
         {
             AlertDialog.Builder builder = new AlertDialog.Builder(this);
             builder.SetMessage(ex.Message);
             builder.SetTitle("You must log in. Login Required");
             builder.Create().Show();
         }
      }
      protected override void OnActivityResult(int requestCode, Result resultCode, Intent data)
      {
      
         base.OnActivityResult(requestCode, resultCode, data);
         AuthenticationAgentContinuationHelper.SetAuthenticationAgentContinuationEventArgs(requestCode, resultCode, data);
      }
      

Einmaliges Anmelden mit einem Token von Facebook oder GoogleSingle Sign-On using a token from Facebook or Google

Der folgende Codeausschnitt zeigt den Clientfluss für Facebook oder Google.You can use the client flow as shown in this snippet for Facebook or Google.

var token = new JObject();
// Replace access_token_value with actual value of your access token obtained
// using the Facebook or Google SDK.
token.Add("access_token", "access_token_value");

private MobileServiceUser user;
private async Task AuthenticateAsync()
{
    while (user == null)
    {
        string message;
        try
        {
            // Change MobileServiceAuthenticationProvider.Facebook
            // to MobileServiceAuthenticationProvider.Google if using Google auth.
            user = await client.LoginAsync(MobileServiceAuthenticationProvider.Facebook, token);
            message = string.Format("You are now logged in - {0}", user.UserId);
        }
        catch (InvalidOperationException)
        {
            message = "You must log in. Login Required";
        }

        var dialog = new MessageDialog(message);
        dialog.Commands.Add(new UICommand("OK"));
        await dialog.ShowAsync();
    }
}

Vom Server verwaltete AuthentifizierungServer-managed authentication

Rufen Sie nach der Registrierung Ihres Identitätsanbieters die LoginAsync-Methode für den MobileServiceClient mit dem MobileServiceAuthenticationProvider-Wert Ihres Anbieters auf.Once you have registered your identity provider, call the LoginAsync method on the [MobileServiceClient] with the MobileServiceAuthenticationProvider value of your provider. Der folgende Beispielcode startet eine Serverfluss-Anmeldung über Facebook.For example, the following code initiates a server flow sign-in by using Facebook.

private MobileServiceUser user;
private async System.Threading.Tasks.Task Authenticate()
{
    while (user == null)
    {
        string message;
        try
        {
            user = await client
                .LoginAsync(MobileServiceAuthenticationProvider.Facebook);
            message =
                string.Format("You are now logged in - {0}", user.UserId);
        }
        catch (InvalidOperationException)
        {
            message = "You must log in. Login Required";
        }

        var dialog = new MessageDialog(message);
        dialog.Commands.Add(new UICommand("OK"));
        await dialog.ShowAsync();
    }
}

Falls Sie einen anderen Identitätsanbieter als Facebook verwenden, ändern Sie den Wert für MobileServiceAuthenticationProvider oben entsprechend Ihrem Anbieter.If you are using an identity provider other than Facebook, change the value of MobileServiceAuthenticationProvider to the value for your provider.

In einem Serverfluss verwaltet Azure App Service den OAuth-Authentifizierungsfluss durch Anzeigen der Anmeldeseite des ausgewählten Anbieters.In a server flow, Azure App Service manages the OAuth authentication flow by displaying the sign-in page of the selected provider. Sobald der Identitätsanbieter eine Antwort zurückgibt, generiert Azure App Service ein App Service-Authentifizierungstoken.Once the identity provider returns, Azure App Service generates an App Service authentication token. Die LoginAsync-Methode gibt einen MobileServiceUser zurück, der sowohl die UserId des authentifizierten Benutzers als auch das MobileServiceAuthenticationToken in Form eines JSON-Webtokens (JWT) bereitstellt.The LoginAsync method returns a MobileServiceUser, which provides both the UserId of the authenticated user and the MobileServiceAuthenticationToken, as a JSON web token (JWT). Dieses Token kann zwischengespeichert und wiederverwendet werden, bis es abläuft.This token can be cached and reused until it expires. Weitere Informationen finden Sie unter Zwischenspeichern des Authentifizierungstokens.For more information, see Caching the authentication token.

Zwischenspeichern des AuthentifizierungstokensCaching the authentication token

In einigen Fällen kann der Aufruf der Anmeldemethode nach der ersten erfolgreichen Authentifizierung vermieden werden, indem das Authentifizierungstoken des Anbieters gespeichert wird.In some cases, the call to the login method can be avoided after the first successful authentication by storing the authentication token from the provider. Microsoft Store- und UWP-Apps können nach einer erfolgreichen Anmeldung Kennworttresor zum Zwischenspeichern des aktuellen Authentifizierungstokens verwenden:Microsoft Store and UWP apps can use PasswordVault to cache the current authentication token after a successful sign-in, as follows:

await client.LoginAsync(MobileServiceAuthenticationProvider.Facebook);

PasswordVault vault = new PasswordVault();
vault.Add(new PasswordCredential("Facebook", client.currentUser.UserId,
    client.currentUser.MobileServiceAuthenticationToken));

Die Benutzer-ID wird als Benutzername der Anmeldeinformationen und das Token als Kennwort gespeichert.The UserId value is stored as the UserName of the credential and the token is the stored as the Password. Bei nachfolgenden Systemstarts können Sie PasswordVault auf zwischengespeicherte Anmeldeinformationen überprüfen.On subsequent start-ups, you can check the PasswordVault for cached credentials. Das folgende Beispiel verwendet zwischengespeicherte Anmeldeinformationen, sobald diese gefunden werden, und versucht andernfalls, eine erneute Authentifizierung beim Back-End:The following example uses cached credentials when they are found, and otherwise attempts to authenticate again with the backend:

// Try to retrieve stored credentials.
var creds = vault.FindAllByResource("Facebook").FirstOrDefault();
if (creds != null)
{
    // Create the current user from the stored credentials.
    client.currentUser = new MobileServiceUser(creds.UserName);
    client.currentUser.MobileServiceAuthenticationToken =
        vault.Retrieve("Facebook", creds.UserName).Password;
}
else
{
    // Regular login flow and cache the token as shown above.
}

Wenn Sie einen Benutzer abmelden, müssen Sie auch die gespeicherten Anmeldeinformationen wie folgt entfernen:When you sign out a user, you must also remove the stored credential, as follows:

client.Logout();
vault.Remove(vault.Retrieve("Facebook", client.currentUser.UserId));

Xamarin-Apps verwenden die Xamarin.Auth -APIs zum sicheren Speichern von Anmeldeinformationen in einem Account -Objekt.Xamarin apps use the Xamarin.Auth APIs to securely store credentials in an Account object. Ein Beispiel für die Verwendung dieser APIs finden Sie in der Codedatei AuthStore.cs im ContosoMoments-Beispiel für das Teilen von Fotos.For an example of using these APIs, see the AuthStore.cs code file in the ContosoMoments photo sharing sample.

Wenn Sie die vom Client verwaltete Authentifizierung verwenden, können Sie auch das von einem Anbieter wie Facebook oder Twitter erhaltene Zugriffstoken zwischenspeichern.When you use client-managed authentication, you can also cache the access token obtained from your provider such as Facebook or Twitter. Dieses Token kann angegeben werden, um ein neues Authentifizierungstoken wie folgt vom Back-End anzufordern:This token can be supplied to request a new authentication token from the backend, as follows:

var token = new JObject();
// Replace <your_access_token_value> with actual value of your access token
token.Add("access_token", "<your_access_token_value>");

// Authenticate using the access token.
await client.LoginAsync(MobileServiceAuthenticationProvider.Facebook, token);

PushbenachrichtigungenPush Notifications

Die folgenden Themen behandeln Pushbenachrichtigungen:The following topics cover Push Notifications:

Vorgehensweise: Registrieren für PushbenachrichtigungenHow to: Register for Push Notifications

Mit dem Mobile Apps-Client können Sie die App für Pushbenachrichtigungen mit Azure Notification Hubs registrieren.The Mobile Apps client enables you to register for push notifications with Azure Notification Hubs. Wenn Sie sich registrieren, erhalten Sie ein Handle, das vom plattformspezifischen Pushbenachrichtigungsdienst bezogen wird.When registering, you obtain a handle that you obtain from the platform-specific Push Notification Service (PNS). Diesen Wert müssen Sie zusammen mit allen übrigen Tags beim Registrieren angeben.You then provide this value along with any tags when you create the registration. Der folgende Code registriert Ihre Windows-App für Pushbenachrichtigungen mit dem Windows-Benachrichtigungsdienst (Windows Notification Service, WNS):The following code registers your Windows app for push notifications with the Windows Notification Service (WNS):

private async void InitNotificationsAsync()
{
    // Request a push notification channel.
    var channel = await PushNotificationChannelManager.CreatePushNotificationChannelForApplicationAsync();

    // Register for notifications using the new channel.
    await MobileService.GetPush().RegisterNativeAsync(channel.Uri, null);
}

Für Pushvorgänge an den WNS MÜSSEN Sie eine Microsoft Store-Paket-SID abrufen.If you are pushing to WNS, then you MUST obtain a Microsoft Store package SID. Weitere Informationen zu Windows-Apps, z. B. zum Registrieren für Vorlagenregistrierungen, finden Sie unter Hinzufügen von Pushbenachrichtigungen zur App.For more information on Windows apps, including how to register for template registrations, see Add push notifications to your app.

Die Anforderung von Tags vom Client wird nicht unterstützt.Requesting tags from the client is not supported. Tag-Anforderungen werden automatisch aus der Registrierung gelöscht.Tag Requests are silently dropped from registration. Wenn Sie Ihr Gerät mit Tags registrieren möchten, erstellen Sie eine benutzerdefinierte API, die die Notification Hubs-API verwendet, um die Registrierung in Ihrem Namen auszuführen.If you wish to register your device with tags, create a Custom API that uses the Notification Hubs API to perform the registration on your behalf. Rufen Sie anstelle der RegisterNativeAsync()-Methode die benutzerdefinierte API auf.Call the Custom API instead of the RegisterNativeAsync() method.

Gewusst wie: Abrufen einer Microsoft Store-Paket-SIDHow to: Obtain a Microsoft Store package SID

Für Pushbenachrichtigungen in Microsoft Store-Apps ist eine Paket-SID erforderlich.A package SID is needed for enabling push notifications in Microsoft Store apps. Registrieren Sie Ihre Anwendung beim Microsoft Store, um eine Paket-SID zu erhalten.To receive a package SID, register your application with the Microsoft Store.

Dieser Wert wird wie folgt abgerufen:To obtain this value:

  1. Klicken Sie im Projektmappen-Explorer von Visual Studio mit der rechten Maustaste auf das Microsoft Store-App-Projekt, und klicken Sie dann auf Store > App mit Store verknüpfen... .In Visual Studio Solution Explorer, right-click the Microsoft Store app project, click Store > Associate App with the Store....
  2. Klicken Sie im Assistenten auf Weiter, melden Sie sich mit Ihrem Microsoft-Konto an, geben Sie unter App-Namen reservieren einen Namen für Ihre App ein, und klicken Sie dann auf Reservieren.In the wizard, click Next, sign in with your Microsoft account, type a name for your app in Reserve a new app name, then click Reserve.
  3. Nachdem die App-Registrierung erfolgreich erstellt wurde, wählen Sie den Namen der App aus, und klicken Sie auf Weiter und dann auf Zuordnen.After the app registration is successfully created, select the app name, click Next, and then click Associate.
  4. Melden Sie sich mit Ihrem Microsoft-Konto beim Windows Dev Center an.Log in to the Windows Dev Center using your Microsoft Account. Klicken Sie unter Meine Appsauf die erstellte App-Registrierung.Under My apps, click the app registration you created.
  5. Klicken Sie auf App-Verwaltung > App-Identität, und scrollen Sie nach unten zu Ihrer Paket-SID.Click App management > App identity, and then scroll down to find your Package SID.

In vielen Anwendungsfällen wird die Paket-SID als URI behandelt. In diesem Fall müssen Sie ms-app:// als Schema verwenden.Many uses of the package SID treat it as a URI, in which case you need to use ms-app:// as the scheme. Notieren Sie sich die Version der Paket-SID, die durch Verkettung dieses Werts als Präfix gebildet wird.Make note of the version of your package SID formed by concatenating this value as a prefix.

Xamarin-Apps erfordern zusätzlichen Code, um eine App registrieren zu können, die auf iOS- oder Android-Plattformen ausgeführt wird.Xamarin apps require some additional code to be able to register an app running on the iOS or Android platforms. Weitere Informationen finden Sie im Thema zu Ihrer Plattform:For more information, see the topic for your platform:

Vorgehensweise: Registrieren von Pushvorlagen zum Senden plattformübergreifender BenachrichtigungenHow to: Register push templates to send cross-platform notifications

Verwenden Sie die RegisterAsync() -Methode wie folgt, um Vorlagen zu registrieren:To register templates, use the RegisterAsync() method with the templates, as follows:

JObject templates = myTemplates();
MobileService.GetPush().RegisterAsync(channel.Uri, templates);

Ihre Vorlagen sollten den Typ JObject aufweisen und können mehrere Vorlagen im folgenden JSON-Format enthalten:Your templates should be JObject types and can contain multiple templates in the following JSON format:

public JObject myTemplates()
{
    // single template for Windows Notification Service toast
    var template = "<toast><visual><binding template=\"ToastText01\"><text id=\"1\">$(message)</text></binding></visual></toast>";

    var templates = new JObject
    {
        ["generic-message"] = new JObject
        {
            ["body"] = template,
            ["headers"] = new JObject
            {
                ["X-WNS-Type"] = "wns/toast"
            },
            ["tags"] = new JArray()
        },
        ["more-templates"] = new JObject {...}
    };
    return templates;
}

Die RegisterAsync() -Methode akzeptiert auch sekundäre Kacheln:The method RegisterAsync() also accepts Secondary Tiles:

MobileService.GetPush().RegisterAsync(string channelUri, JObject templates, JObject secondaryTiles);

Während der Registrierung werden aus Sicherheitsgründen alle Tags entfernt.All tags are stripped away during registration for security. Informationen zum Hinzufügen von Tags zu Installationen bzw. Vorlagen innerhalb von Installationen finden Sie unter „Verwenden des .NET-Back-End-Server SDK für Azure Mobile Apps“.To add tags to installations or templates within installations, see [Work with the .NET backend server SDK for Azure Mobile Apps].

Informationen zum Senden von Benachrichtigungen unter Verwendung dieser registrierten Vorlagen finden Sie unter Notification Hubs-APIs.To send notifications utilizing these registered templates, refer to the Notification Hubs APIs.

Verschiedene ThemenMiscellaneous Topics

Vorgehensweise: FehlerbehandlungHow to: Handle errors

Tritt ein Fehler im Back-End auf, löst das Client-SDK eine MobileServiceInvalidOperationExceptionaus.When an error occurs in the backend, the client SDK raises a MobileServiceInvalidOperationException. Das folgende Beispiel zeigt, wie eine vom Back-End zurückgegebene Ausnahme behandelt wird:The following example shows how to handle an exception that is returned by the backend:

private async void InsertTodoItem(TodoItem todoItem)
{
    // This code inserts a new TodoItem into the database. When the operation completes
    // and App Service has assigned an Id, the item is added to the CollectionView
    try
    {
        await todoTable.InsertAsync(todoItem);
        items.Add(todoItem);
    }
    catch (MobileServiceInvalidOperationException e)
    {
        // Handle error
    }
}

Sie finden ein weiteres Beispiel für die Behandlung von Fehlerbedingungen im Beispiel für Mobile Apps-Dateien.Another example of dealing with error conditions can be found in the Mobile Apps Files Sample. Das LoggingHandler-Beispiel stellt einen Delegathandler für die Protokollierung der Anforderungen an das Back-End bereit.The LoggingHandler example provides a logging delegate handler to log the requests being made to the backend.

Vorgehensweise: Anpassen von AnforderungsheadernHow to: Customize request headers

Um Ihr spezielles App-Szenario zu unterstützen, müssen Sie unter Umständen die Kommunikation mit dem Mobile App-Back-End anpassen.To support your specific app scenario, you might need to customize communication with the Mobile App backend. Sie können z. B. benutzerdefinierte Header zu allen ausgehenden Anforderungen hinzufügen oder den Statuscode von Antworten ändern.For example, you may want to add a custom header to every outgoing request or even change responses status codes. Sie können einen benutzerdefinierten DelegatingHandler bereitstellen, wie im folgenden Beispiel gezeigt:You can use a custom DelegatingHandler, as in the following example:

public async Task CallClientWithHandler()
{
    MobileServiceClient client = new MobileServiceClient("AppUrl", new MyHandler());
    IMobileServiceTable<TodoItem> todoTable = client.GetTable<TodoItem>();
    var newItem = new TodoItem { Text = "Hello world", Complete = false };
    await todoTable.InsertAsync(newItem);
}

public class MyHandler : DelegatingHandler
{
    protected override async Task<HttpResponseMessage>
        SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
    {
        // Change the request-side here based on the HttpRequestMessage
        request.Headers.Add("x-my-header", "my value");

        // Do the request
        var response = await base.SendAsync(request, cancellationToken);

        // Change the response-side here based on the HttpResponseMessage

        // Return the modified response
        return response;
    }
}