Utilisation du client géré pour Azure Mobile AppsHow to use the managed client for Azure Mobile Apps

Notes

Visual Studio App Center investit dans des services nouveaux et intégrés, essentiels au développement d’applications mobiles.Visual Studio App Center is investing in new and integrated services central to mobile app development. Les développeurs peuvent utiliser les services Build, Test et Distribute pour configurer le pipeline de livraison et d’intégration continues.Developers can use Build, Test and Distribute services to set up Continuous Integration and Delivery pipeline. Une fois l’application déployée, les développeurs peuvent surveiller l’état et l’utilisation de leur application à l’aide des services Analytics et Diagnostics et interagir avec des utilisateurs à l’aide du service Push.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. Les développeurs peuvent également utiliser Auth pour authentifier leurs utilisateurs, ainsi que le service Data pour conserver et synchroniser les données d’application dans le cloud.Developers can also leverage Auth to authenticate their users and Data service to persist and sync app data in the cloud. Découvrez App Center dès aujourd’hui.Check out App Center today.

Vue d'ensembleOverview

Ce guide vous montre comment mettre en place des scénarios courants à l’aide de la bibliothèque cliente gérée pour Azure App Service Mobile Apps pour les applications Windows et Xamarin.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. Si vous débutez avec Mobile Apps, suivez le didacticiel Démarrage rapide avec Azure Mobile Apps .If you are new to Mobile Apps, you should consider first completing the Azure Mobile Apps quickstart tutorial. Dans ce guide, nous nous concentrons sur le Kit de développement logiciel (SDK) géré côté client.In this guide, we focus on the client-side managed SDK. Pour plus d’informations sur les Kits de développement logiciel (SDK) côté serveur pour Mobile Apps, consultez la documentation du Kit de développement logiciel (SDK) .NET Server or the 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.

Documentation de référenceReference documentation

La documentation de référence du kit SDK du client se trouve ici : Référence du client .NET Azure Mobile Apps.The reference documentation for the client SDK is located here: Azure Mobile Apps .NET client reference. Vous trouverez plusieurs exemples de client dans le référentiel GitHub d’exemples Azure.You can also find several client samples in the Azure-Samples GitHub repository.

Plateformes prises en chargeSupported Platforms

La plate-forme .NET prend en charge les plates-formes suivantes :The .NET Platform supports the following platforms:

  • Versions Xamarin Android pour API 19 à 24 (KitKat jusqu’à Nougat)Xamarin Android releases for API 19 through 24 (KitKat through Nougat)
  • Versions Xamarin iOS pour iOS 8.0 et versions ultérieuresXamarin iOS releases for iOS versions 8.0 and later
  • Plateforme Windows universelleUniversal Windows Platform
  • Windows Phone 8.1Windows Phone 8.1
  • Windows Phone 8.0, à l’exception des applications SilverlightWindows Phone 8.0 except for Silverlight applications

L’authentification « serveur flux » utilise un mode d’affichage WebView pour l’interface utilisateur présentée.The "server-flow" authentication uses a WebView for the presented UI. Si l’appareil n’est pas en mesure de présenter une interface utilisateur WebView, d’autres méthodes d’authentification sont alors nécessaires.If the device is not able to present a WebView UI, then other methods of authentication are needed. Ce SDK ne convient donc pas au type Watch ou d’autres appareils restreints similaires.This SDK is thus not suitable for Watch-type or similarly restricted devices.

Configuration et conditions préalablesSetup and Prerequisites

Nous supposons que vous avez déjà créé et publié votre projet de backend Mobile Apps et qu'il comprend au moins une table.We assume that you have already created and published your Mobile App backend project, which includes at least one table. Dans le code utilisé dans cette rubrique, la table s'intitule TodoItem et contient les colonnes suivantes : Id, Text et Complete.In the code used in this topic, the table is named TodoItem and it has the following columns: Id, Text, and Complete. Il s’agit de la table créée lors du démarrage rapide d’Azure Mobile Apps.This table is the same table created when you complete the Azure Mobile Apps quickstart.

Le type côté client typé en C# correspondant est la classe suivante :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; }
}

L’attribut JsonPropertyAttribute est utilisé pour définir le mappage PropertyName entre le champ client et le champ de la table.The JsonPropertyAttribute is used to define the PropertyName mapping between the client field and the table field.

Pour savoir comment créer des tables dans votre back end Mobile Apps, consultez la rubrique relative au Kit de développement logiciel (SDK) .NET Server or the Node.js Server SDK topic.To learn how to create tables in your Mobile Apps backend, see the .NET Server SDK topic or the Node.js Server SDK topic. Si vous avez créé votre backend Mobile Apps dans le Portail Azure avec le démarrage rapide, vous pouvez également utiliser le paramètre Tables facile dans le Portail Azure.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.

Activation Installer le package du Kit de développement logiciel (SDK) client géréHow to: Install the managed client SDK package

Utilisez une des méthodes suivantes pour installer le package du Kit de développement logiciel (SDK) client géré pour applications mobiles à partir de NuGet:Use one of the following methods to install the managed client SDK package for Mobile Apps from NuGet:

  • Visual Studio Cliquez avec le bouton droit sur votre projet, puis cliquez sur Gérer les packages NuGet, recherchez le package Microsoft.Azure.Mobile.Client et cliquez sur Installer.Visual Studio Right-click your project, click Manage NuGet Packages, search for the Microsoft.Azure.Mobile.Client package, then click Install.
  • Xamarin Studio Cliquez avec le bouton droit sur votre projet, cliquez sur Ajouter>Ajouter des packages NuGet, recherchez le package Microsoft.Azure.Mobile.Client, puis cliquez sur Ajouter un package.Xamarin Studio Right-click your project, click Add > Add NuGet Packages, search for the Microsoft.Azure.Mobile.Client package, and then click Add Package.

Dans votre fichier d’activité principal, pensez à ajouter l’instruction using suivante :In your main activity file, remember to add the following using statement:

using Microsoft.WindowsAzure.MobileServices;

Notes

Notez que tous les packages de support référencés dans votre projet Android doivent avoir la même version.Please note that all the support packages referenced in your Android project must have the same version. Le SDK a la dépendance Xamarin.Android.Support.CustomTabs pour la plateforme Android. Ainsi, si votre projet utilise des packages de support plus récents, vous devez installer directement ce package avec la version nécessaire pour éviter les conflits.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.

Procédure : Utilisation des symboles de débogage dans Visual StudioHow to: Work with debug symbols in Visual Studio

Les symboles de l’espace de noms Microsoft.Azure.Mobile sont disponibles sur SymbolSource. Refer to the SymbolSource instructions pour intégrer SymbolSource à Visual Studio.The symbols for the Microsoft.Azure.Mobile namespace are available on SymbolSource. Refer to the SymbolSource instructions to integrate SymbolSource with Visual Studio.

Création du client Mobile AppsCreate the Mobile Apps client

Le code suivant permet de créer l’objet MobileServiceClient utilisé pour accéder à votre backend Mobile Apps.The following code creates the MobileServiceClient object that is used to access your Mobile App backend.

var client = new MobileServiceClient("MOBILE_APP_URL");

Dans le code précédent, remplacez MOBILE_APP_URL par l’URL du backend Mobile Apps, qui se trouve dans le panneau de votre backend Mobile Apps du portail Azure.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. L’objet MobileServiceClient doit être un singleton.The MobileServiceClient object should be a singleton.

Utilisation des tablesWork with Tables

La section suivante explique comment rechercher et récupérer les enregistrements et modifier les données dans la table.The following section details how to search and retrieve records and modify the data within the table. Cet article contient les rubriques suivantes :The following topics are covered:

Procédure : Création d’une référence de tableHow to: Create a table reference

L’ensemble du code permettant d’accéder aux données d’une table du backend ou de les modifier appelle des fonctions sur l’objet MobileServiceTable .All the code that accesses or modifies data in a backend table calls functions on the MobileServiceTable object. Obtenez une référence à la table en appelant la méthode GetTable , comme suit :Obtain a reference to the table by calling the GetTable method, as follows:

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

L’objet renvoyé utilise le modèle de sérialisation typé.The returned object uses the typed serialization model. Les modèles de sérialisation non typés sont également pris en charge.An untyped serialization model is also supported. L’exemple de code suivant crée une référence à une table non typée :The following example creates a reference to an untyped table:

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

Dans les requêtes non typées, vous devez spécifier la chaîne de requête OData sous-jacente.In untyped queries, you must specify the underlying OData query string.

Procédure : Interrogation des données à partir de votre application mobileHow to: Query data from your Mobile App

Cette section explique comment émettre des requêtes à destination du backend Mobile Apps, qui inclut les fonctionnalités suivantes :This section describes how to issue queries to the Mobile App backend, which includes the following functionality:

Notes

Une taille de page gérée par le serveur est imposée pour empêcher le renvoi de toutes les lignes.A server-driven page size is enforced to prevent all rows from being returned. La pagination permet d'éviter que les requêtes par défaut associées à des jeux de données volumineux aient un impact négatif sur le service.Paging keeps default requests for large data sets from negatively impacting the service. Pour obtenir le renvoi de plus de 50 lignes, utilisez les méthodes Skip et Take, comme décrit dans la section Renvoyer les données dans les pages.To return more than 50 rows, use the Skip and Take method, as described in Return data in pages.

Procédure : Filtrer les données renvoyéesHow to: Filter returned data

Le code suivant montre comment filtrer des données en incluant une clause Where dans une requête.The following code illustrates how to filter data by including a Where clause in a query. Il renvoie tous les éléments de todoTable dont la propriété Complete est égale à false.It returns all items from todoTable whose Complete property is equal to false. La fonction Where applique un prédicat de filtrage de ligne à la requête au niveau de la table.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();

Vous pouvez afficher l’URI de la requête envoyée au backend en utilisant un logiciel d’inspection des messages, par exemple les outils destinés aux développeurs de navigateurs ou 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. Si vous examinez l’URI de requête, vous remarquerez que la chaîne de requête elle-même est modifiée :If you look at the request URI, notice that the query string is modified:

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

Cette requête OData est traduite en requête SQL par le Kit de développement logiciel (SDK) de serveur :This OData request is translated into an SQL query by the Server SDK:

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

La fonction transmise à la méthode Where peut avoir un nombre de conditions arbitraire.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();

Cet exemple serait traduit en requête SQL par le Kit de développement logiciel (SDK) de serveur :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

Cette requête peut également être fractionnée en plusieurs clauses :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();

Les deux méthodes sont équivalentes et peuvent être utilisées de manière interchangeable.The two methods are equivalent and may be used interchangeably. La dernière option—qui consiste à concaténer plusieurs prédicats dans une même requête—est plus compacte. C'est celle que nous recommandons.The former option—of concatenating multiple predicates in one query—is more compact and recommended.

La clause Where prend en charge les opérations traduites dans le sous-ensemble OData.The Where clause supports operations that be translated into the OData subset. Les opérations incluent :Operations include:

  • les opérateurs relationnels (==, !=, <, <=, >, >=),Relational operators (==, !=, <, <=, >, >=),
  • les opérateurs arithmétiques (+, -, /, *, %),Arithmetic operators (+, -, /, *, %),
  • la précision des nombres (Math.Floor, Math.Ceiling),Number precision (Math.Floor, Math.Ceiling),
  • les fonctions de chaîne (Length, Substring, Replace, IndexOf, StartsWith, EndsWith),String functions (Length, Substring, Replace, IndexOf, StartsWith, EndsWith),
  • les propriétés de date (Year, Month, Day, Hour, Minute, Second),Date properties (Year, Month, Day, Hour, Minute, Second),
  • les propriétés d’accès d’un objet, ainsi queAccess properties of an object, and
  • les expressions qui combinent toutes ces opérations.Expressions combining any of these operations.

Quand vous envisagez ce que le SDK Serveur prend en charge, vous pouvez consulter la documentation OData v3.When considering what the Server SDK supports, you can consider the OData v3 Documentation.

Procédure : Trier les données renvoyéesHow to: Sort returned data

Le code suivant montre comment trier les données en incluant une fonction OrderBy ou OrderByDescending dans la requête.The following code illustrates how to sort data by including an OrderBy or OrderByDescending function in the query. Il renvoie des éléments de todoTable, triés par ordre croissant dans le champ Text.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();

Procédure : Renvoyer les données de pagesHow to: Return data in pages

Par défaut, le backend renvoie uniquement les 50 premières lignes.By default, the backend returns only the first 50 rows. Vous pouvez augmenter le nombre de lignes renvoyées en appelant la méthode Take .You can increase the number of returned rows by calling the Take method. Associez Take à la méthode Skip pour demander une « page » spécifique du jeu de données total renvoyé par la requête.Use Take along with the Skip method to request a specific "page" of the total dataset returned by the query. Lorsqu'elle est exécutée, la requête suivante renvoie les trois premiers éléments de la table.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();

La requête révisée ci-dessous ignore les trois premiers résultats et renvoie les trois résultats suivants.The following revised query skips the first three results and returns the next three results. Cette requête produit la deuxième « page » de données, dont la taille est de trois éléments.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();

La méthode IncludeTotalCount demande le nombre total de tous les enregistrements qui auront été renvoyés, en ignorant toute clause de pagination/limite spécifiée :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();

Dans une application réelle, vous pouvez utiliser des requêtes semblables à celles de l’exemple précédent avec un contrôle pager ou une interface utilisateur comparable pour permettre la navigation entre les pages.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.

Notes

Pour remplacer la limite de 50 lignes dans un backend Mobile Apps, vous devez également appliquer l’attribut EnableQueryAttribute à la méthode GET publique et spécifier le comportement de pagination.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. Lorsqu'il est appliqué à la méthode, l'exemple suivant définit le nombre maximal de lignes renvoyées à 1 000 :When applied to the method, the following sets the maximum returned rows to 1000:

[EnableQuery(MaxTop=1000)]

Procédure : Sélectionner des colonnes spécifiquesHow to: Select specific columns

Vous pouvez indiquer le jeu de propriétés à inclure dans les résultats en ajoutant une clause Select à la requête.You can specify which set of properties to include in the results by adding a Select clause to your query. Par exemple, le code suivant montre comment sélectionner un seul champ et comment sélectionner et mettre en forme plusieurs champs :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();

Toutes les fonctions décrites jusqu’ici étant cumulatives, nous pouvons les concaténer.All the functions described so far are additive, so we can keep chaining them. Chaque appel chaîné aura plus de répercussions sur la requête.Each chained call affects more of the query. Un exemple supplémentaire :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();

Procédure : Rechercher des données par IDHow to: Look up data by ID

La fonction LookupAsync permet de rechercher des objets dans la base de données à partir d'un ID particulier.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");

Procédure : Exécution de requêtes non typéesHow to: Execute untyped queries

Quand vous exécutez une requête avec un objet de table non typé, vous devez spécifier explicitement la chaîne de requête OData en appelant ReadAsync, comme dans l’exemple suivant :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");

Vous obtenez en retour des valeurs JSON que vous pouvez utiliser comme conteneur de propriétés.You get back JSON values that you can use like a property bag. Pour plus d’informations sur JToken et Newtonsoft Json.NET, consultez le site Json.NET .For more information on JToken and Newtonsoft Json.NET, see the Json.NET site.

Procédure : Insertion de données dans un backend Mobile AppsHow to: Insert data into a Mobile App backend

Tous les types clients doivent contenir un membre nommé Id, par défaut une chaîne.All client types must contain a member named Id, which is by default a string. Cet Id est requis pour effectuer des opérations CRUD et de synchronisation hors connexion. Le code suivant montre comment utiliser la méthode InsertAsync pour insérer de nouvelles lignes dans une table.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. Le paramètre contient les données à insérer sous forme d'objet .NET.The parameter contains the data to be inserted as a .NET object.

await todoTable.InsertAsync(todoItem);

Si aucune valeur ID personnalisée unique n’est incluse dans todoItem lors d’une insertion, le serveur génère un GUID.If a unique custom ID value is not included in the todoItem during an insert, a GUID is generated by the server. Vous pouvez récupérer l’Id généré en examinant l’objet après le retour de l’appel.You can retrieve the generated Id by inspecting the object after the call returns.

Pour insérer des données non typées, vous pouvez tirer parti de Json.NET :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);

Voici un exemple utilisant une adresse de messagerie comme ID de chaîne unique :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);

Utilisation de valeurs d'IDWorking with ID values

Mobile Apps prend en charge des valeurs de chaîne personnalisées uniques pour la colonne id de la table.Mobile Apps supports unique custom string values for the table's id column. Une valeur de chaîne permet aux applications d’utiliser des valeurs personnalisées telles que les adresses de messagerie ou des noms d’utilisateur pour l’ID.A string value allows applications to use custom values such as email addresses or user names for the ID. Les ID de chaîne fournissent les avantages suivants :String IDs provide you with the following benefits:

  • Les ID sont générés sans effectuer d’aller-retour vers la base de données.IDs are generated without making a round trip to the database.
  • Il est plus facile de fusionner des enregistrements de plusieurs tables ou bases de données.Records are easier to merge from different tables or databases.
  • Les valeurs d’ID peuvent mieux s’intégrer à la logique d’une application.IDs values can integrate better with an application's logic.

Lorsque la valeur d’ID d’une chaîne n’est pas définie sur un enregistrement inséré, le backend Mobile Apps génère une valeur unique pour l’ID.When a string ID value is not set on an inserted record, the Mobile App backend generates a unique value for the ID. Vous pouvez utiliser la méthode Guid.NewGuid pour générer vos propres valeurs d’ID, sur le client ou dans le backend.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"));

Procédure : Modification de données dans un backend Mobile AppsHow to: Modify data in a Mobile App backend

Le code suivant montre comment utiliser la méthode UpdateAsync pour mettre à jour un enregistrement existant avec le même ID avec des informations nouvelles.The following code illustrates how to use the UpdateAsync method to update an existing record with the same ID with new information. Le paramètre contient les données à mettre à jour sous forme d'objet .NET.The parameter contains the data to be updated as a .NET object.

await todoTable.UpdateAsync(todoItem);

Pour mettre à jour des données non typées, vous pouvez utiliser Json.NET ainsi :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);

Vous devez spécifier un champ id si vous effectuez une mise à jour.An id field must be specified when making an update. Le backend utilise le champ id pour identifier la ligne à mettre à jour.The backend uses the id field to identify which row to update. Le champ id peut être obtenu à partir du résultat de l’appel de InsertAsync.The id field can be obtained from the result of the InsertAsync call. Si vous essayez de mettre à jour un élément sans fournir de valeur ArgumentException, une id se déclenche.An ArgumentException is raised if you try to update an item without providing the id value.

Procédure : Suppression de données dans un backend Mobile AppsHow to: Delete data in a Mobile App backend

Le code suivant montre comment utiliser la méthode DeleteAsync pour supprimer une instance existante.The following code illustrates how to use the DeleteAsync method to delete an existing instance. L’instance est identifiée par le champ id défini au niveau de todoItem.The instance is identified by the id field set on the todoItem.

await todoTable.DeleteAsync(todoItem);

Pour supprimer des données non typées, vous pouvez utiliser Json.NET ainsi :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);

Vous devez spécifier un ID lorsque vous effectuez une requête de suppression.When you make a delete request, an ID must be specified. Les autres propriétés ne sont pas transmises au service ou sont ignorées au niveau du service.Other properties are not passed to the service or are ignored at the service. Le résultat d’un appel DeleteAsync a généralement la valeur null.The result of a DeleteAsync call is usually null. L'ID à transmettre peut être obtenu à partir du résultat de l'appel InsertAsync .The ID to pass in can be obtained from the result of the InsertAsync call. Une MobileServiceInvalidOperationException est levée quand vous essayez de supprimer un élément sans spécifier le champ id.A MobileServiceInvalidOperationException is thrown when you try to delete an item without specifying the id field.

Procédure : Utilisation de l’accès concurrentiel optimiste pour résoudre les conflitsHow to: Use Optimistic Concurrency for conflict resolution

Plusieurs clients peuvent écrire à un même moment des modifications dans un même élément.Two or more clients may write changes to the same item at the same time. En l'absence de détection de conflits, la dernière écriture remplace les mises à jour précédentes.Without conflict detection, the last write would overwrite any previous updates. contrôle d'accès concurrentiel optimiste considère que chaque transaction peut être validée et, qu’à ce titre, elle ne fait appel à aucun verrouillage de ressources.Optimistic concurrency control assumes that each transaction can commit and therefore does not use any resource locking. Avant de valider une transaction, le contrôle d'accès concurrentiel optimiste vérifie qu'aucune autre transaction n'a modifié les données.Before committing a transaction, optimistic concurrency control verifies that no other transaction has modified the data. Si les données ont été modifiées, la transaction de validation est annulée.If the data has been modified, the committing transaction is rolled back.

Mobile Apps prend en charge le contrôle d'accès concurrentiel optimiste en suivant les modifications apportées à chaque élément à l'aide de la colonne de la propriété système version définie pour chaque table de votre serveur principal Mobile Apps.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. Chaque fois qu’un enregistrement est mis à jour, Mobile Apps attribue une nouvelle valeur à la propriété version de cet enregistrement.Each time a record is updated, Mobile Apps sets the version property for that record to a new value. À chaque demande de mise à jour, la propriété version de l'enregistrement inclus dans la demande est comparée à celle de l'enregistrement basé sur le serveur.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. Si la version transmise avec la demande ne correspond pas à celle du serveur principal, la bibliothèque cliente déclenche une exception MobileServicePreconditionFailedException<T> .If the version passed with the request does not match the backend, then the client library raises a MobileServicePreconditionFailedException<T> exception. Le type inclus avec l’exception est l’enregistrement du backend contenant la version serveur de l’enregistrement.The type included with the exception is the record from the backend containing the servers version of the record. À partir de cette information, l’application peut décider ou non d’exécuter à nouveau la requête de mise à jour avec la valeur version correcte du serveur principal pour valider les modifications.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.

Pour activer l’accès concurrentiel optimiste, l’application définit une colonne sur la classe table de la propriété système version .Define a column on the table class for the version system property to enable optimistic concurrency. Par exemple :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; }
}

Dans le cas des applications utilisant des tables non typées, l'accès concurrentiel optimiste est activé en définissant l'indicateur Version au niveau de la propriété SystemProperties de la table, comme suit.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;

Outre l’activation de l’accès concurrentiel optimiste, vous devez également intercepter l’exception MobileServicePreconditionFailedException<T> dans votre code au moment de l’appel UpdateAsync.In addition to enabling optimistic concurrency, you must also catch the MobileServicePreconditionFailedException<T> exception in your code when calling UpdateAsync. Résolvez le conflit en appliquant la version correcte pour l’enregistrement mis à jour et appelez UpdateAsync avec l’enregistrement résolu.Resolve the conflict by applying the correct version to the updated record and call UpdateAsync with the resolved record. Le code suivant montre comment résoudre un conflit d’écriture une fois qu’il est détecté :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();
}

Pour en savoir plus, consultez la rubrique Synchronisation des données hors connexion dans Azure Mobile Apps .For more information, see the Offline Data Sync in Azure Mobile Apps topic.

Procédure : liaison de données Mobile Apps à une interface utilisateur WindowsHow to: Bind Mobile Apps data to a Windows user interface

Cette section montre comment afficher des objets de données renvoyés à l'aide d'éléments d'interface utilisateur dans une application Windows.This section shows how to display returned data objects using UI elements in a Windows app. L’exemple de code suivant est lié à la source de la liste avec une requête pour les éléments incomplets.The following example code binds to the source of the list with a query for incomplete items. MobileServiceCollection permet de créer une collection de liaisons prenant en charge Mobile Apps.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;

Certains contrôles dans l’exécution gérée prennent en charge une interface appelée ISupportIncrementalLoading.Some controls in the managed runtime support an interface called ISupportIncrementalLoading. Cette interface permet aux contrôles de demander des données supplémentaires lorsque l'utilisateur fait défiler l'écran.This interface allows controls to request extra data when the user scrolls. Une prise en charge de cette interface peut être intégrée aux applications Windows universelles par le biais de MobileServiceIncrementalLoadingCollection, qui traite automatiquement les appels en provenance des contrôles.There is built-in support for this interface for universal Windows apps via MobileServiceIncrementalLoadingCollection, which automatically handles the calls from the controls. Utilisez MobileServiceIncrementalLoadingCollection dans les applications Windows, comme suit :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;

Pour utiliser la nouvelle collection sur les applications Windows Phone 8 et « Silverlight », utilisez les méthodes d’extension ToCollection au niveau de IMobileServiceTableQuery<T> et 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>. Pour charger les données, appelez LoadMoreItemsAsync().To load data, call LoadMoreItemsAsync().

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

Lorsque vous utilisez la collection créée par l'appel de ToCollectionAsync ou ToCollection, vous obtenez une collection qui peut être liée aux contrôles d'interface utilisateur.When you use the collection created by calling ToCollectionAsync or ToCollection, you get a collection that can be bound to UI controls. Cette collection prend en charge la pagination.This collection is paging-aware. Comme la collection charge les données à partir du réseau, le chargement peut échouer.Since the collection is loading data from the network, loading sometimes fails. Pour gérer ces échecs, ignorez la méthode OnException au niveau de MobileServiceIncrementalLoadingCollection pour traiter les exceptions résultant des appels vers LoadMoreItemsAsync.To handle such failures, override the OnException method on MobileServiceIncrementalLoadingCollection to handle exceptions resulting from calls to LoadMoreItemsAsync.

Imaginez que votre table contient de nombreux champs, mais que vous ne souhaitez en afficher qu'une partie dans votre contrôle.Consider if your table has many fields but you only want to display some of them in your control. Vous pouvez suivre les instructions fournies dans la section précédente «Sélectionner des colonnes spécifiques» pour sélectionner les colonnes à afficher dans l’interface utilisateur.You may use the guidance in the preceding section "Select specific columns" to select specific columns to display in the UI.

Modifier la taille de pageChange the Page size

Par défaut, Azure Mobile Apps retourne au maximum 50 éléments par demande.Azure Mobile Apps returns a maximum of 50 items per request by default. Vous pouvez modifier la taille de pagination en augmentant la taille de page maximale à la fois sur le client et sur le serveur.You can change the paging size by increasing the maximum page size on both the client and server. Pour augmenter la taille de page demandée, spécifiez PullOptions lorsque vous utilisez PullAsync() :To increase the requested page size, specify PullOptions when using PullAsync():

PullOptions pullOptions = new PullOptions
    {
        MaxPageSize = 100
    };

Si vous définissez sur une valeur PageSize égale ou supérieure à 100 sur le serveur, une requête renvoie jusqu’à 100 éléments.Assuming you have made the PageSize equal to or greater than 100 within the server, a request returns up to 100 items.

Utilisation de tables hors connexionWork with Offline Tables

Les tables hors connexion utilisent une banque de données SQLite locale pour stocker les données pour une utilisation en mode hors connexion.Offline tables use a local SQLite store to store data for use when offline. Toutes les opérations de table sont effectuées sur la banque de données SQLite locale au lieu de la banque de données du serveur distant.All table operations are done against the local SQLite store instead of the remote server store. Pour créer une table hors connexion, préparez tout d’abord votre projet :To create an offline table, first prepare your project:

  1. Dans Visual Studio, cliquez sur la solution > Gérer les packages NuGet pour la solution... , puis recherchez et installez le package NuGet Microsoft.Azure.Mobile.Client.SQLiteStore pour tous les projets dans la solution.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. (Facultatif) Pour prendre en charge des appareils Windows, installez l’un des packages runtime SQLite suivants :(Optional) To support Windows devices, install one of the following SQLite runtime packages:

  3. (Facultatif).(Optional). Pour les appareils Windows, cliquez sur Références > Ajouter une référence, développez le dossier Windows > Extensions, puis activez le Kit de développement logiciel (SDK) SQLite pour Windows approprié en même temps que le Kit de développement logiciel (SDK) Runtime Visual C++ 2013 pour 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. Les noms de SDK SQLite varient légèrement en fonction de la plateforme Windows utilisée.The SQLite SDK names vary slightly with each Windows platform.

Avant que vous ne puissiez créer une référence de table, la banque de données locale doit être préparée :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);

L’initialisation de la banque de données est normalement effectuée immédiatement après la création du client.Store initialization is normally done immediately after the client is created. L’OfflineDbPath doit être un nom de fichier approprié pour une utilisation sur toutes les plates-formes prises en charge.The OfflineDbPath should be a filename suitable for use on all platforms that you support. Si le chemin d’accès est un chemin d’accès qualifié complet (autrement dit, s’il commence par une barre oblique), ce chemin d’accès est utilisé.If the path is a fully qualified path (that is, it starts with a slash), then that path is used. Si le chemin d’accès n’est pas complet, le fichier est placé dans un emplacement spécifique à la plateforme.If the path is not fully qualified, the file is placed in a platform-specific location.

  • Pour les appareils iOS et Android, le chemin d’accès par défaut est le dossier des fichiers personnels.For iOS and Android devices, the default path is the "Personal Files" folder.
  • Pour les appareils Windows, le chemin d’accès par défaut est le dossier « AppData » spécifiques à l’application.For Windows devices, the default path is the application-specific "AppData" folder.

Une référence de table peut être obtenue à l’aide de la GetSyncTable<> méthode :A table reference can be obtained using the GetSyncTable<> method:

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

Il est inutile de s’authentifier pour utiliser une table hors connexion.You do not need to authenticate to use an offline table. Il vous suffit de vous authentifier lorsque vous communiquez avec le service backend.You only need to authenticate when you are communicating with the backend service.

Synchronisation d’une table hors connexionSyncing an Offline Table

Les tables hors connexion ne sont pas synchronisées avec le backend par défaut.Offline tables are not synchronized with the backend by default. La synchronisation est divisée en deux parties.Synchronization is split into two pieces. Vous pouvez transmettre des modifications en dehors du processus de téléchargement de nouveaux éléments.You can push changes separately from downloading new items. Voici une méthode de synchronisation typique :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"]);
        }
    }
}

Si le premier argument de PullAsync est null, la synchronisation incrémentielle n’est pas utilisée.If the first argument to PullAsync is null, then incremental sync is not used. Chaque opération de synchronisation récupère tous les enregistrements.Each sync operation retrieves all records.

Le Kit de développement logiciel (SDK) effectue une PushAsync() implicite avant l’extraction des enregistrements.The SDK performs an implicit PushAsync() before pulling records.

La gestion des conflits s’effectue par le biais d’une méthode PullAsync().Conflict handling happens on a PullAsync() method. Vous pouvez traiter les conflits de la même manière que les tables en ligne.You can deal with conflicts in the same way as online tables. Le conflit est généré lorsque PullAsync() est appelée à la place de ou pendant l’insertion, la mise à jour ou la suppression.The conflict is produced when PullAsync() is called instead of during the insert, update, or delete. Si plusieurs conflits se produisent, les opérations sont regroupées dans une seule MobileServicePushFailedException.If multiple conflicts happen, they are bundled into a single MobileServicePushFailedException. Gérez chaque défaillance séparément.Handle each failure separately.

Utilisation d’une API personnaliséeWork with a custom API

Une API personnalisée vous permet de définir des points de terminaison exposant une fonctionnalité de serveur qui ne mappe pas vers une opération d'insertion, de mise à jour, de suppression ou de lecture.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. En utilisant une API personnalisée, vous pouvez exercer davantage de contrôle sur la messagerie, notamment lire et définir des en-têtes de message HTTP et définir un format de corps de message autre que JSON.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.

Vous appelez une API personnalisée en appelant l'une des méthodes InvokeApiAsync sur le client.You call a custom API by calling one of the InvokeApiAsync methods on the client. Par exemple, la ligne de code suivante envoie une requête POST à l’API completeAll sur le backend :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);

Il s’agit d’un appel de méthode typé pour lequel le type de renvoi MarkAllResult doit être défini.This form is a typed method call and requires that the MarkAllResult return type is defined. Les méthodes typées et non typées sont toutes deux prises en charge.Both typed and untyped methods are supported.

La méthode InvokeApiAsync() ajoute « /api/ » à l’API que vous souhaitez appeler, sauf si l’API commence par « / ».The InvokeApiAsync() method prepends '/api/' to the API that you wish to call unless the API starts with a '/'. Par exemple :For example:

  • InvokeApiAsync("completeAll",...) appelle /api/completeAll sur le serveur principalInvokeApiAsync("completeAll",...) calls /api/completeAll on the backend
  • InvokeApiAsync("/.auth/me",...) appelle /.auth/me sur le serveur principalInvokeApiAsync("/.auth/me",...) calls /.auth/me on the backend

Vous pouvez utiliser InvokeApiAsync pour appeler des API web, y compris si celles-ci ne sont pas définies avec Azure Mobile Apps.You can use InvokeApiAsync to call any WebAPI, including those WebAPIs that are not defined with Azure Mobile Apps. Lorsque vous utilisez InvokeApiAsync(), les en-têtes appropriés, y compris les en-têtes d’authentification, sont envoyés avec la demande.When you use InvokeApiAsync(), the appropriate headers, including authentication headers, are sent with the request.

Authentification des utilisateursAuthenticate users

Mobile Apps prend en charge l’authentification et l’autorisation des utilisateurs de l’application par l’intermédiaire de différents fournisseurs d’identité externes : Facebook, Google, compte Microsoft, Twitter et 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. Vous pouvez définir des autorisations sur les tables pour limiter l'accès à certaines opérations aux seuls utilisateurs authentifiés.You can set permissions on tables to restrict access for specific operations to only authenticated users. Vous pouvez également utiliser l’identité des utilisateurs authentifiés pour implémenter des règles d’autorisation dans les scripts serveur.You can also use the identity of authenticated users to implement authorization rules in server scripts. Pour plus d'informations, consultez le didacticiel Ajout de l'authentification à votre application.For more information, see the tutorial Add authentication to your app.

Deux flux d’authentification sont pris en charge : le flux géré par le client et le flux géré par le serveur.Two authentication flows are supported: client-managed and server-managed flow. Le flux géré par le serveur fournit l'authentification la plus simple, car il repose sur l'interface d'authentification Web du fournisseur.The server-managed flow provides the simplest authentication experience, as it relies on the provider's web authentication interface. En revanche, le flux géré par le client est celui qui s'intègre le plus profondément aux fonctionnalités propres à l'appareil, car il s'appuie sur les Kits de développement logiciel (SDK) propres au fournisseur et à l'appareil.The client-managed flow allows for deeper integration with device-specific capabilities as it relies on provider-specific device-specific SDKs.

Notes

Nous vous recommandons d’utiliser un flux géré par le client dans vos applications de production.We recommend using a client-managed flow in your production apps.

Pour configurer l’authentification, vous devez inscrire votre application avec un ou plusieurs fournisseurs d’identité.To set up authentication, you must register your app with one or more identity providers. Le fournisseur d’identité génère un ID client et une clé secrète client pour votre application.The identity provider generates a client ID and a client secret for your app. Ces valeurs sont ensuite définies dans votre backend pour activer l’authentification/autorisation d’Azure App Service.These values are then set in your backend to enable Azure App Service authentication/authorization. Pour plus d’informations, suivez les instructions détaillées dans le didacticiel Ajout de l'authentification à votre application.For more information, follow the detailed instructions in the tutorial Add authentication to your app.

Les rubriques traitées dans cette section sont les suivantes :The following topics are covered in this section:

Authentification gérée par le clientClient-managed authentication

Votre application peut contacter le fournisseur d’identité de manière indépendante, puis fournir le jeton renvoyé pendant la connexion à votre backend.Your app can independently contact the identity provider and then provide the returned token during login with your backend. Le flux client permet de proposer l'authentification unique aux utilisateurs ou de récupérer d'autres données utilisateur auprès du fournisseur d'identité.This client flow enables you to provide a single sign-on experience for users or to retrieve additional user data from the identity provider. L’authentification par flux client est préférable à l’utilisation d’un flux géré par le serveur, car le SDK du fournisseur d’identité offre une interface UX native plus simple et permet une personnalisation supplémentaire.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.

Des exemples sont fournis pour les modèles suivants d’authentification gérée par le client :Examples are provided for the following client-flow authentication patterns:

Authentification des utilisateurs avec la bibliothèque ADAL (Active Directory Authentication Library)Authenticate users with the Active Directory Authentication Library

Vous pouvez utiliser la bibliothèque d’authentification Active Directory (ADAL) pour initier l’authentification des utilisateurs à partir du client via l’authentification Azure Active Directory.You can use the Active Directory Authentication Library (ADAL) to initiate user authentication from the client using Azure Active Directory authentication.

  1. Si vous souhaitez configurer le backend de votre application mobile pour utiliser la connexion AAD, suivez le didacticiel Configuration d’App Service la connexion Active Directory.Configure your mobile app backend for AAD sign-on by following the How to configure App Service for Active Directory login tutorial. Bien que cette étape soit facultative, veillez à inscrire une application cliente native.Make sure to complete the optional step of registering a native client application.

  2. Dans Visual Studio ou Xamarin Studio, ouvrez votre projet et ajoutez une référence au package NuGet Microsoft.IdentityModel.Clients.ActiveDirectory .In Visual Studio or Xamarin Studio, open your project and add a reference to the Microsoft.IdentityModel.Clients.ActiveDirectory NuGet package. Au cours de la recherche, incluez les versions préliminaires.When searching, include pre-release versions.

  3. Ajoutez le code suivant à votre application, en fonction de la plateforme utilisée.Add the following code to your application, according to the platform you are using. Dans chaque cas, effectuez les remplacements suivants :In each, make the following replacements:

    • Remplacez INSERT-AUTHORITY-HERE par le nom du client dans lequel vous avez approvisionné votre application.Replace INSERT-AUTHORITY-HERE with the name of the tenant in which you provisioned your application. Le format doit être https://login.microsoftonline.com/contoso.onmicrosoft.com.The format should be https://login.microsoftonline.com/contoso.onmicrosoft.com. Cette valeur peut être copiée depuis l’onglet Domaine de votre Azure Active Directory dans le Portail Azure.This value can be copied from the Domain tab in your Azure Active Directory in the Azure portal.

    • Remplacez INSERT-RESOURCE-ID-HERE par l’ID client du serveur principal de votre application mobile.Replace INSERT-RESOURCE-ID-HERE with the client ID for your mobile app backend. Vous pouvez obtenir l’ID client sur le portail, sous l’onglet Avancé du menu Paramètres Azure Active Directory.You can obtain the client ID from the Advanced tab under Azure Active Directory Settings in the portal.

    • Remplacez INSERT-CLIENT-ID-HERE par l’ID client que vous avez copié depuis l’application cliente native.Replace INSERT-CLIENT-ID-HERE with the client ID you copied from the native client application.

    • Remplacez INSERT-REDIRECT-URI-HERE par le point de terminaison /.auth/login/done de votre site, en utilisant le modèle HTTPS.Replace INSERT-REDIRECT-URI-HERE with your site's /.auth/login/done endpoint, using the HTTPS scheme. Cette valeur doit être similaire à https://contoso.azurewebsites.net/.auth/login/done .This value should be similar to https://contoso.azurewebsites.net/.auth/login/done.

      Voici le code nécessaire pour chaque plateforme :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);
      }
      

Authentification unique à l’aide d’un jeton Facebook ou GoogleSingle Sign-On using a token from Facebook or Google

Vous pouvez utiliser le flux client comme indiqué dans cet extrait de code pour Facebook ou 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();
    }
}

Authentification gérée par le serveurServer-managed authentication

Une fois que vous avez inscrit votre fournisseur d’identité, appelez la méthode LoginAsync sur le [MobileServiceClient] avec la valeur MobileServiceAuthenticationProvider de votre fournisseur.Once you have registered your identity provider, call the LoginAsync method on the [MobileServiceClient] with the MobileServiceAuthenticationProvider value of your provider. Par exemple, le code suivant initie une connexion de flux serveur via 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();
    }
}

Si vous utilisez un fournisseur d'identité autre que Facebook, remplacez la valeur de MobileServiceAuthenticationProvider par la valeur de votre fournisseur.If you are using an identity provider other than Facebook, change the value of MobileServiceAuthenticationProvider to the value for your provider.

Dans un flux serveur, Azure App Service gère le flux d’authentification OAuth en affichant la page de connexion du fournisseur sélectionné.In a server flow, Azure App Service manages the OAuth authentication flow by displaying the sign-in page of the selected provider. Après le retour du fournisseur identité, Azure App Service génère un jeton d’authentification App Service.Once the identity provider returns, Azure App Service generates an App Service authentication token. La LoginAsync renvoie un MobileServiceUser, qui fournit à la fois l'UserId de l'utilisateur authentifié et le MobileServiceAuthenticationToken, sous la forme d'un jeton Web JSON (JWT).The LoginAsync method returns a MobileServiceUser, which provides both the UserId of the authenticated user and the MobileServiceAuthenticationToken, as a JSON web token (JWT). Ce jeton peut être mis en cache et réutilisé jusqu'à ce qu'il arrive à expiration.This token can be cached and reused until it expires. Pour plus d'informations, consultez la section Mise en cache du jeton d'authentification.For more information, see Caching the authentication token.

Mise en cache du jeton d’authentificationCaching the authentication token

Dans certains cas, il est possible d’éviter l’appel à la méthode de connexion après la première authentification réussie en stockant le jeton d’authentification à partir du fournisseur.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. Les applications Microsoft Store et UWP peuvent utiliser PasswordVault pour mettre en cache le jeton d’authentification en cours après une connexion réussie, comme suit :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));

La valeur UserId est stockée en tant que nom d’utilisateur des informations d’identification et le jeton est stocké en tant que mot de passe.The UserId value is stored as the UserName of the credential and the token is the stored as the Password. Lors des démarrages suivants, vous pouvez vérifier les informations d’identification mises en cache dans PasswordVault.On subsequent start-ups, you can check the PasswordVault for cached credentials. L’exemple suivant utilise les informations d’identification mises en cache si elles sont trouvées. Sinon, il tente à nouveau l’authentification avec le backend :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.
}

Lorsque vous déconnectez un utilisateur, vous devez également supprimer les informations d’identifications stockées, comme suit :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));

Les applications Xamarin utilisent les API Xamarin.Auth pour stocker de manière sécurisée les informations d’identification dans un objet Account .Xamarin apps use the Xamarin.Auth APIs to securely store credentials in an Account object. Pour obtenir un exemple d’utilisation de ces API, consultez le fichier de code AuthStore.cs dans l’exemple de partage de photos ContosoMoments.For an example of using these APIs, see the AuthStore.cs code file in the ContosoMoments photo sharing sample.

Lorsque vous utilisez l’authentification gérée par le client, vous pouvez également mettre en cache le jeton d’accès obtenu à partir du fournisseur (par exemple, Facebook ou Twitter).When you use client-managed authentication, you can also cache the access token obtained from your provider such as Facebook or Twitter. Ce jeton peut être fourni pour demander un nouveau jeton d’authentification à partir du backend, comme suit :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);

Notifications PushPush Notifications

Les rubriques suivantes traitent des notifications Push :The following topics cover Push Notifications:

Procédure : Inscription aux notifications PushHow to: Register for Push Notifications

Le client Mobile Apps permet de s’inscrire aux notifications Push avec Azure Notification Hubs.The Mobile Apps client enables you to register for push notifications with Azure Notification Hubs. Lors de l'inscription, vous obtenez un handle à partir de spécifique à la plate-forme Push Notification Service (PNS).When registering, you obtain a handle that you obtain from the platform-specific Push Notification Service (PNS). Vous fournissez ensuite cette valeur, ainsi que toutes les balises lorsque vous créez l'inscription.You then provide this value along with any tags when you create the registration. Le code suivant inscrit votre application Windows aux notifications push avec le service de notification Windows (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);
}

Si vous déployez vers WNS, alors vous DEVEZ obtenir un SID de package Microsoft Store.If you are pushing to WNS, then you MUST obtain a Microsoft Store package SID. Pour plus d'informations sur les applications Windows, y compris l'enregistrement pour les inscriptions de modèle, consultez la page Ajouter des notifications Push à votre application.For more information on Windows apps, including how to register for template registrations, see Add push notifications to your app.

La requête de balises à partir du client n’est pas prise en charge.Requesting tags from the client is not supported. Les requêtes de balises sont supprimées de manière silencieuse à partir de l’inscription.Tag Requests are silently dropped from registration. Si vous souhaitez inscrire votre appareil avec des balises, créez une API personnalisée qui utilise l’API Notification Hubs pour effectuer l’inscription de votre part.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. Appelez l'API personnalisée au lieu de la méthode RegisterNativeAsync().Call the Custom API instead of the RegisterNativeAsync() method.

Procédure : Obtention d’un SID de package Microsoft StoreHow to: Obtain a Microsoft Store package SID

Un SID de package est nécessaire pour l’activation des notifications Push dans les applications Microsoft Store.A package SID is needed for enabling push notifications in Microsoft Store apps. Pour recevoir un SID de package, enregistrez votre application auprès du Microsoft Store.To receive a package SID, register your application with the Microsoft Store.

Pour obtenir cette valeur :To obtain this value:

  1. Dans l’Explorateur de solutions de Visual Studio, cliquez avec le bouton droit sur le projet d’application Microsoft Store, puis cliquez sur Store > Associer l’application au Windows Store... .In Visual Studio Solution Explorer, right-click the Microsoft Store app project, click Store > Associate App with the Store....
  2. Dans l'Assistant, cliquez sur Suivant, connectez-vous à votre compte Microsoft, saisissez un nom pour votre application dans Réserver un nouveau nom d'application, puis cliquez sur Réserver.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. Une fois l’inscription de l’application effectuée, sélectionnez son nom, cliquez sur Suivant, puis sur Associer.After the app registration is successfully created, select the app name, click Next, and then click Associate.
  4. Connectez-vous au Centre de développement Windows à l’aide de votre compte Microsoft.Log in to the Windows Dev Center using your Microsoft Account. Sous Mes applications, cliquez sur l’inscription de l’application que vous venez de créer.Under My apps, click the app registration you created.
  5. Cliquez sur Gestion des applications > Identité de l'application, puis faites défiler jusqu'à trouver votre SID de package.Click App management > App identity, and then scroll down to find your Package SID.

De nombreuses utilisations du SID de package traitent ce dernier comme une URI, auquel cas vous devez utiliser ms-app:// comme schéma.Many uses of the package SID treat it as a URI, in which case you need to use ms-app:// as the scheme. Prenez note de la version de votre package SID formé en concaténant cette valeur comme préfixe.Make note of the version of your package SID formed by concatenating this value as a prefix.

Les applications Xamarin nécessitent un code supplémentaire pour pouvoir enregistrer une application en cours d’exécution sur les plateformes Android ou iOS.Xamarin apps require some additional code to be able to register an app running on the iOS or Android platforms. Pour plus d’informations, consultez la rubrique pour votre plateforme :For more information, see the topic for your platform:

Procédure : Inscrire des modèles Push pour envoyer des notifications multiplateformeHow to: Register push templates to send cross-platform notifications

Pour enregistrer les modèles, utilisez la méthode RegisterAsync() avec les modèles, comme suit :To register templates, use the RegisterAsync() method with the templates, as follows:

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

Vos modèles doivent être de type JObject et peuvent contenir plusieurs modèles au format JSON suivant :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;
}

La méthode RegisterAsync() accepte également les mosaïques secondaires :The method RegisterAsync() also accepts Secondary Tiles:

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

Toutes les balises sont supprimées lors de l’inscription pour la sécurité.All tags are stripped away during registration for security. Pour ajouter des balises à des installations ou des modèles dans des installations, consultez [Utiliser le Kit de développement logiciel (SDK) du serveur principal .NET pour Azure Mobile Apps].To add tags to installations or templates within installations, see [Work with the .NET backend server SDK for Azure Mobile Apps].

Pour envoyer des notifications à l’aide de ces modèles inscrits, consultez les API Notification Hubs.To send notifications utilizing these registered templates, refer to the Notification Hubs APIs.

Rubriques diversesMiscellaneous Topics

Procédure : des erreursHow to: Handle errors

Quand une erreur se produit sur le backend, le Kit de développement logiciel (SDK) client déclenche une MobileServiceInvalidOperationException.When an error occurs in the backend, the client SDK raises a MobileServiceInvalidOperationException. L’exemple suivant montre comment gérer une exception renvoyée par le backend :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
    }
}

Vous trouverez un autre exemple de traitement des conditions d’erreur dans l’ exemple de fichiers Mobile Apps.Another example of dealing with error conditions can be found in the Mobile Apps Files Sample. L’exemple LoggingHandler fournit un gestionnaire de délégué de journalisation pour consigner les requêtes envoyées au backend.The LoggingHandler example provides a logging delegate handler to log the requests being made to the backend.

Procédure : Personnalisation des en-têtes de requêteHow to: Customize request headers

Pour prendre en charge votre scénario d’application en particulier, vous devrez peut-être personnaliser la communication avec le backend Mobile Apps.To support your specific app scenario, you might need to customize communication with the Mobile App backend. Par exemple, il est possible que vous vouliez ajouter un en-tête personnalisé à chaque demande sortante ou même modifier le code d'état des réponses.For example, you may want to add a custom header to every outgoing request or even change responses status codes. Pour cela, utilisez un DelegatingHandlerpersonnalisé, comme dans l'exemple suivant :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;
    }
}