Jak používat spravovaného klienta pro Azure Mobile Apps

Přehled

Tato příručka vám ukáže, jak provádět běžné scénáře pomocí spravované klientské knihovny pro Azure App Service Mobile Apps pro Windows a Xamarin. Pokud s nasazením služby Mobile Apps, měli byste nejprve zvážit dokončení kurzu rychlý Mobile Apps Azure . V této příručce se zaměříme na spravovanou sadu SDK na straně klienta. Další informace o sadch SDK na straně serveru pro Mobile Apps najdete v dokumentaci k sadě .NET Server SDK nebo sadě SDKNode.js Serveru.

Referenční dokumentace

Referenční dokumentace pro klientskou sadu SDK je k dispozici tady: Referenční informace Mobile Apps rozhraní .NET pro Azure. Několik ukázek klienta najdete také v úložišti Azure-Samples GitHub úložiště.

Podporované platformy

Platforma .NET podporuje následující platformy:

  • Vydání Xamarin Androidu pro rozhraní API 19 až 24 (KitKat přes Nougat)
  • Verze Xamarin iOS pro iOS verze 8.0 a novější
  • Univerzální platforma Windows
  • Windows Phone 8.1
  • Windows Phone 8.0 s výjimkou aplikací Silverlight

Při ověřování "toku serveru" se pro prezentované uživatelské rozhraní používá WebView. Pokud zařízení nemůže prezentovat uživatelské rozhraní WebView, jsou potřeba další metody ověřování. Tato sada SDK proto není vhodná pro zařízení typu Watch nebo podobně omezená.

Nastavení a požadavky

Předpokládáme, že jste už vytvořili a publikovali back-endový projekt mobilní aplikace, který obsahuje alespoň jednu tabulku. V kódu použitém v tomto tématu se TodoItem tabulka jmenuje a má následující sloupce: Id, Texta Complete. Tato tabulka je stejná jako tabulka vytvořená po dokončení rychlého Mobile Apps Azure.

Odpovídající typ na straně klienta v jazyce C# je následující třída:

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

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

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

Atribut JsonPropertyAttribute slouží k definování mapování PropertyName mezi polem klienta a polem tabulky.

Informace o vytváření tabulek v back-Mobile Apps najdete v tématu .NET Server SDK nebo v tématuNode.js Server SDK. Pokud jste back-end mobilní aplikace vytvořili v Azure Portal pomocí rychlého startu, můžete také použít nastavení Snadné tabulky v Azure Portal.

Postupy: Instalace balíčku spravované klientské sady SDK

Pomocí jedné z následujících metod nainstalujte balíček spravované klientské sady SDK pro Mobile Apps z NuGet:

  • Visual Studio pravým tlačítkem myši klikněte na projekt, klikněte na Spravovat NuGet balíčků, Microsoft.Azure.Mobile.Client vyhledejte balíček a pak klikněte na Nainstalovat.
  • Xamarin Studio Klikněte pravým tlačítkem na projekt, klikněte na PřidatPřidat>NuGet balíčků, Microsoft.Azure.Mobile.Client vyhledejte balíček a pak klikněte na Přidat balíček.

V hlavním souboru aktivit nezapomeňte přidat následující příkaz using :

using Microsoft.WindowsAzure.MobileServices;

Poznámka

Upozorňujeme, že všechny balíčky podporu odkazované ve vašem projektu Android musí mít stejnou verzi. Sada SDK je závislá Xamarin.Android.Support.CustomTabs na platformě Android, takže pokud váš projekt používá novější balíčky podpory, musíte tento balíček nainstalovat s požadovanou verzí přímo, abyste se vyhnuli konfliktům.

Postupy: Práce se symboly ladění v Visual Studio

Symboly pro obor názvů Microsoft.Azure.Mobile jsou k dispozici na webu SymbolSource. Pokyny k integraci SymbolSource s rozhraním Visual Studio.

Vytvoření Mobile Apps klienta

Následující kód vytvoří objekt MobileServiceClient , který se používá pro přístup k back-endu mobilní aplikace.

var client = new MobileServiceClient("MOBILE_APP_URL");

V předchozím kódu nahraďte MOBILE_APP_URL adresou URL back-endu mobilní aplikace, která se nachází v okně back-endu mobilní aplikace v Azure Portal. Objekt MobileServiceClient by měl být singleton.

Práce s tabulkami

Následující část podrobně popisuje, jak vyhledávat a načítat záznamy a upravovat data v tabulce. Jsou uvedená následující témata:

Postupy: Vytvoření odkazu na tabulku

Veškerý kód, který přistupuje k datům v back-endové tabulce nebo je upravuje, volá funkce objektu MobileServiceTable . Získejte odkaz na tabulku voláním metody GetTable následujícím způsobem:

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

Vrácený objekt používá typový model serializace. Je také podporován model beztypové serializace. Následující příklad vytvoří odkaz na tabulku bez typu:

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

V netypových dotazech musíte zadat základní řetězec dotazu OData.

Postupy: Dotazování na data z mobilní aplikace

Tato část popisuje, jak vydávat dotazy na back-end mobilní aplikace, které zahrnují následující funkce:

Poznámka

Velikost stránky řízené serverem se vynucuje, aby se zabránilo vrácení všech řádků. Stránkování zajišťuje, aby výchozí požadavky na velké datové sady negativně ovlivnily službu. Pokud chcete vrátit více než 50 řádků, použijte Skip metodu a Take , jak je popsáno v části Vrácení dat na stránkách.

Postupy: Filtrování vrácených dat

Následující kód ukazuje, jak filtrovat data zahrnutím Where klauzule do dotazu. Vrátí všechny položky, jejichž todoTable vlastnost Complete je rovna false. Funkce Where použije na dotaz na tabulku predikát filtrování řádků.

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

Identifikátor URI požadavku odeslaného do back-endu můžete zobrazit pomocí softwaru pro kontrolu zpráv, jako jsou vývojářské nástroje prohlížeče nebo Fiddler. Pokud se podíváte na identifikátor URI požadavku, všimněte si, že se řetězec dotazu změnil:

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

Tento požadavek OData se přeloží do SQL dotazu sadou Server SDK:

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

Funkce předaná metodě Where může mít libovolný počet podmínek.

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

Tento příklad by byla přeložena do SQL dotaz pomocí serverové sady SDK:

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

Tento dotaz lze také rozdělit na více klauzulí:

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

Tyto dvě metody jsou ekvivalentní a mohou být zaměnitelné. První možnost zřetězování více predikátů v jednom dotazu je kompaktnější a doporučovat.

Klauzule Where podporuje operace, které se překládají do podmnožiny OData. Mezi operace patří:

  • Relační operátory (==, !=, <, <=, >, >=),
  • Aritmetické operátory (+, -, /, *, %)
  • Přesnost čísel (Math. Floor, Math. strop),
  • Řetězcové funkce (délka, podřetězec, Replace, IndexOf, StartsWith, EndsWith),
  • Vlastnosti data (rok, měsíc, den, hodina, minuta, sekundy),
  • Přístup k vlastnostem objektu a
  • Výrazy kombinující některé z těchto operací.

Při zvažování, co podporuje sada SDK serveru, můžete zvážit dokumentaci k OData V3.

Postupy: řazení vrácených dat

Následující kód ilustruje, jak řadit data zahrnutím funkce OrderBy nebo OrderByDescending do dotazu. Vrátí položky ze todoTable vzestupného řazení podle Text pole.

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

Postupy: vrácení dat na stránkách

Ve výchozím nastavení back-end vrátí jenom prvních 50 řádků. Počet vrácených řádků můžete zvýšit voláním metody přijmout . Použijte Take spolu s metodou Skip pro vyžádání konkrétní "stránky" celkové datové sady vrácené dotazem. Následující dotaz po provedení vrátí první tři položky v tabulce.

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

Následující revidovaný dotaz přeskočí první tři výsledky a vrátí další tři výsledky. Tento dotaz vytvoří druhou "stránku" dat, kde je velikost stránky tři položky.

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

Metoda IncludeTotalCount požaduje celkový počet všech záznamů, které by byly vráceny, ignorování všech zadaných klauzulí stránkování a omezení:

query = query.IncludeTotalCount();

V reálné aplikaci můžete použít dotazy podobné předchozím příkladům pomocí ovládacího prvku stránkování nebo srovnatelného uživatelského rozhraní pro navigaci mezi stránkami.

Poznámka

Chcete-li v back-endu mobilní aplikace přepsat 50 – limit řádku, je nutné také použít EnableQueryAttribute na metodu public get a určit chování stránkování. Při použití na metodu nastaví následující nastavení maximální počet vrácených řádků na 1000:

[EnableQuery(MaxTop=1000)]

Postupy: Výběr konkrétních sloupců

Přidáním klauzule Select do dotazu můžete určit, kterou sadu vlastností zahrnout do výsledků. Například následující kód ukazuje, jak vybrat pouze jedno pole a také jak vybrat a formátovat více polí:

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

Všechny funkce popsané v této míře jsou doplňkové, takže je můžeme dál zřetězit. Každé zřetězené volání má vliv na více dotazů. Jeden další příklad:

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

Postupy: vyhledávání dat podle ID

Funkci LookupAsync lze použít k vyhledání objektů z databáze pomocí konkrétního 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");

Postupy: spuštění netypových dotazů

Při provádění dotazu pomocí netypového objektu tabulky je nutné explicitně zadat řetězec dotazu OData voláním ReadAsync, jak je uvedeno v následujícím příkladu:

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

Vrátíte se zpátky hodnoty JSON, které můžete použít jako kontejner objektů a dat. Další informace o JToken a Newtonsoft Json.NET najdete na webu JSON.NET .

Postupy: vkládání dat do back-endu mobilní aplikace

Všechny typy klientů musí obsahovat člen s názvem ID, který je ve výchozím nastavení řetězec. Toto ID je vyžadováno k provádění operací CRUD a pro offline synchronizaci. Následující kód ilustruje použití metody InsertAsync k vložení nových řádků do tabulky. Parametr obsahuje data, která mají být vložena jako objekt rozhraní .NET.

await todoTable.InsertAsync(todoItem);

Pokud během vložení není v todoItem průběhu vkládání zahrnutá jedinečná hodnota vlastního ID, vygeneruje se na serveru identifikátor GUID. Vygenerované ID můžete načíst tak, že zkontrolujete objekt po návratu volání.

Chcete-li vložit netypové údaje, můžete využít výhod Json.NET:

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

Tady je příklad použití e-mailové adresy jako jedinečného ID řetězce:

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

Práce s hodnotami ID

Mobile Apps podporuje jedinečné vlastní hodnoty řetězce pro sloupec ID tabulky. Řetězcová hodnota umožňuje aplikacím používat vlastní hodnoty, jako jsou e-mailové adresy nebo uživatelská jména pro ID. ID řetězců poskytují následující výhody:

  • ID jsou generována bez odeslání odezvy do databáze.
  • Záznamy je snazší sloučit z různých tabulek nebo databází.
  • Hodnoty ID se můžou integrovat lépe díky logice aplikace.

Pokud u vloženého záznamu není nastavená hodnota ID řetězce, back-end mobilní aplikace vygeneruje pro ID jedinečnou hodnotu. Pomocí metody GUID. NewGuid můžete vygenerovat vlastní hodnoty ID, a to buď v klientovi, nebo v back-endu.

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

Postupy: Změna dat v back-endu mobilní aplikace

Následující kód ilustruje použití metody UpdateAsync k aktualizaci existujícího záznamu se stejným ID s novými informacemi. Parametr obsahuje data, která mají být aktualizována jako objekt .NET.

await todoTable.UpdateAsync(todoItem);

Chcete-li aktualizovat netypové údaje, můžete využít výhod JSON.NET následujícím způsobem:

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

idPři provádění aktualizace je třeba zadat pole. Back-end používá id pole k identifikaci řádku, který se má aktualizovat. idPole lze získat z výsledku InsertAsync volání. ArgumentExceptionJe vyvolána, pokud se pokusíte aktualizovat položku bez zadání id hodnoty.

Postupy: odstranění dat v back-endu mobilní aplikace

Následující kód ilustruje použití metody DeleteAsync k odstranění existující instance. Instance je identifikována id polem nastaveným na todoItem .

await todoTable.DeleteAsync(todoItem);

K odstranění netypových dat můžete využít výhod Json.NET následujícím způsobem:

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

Při provádění žádosti o odstranění je nutné zadat ID. Do služby se nepředaly další vlastnosti nebo se ve službě ignorují. Výsledek DeleteAsync volání je obvykle null . ID, které se má předat, lze získat z výsledku InsertAsync volání. MobileServiceInvalidOperationExceptionVýjimka je vyvolána, pokud se pokusíte odstranit položku bez zadání id pole.

Postupy: použití optimistického řízení souběžnosti pro řešení konfliktů

Dva nebo více klientů může současně zapisovat změny stejné položky. Bez zjištění konfliktů by poslední zápis přepsal všechny předchozí aktualizace. Optimistické řízení souběžnosti předpokládá, že každá transakce se může potvrdit, a proto nepoužívá žádné uzamykání prostředků. Před potvrzením transakce ověří optimistické řízení souběžnosti, že žádná jiná transakce data nezměnila. Pokud byla data změněna, transakce potvrzení se vrátí zpět.

Mobile Apps podporuje optimistické řízení souběžnosti tím, že sleduje změny každé položky pomocí version sloupce vlastnost systému, který je definovaný pro každou tabulku v back-endu mobilní aplikace. Pokaždé, když se aktualizuje záznam, Mobile Apps nastaví version vlastnost pro tento záznam na novou hodnotu. Během každé žádosti o version aktualizaci se vlastnost záznamu zahrnutého spolu s požadavkem porovnává se stejnou vlastností záznamu na serveru. Pokud se verze předaná s požadavkem neshoduje s back-end, Klientská knihovna vyvolá MobileServicePreconditionFailedException<T> výjimku. Typ zahrnutý s výjimkou je záznam z back-endu, který obsahuje verzi daného záznamu na serverech. Aplikace pak může tyto informace použít k rozhodnutí, jestli se má znovu spustit žádost o aktualizaci se správnou version hodnotou z back-endu pro potvrzení změn.

Definujte sloupec třídy Table pro version vlastnost System, aby se povolila Optimistická souběžnost. Například:

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

Aplikace používající netypové tabulky umožňují optimistickou souběžnost nastavením Version příznaku v SystemProperties tabulce následujícím způsobem.

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

Kromě povolení optimistické souběžnosti musíte také zachytit MobileServicePreconditionFailedException<T> výjimku v kódu při volání UpdateAsync. Vyřešte konflikt tím, že použijete správný version záznam na aktualizovaný záznam a zavoláte UpdateAsync s vyřešeným záznamem. Následující kód ukazuje, jak vyřešit konflikt zápisu, jakmile byl zjištěn:

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

další informace najdete v tématu Offline Synchronizace dat v Azure Mobile Apps tématu.

postupy: vázání dat Mobile Apps k uživatelskému rozhraní Windows

v této části se dozvíte, jak zobrazit vrácené datové objekty pomocí prvků uživatelského rozhraní v aplikaci Windows. Následující příklad kódu se váže ke zdroji seznamu s dotazem na nedokončené položky. MobileServiceCollection vytvoří kolekci vazeb s podporou Mobile Apps.

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

Některé ovládací prvky ve spravovaném modulu runtime podporují rozhraní s názvem ISupportIncrementalLoading. Toto rozhraní umožňuje ovládacím prvkům požádat o další data, když se uživatel posune. k dispozici je integrovaná podpora pro toto rozhraní pro univerzální Windows aplikace přes MobileServiceIncrementalLoadingCollection, která automaticky zpracovává volání z ovládacích prvků. v aplikacích Windows použijte MobileServiceIncrementalLoadingCollection následující postup:

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

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

chcete-li použít novou kolekci v aplikacích Windows Phone 8 a Silverlight, použijte ToCollection metody rozšíření v systémech IMobileServiceTableQuery<T> a IMobileServiceTable<T> . Chcete-li načíst data, zavolejte LoadMoreItemsAsync() .

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

Použijete-li kolekci vytvořenou voláním ToCollectionAsync nebo ToCollection , získáte kolekci, která může být svázána s ovládacími prvky uživatelského rozhraní. Tato kolekce je s podporou stránkování. Vzhledem k tomu, že kolekce načítá data ze sítě, načítání se někdy nezdařilo. Chcete-li tyto chyby zpracovat, přepište OnException metodu na MobileServiceIncrementalLoadingCollection pro zpracování výjimek vyplývajících z volání LoadMoreItemsAsync .

Zvažte, jestli tabulka obsahuje mnoho polí, ale chcete v ovládacím prvku zobrazit jenom některá z nich. K výběru konkrétních sloupců, které se mají zobrazit v uživatelském rozhraní, můžete použít pokyny v předchozí části Výběr konkrétních sloupců.

Změna velikosti stránky

Azure Mobile Apps ve výchozím nastavení maximálně 50 položek na požadavek. Velikost stránkování můžete změnit zvýšením maximální velikosti stránky na klientovi i na serveru. Pokud chcete požadovanou velikost stránky zvětšit, zadejte PullOptions při použití příkazu PullAsync():

PullOptions pullOptions = new PullOptions
    {
        MaxPageSize = 100
    };

Za předpokladu, že PageSize jste v rámci serveru provedli hodnotu 100 nebo vyšší, vrátí požadavek až 100 položek.

Práce s offline tabulkami

Offline tabulky používají místní úložiště SQLite k ukládání dat pro použití v offline režimu. Všechny operace s tabulkami se provádí s místním úložištěm SQLite namísto úložiště vzdáleného serveru. Pokud chcete vytvořit offline tabulku, nejprve připravte svůj projekt:

  1. V Visual Studio > klikněte pravým tlačítkem na řešení Spravovat balíčky NuGet pro řešení... a pak vyhledejte a nainstalujte balíček NuGet Microsoft.Azure.Mobile.Client.SQLiteStore pro všechny projekty v řešení.

  2. (Volitelné) Pokud chcete Windows zařízení, nainstalujte jeden z následujících balíčků modulu runtime SQLite:

  3. (Volitelné). U Windows > zařízení klikněte na OdkazyPřidat odkaz..., rozbalte složku WindowsExtensions (Rozšíření) a > pak povolte příslušnou SQLite pro sadu Windows SDK společně se sadou Visual C++ 2013 Runtime for Windows SDK. Názvy sad SQLite SDK se mírně liší podle Windows platformy.

Před vytvořením odkazu na tabulku je nutné připravit místní úložiště:

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

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

Inicializace úložiště se obvykle provádí okamžitě po vytvoření klienta. OfflineDbPath by měl být název souboru vhodný pro použití na všech platformách, které podporujete. Pokud je cesta plně kvalifikovanou cestou (to znamená, že začíná lomítkem), použije se tato cesta. Pokud cesta není plně kvalifikovaná, soubor je umístěn v umístění specifickém pro platformu.

  • Výchozí cestou pro zařízení s iOSem a Androidem je složka Osobní soubory.
  • Pro Windows zařízení je výchozí cestou složka AppData specifická pro aplikaci.

Odkaz na tabulku lze získat pomocí GetSyncTable<> metody :

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

Pokud chcete používat offline tabulku, není nutné se ověřovat. Ověření je nutné provést pouze při komunikaci s back-endovou službou.

Synchronizace offline tabulky

Offline tabulky nejsou ve výchozím nastavení synchronizovány s back-endem. Synchronizace je rozdělená na dvě části. Změny můžete provádět odděleně od stahování nových položek. Tady je typická metoda synchronizace:

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

Pokud má první argument parametru PullAsync hodnotu null, přírůstková synchronizace se nebude používat. Každá operace synchronizace načte všechny záznamy.

Sada SDK provádí implicitní před stažením PushAsync() záznamů.

Ke zpracování konfliktů dochází u PullAsync() metody . Konflikty můžete řešit stejným způsobem jako online tabulky. Konflikt se vyprodukuje PullAsync() , když se volá místo během vkládání, aktualizace nebo odstraňování. Pokud dojde k více konfliktům, zabalí se do jedné výjimky MobileServicePushFailedException. Jednotlivá selhání zvládáte samostatně.

Práce s vlastním rozhraním API

Vlastní rozhraní API umožňuje definovat vlastní koncové body, které zpřístupňuje funkce serveru, které se nemapují na operaci vložení, aktualizace, odstranění nebo čtení. Pomocí vlastního rozhraní API můžete mít větší kontrolu nad zasíláním zpráv, včetně čtení a nastavení hlaviček zpráv HTTP a definování jiného formátu těla zprávy než JSON.

Vlastní rozhraní API můžete volat voláním jedné z metod InvokeApiAsync na klientovi. Například následující řádek kódu odešle požadavek POST do rozhraní completeAll API na back-endu:

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

Tento formulář je volání metody typu a vyžaduje, aby byl definován návratový typ MarkAllResult . Podporují se typové i netypové metody.

Metoda InvokeApiAsync() předá /api/k rozhraní API, které chcete volat, pokud rozhraní API nezačne na /. Například:

  • InvokeApiAsync("completeAll",...) volá /api/completeAll na back-endu.
  • InvokeApiAsync("/.auth/me",...) zavolá /.auth/me na back-endu.

InvokeApiAsync můžete použít k volání libovolného rozhraní WebAPI, včetně rozhraní WebAPI, které nejsou definované pomocí Azure Mobile Apps. Když použijete Metodu InvokeApiAsync(), budou spolu s požadavkem odeslány příslušné hlavičky, včetně hlaviček ověřování.

Ověřování uživatelů

Mobile Apps podporuje ověřování a ověřování uživatelů aplikací pomocí různých externích zprostředkovatelů identity: Facebook, Google, účet Microsoft, Twitter a Azure Active Directory. Můžete nastavit oprávnění k tabulkám a omezit tak přístup pro konkrétní operace jenom na ověřené uživatele. Identitu ověřených uživatelů můžete použít také k implementaci autorizačních pravidel ve skriptech serveru. Další informace najdete v kurzu Přidání ověřování do aplikace.

Podporují se dva toky ověřování: tok spravovaný klientem a tok spravovaný serverem . Tok spravovaný serverem poskytuje nejjednodušší prostředí ověřování, protože spoléhá na webové ověřovací rozhraní poskytovatele. Tok spravovaný klientem umožňuje hlubší integraci s funkcemi specifickými pro zařízení, protože závisí na zprostředkovatelích specifických sdk pro zařízení.

Poznámka

V produkčních aplikacích doporučujeme použít tok spravovaný klientem.

Pokud chcete nastavit ověřování, musíte svou aplikaci zaregistrovat u jednoho nebo více zprostředkovatelů identity. Zprostředkovatel identity vygeneruje ID klienta a tajný kód klienta pro vaši aplikaci. Tyto hodnoty se pak nastaví v back-endu, aby Azure App Service ověřování/autorizaci. Další informace najdete v podrobných pokynech v kurzu Přidání ověřování do aplikace.

V této části jsou uvedená následující témata:

Ověřování spravované klientem

Vaše aplikace může nezávisle kontaktovat zprostředkovatele identity a pak poskytnout vrácený token během přihlášení pomocí back-endu. Tento klientský tok umožňuje poskytovat uživatelům jednotné přihlašování nebo načítat další uživatelská data od zprostředkovatele identity. Ověřování toku klienta se upřednostní před použitím toku serveru, protože sada SDK zprostředkovatele identity poskytuje více nativního uživatelského rozhraní a umožňuje další přizpůsobení.

Příklady jsou k dispozici pro následující vzory ověřování toku klienta:

Ověřování uživatelů pomocí Active Directory Authentication Library

Pomocí rozhraní Active Directory Authentication Library (ADAL) můžete zahájit ověřování uživatelů z klienta pomocí Azure Active Directory ověřování.

  1. Nakonfigurujte back-end mobilní aplikace AAD přihlášení podle kurzu Konfigurace konfigurace App Service pro přihlášení ke službě Active Directory. Nezapomeňte dokončit volitelný krok registrace nativní klientské aplikace.

  2. V Visual Studio nebo Xamarin Studio otevřete projekt a přidejte odkaz na Microsoft.IdentityModel.Clients.ActiveDirectory NuGet balíček. Při hledání zahrnte předběžné verze.

  3. Přidejte do aplikace následující kód podle platformy, kterou používáte. V každém z nich proveďte následující nahrazení:

    • Nahraďte INSERT-AUTHORITY-HERE názvem tenanta, ve kterém jste svou aplikaci zř vyhradí. Formát by měl být https://login.microsoftonline.com/contoso.onmicrosoft.com. Tuto hodnotu můžete zkopírovat z karty Doména ve vašem Azure Active Directory v Azure Portal.

    • Nahraďte INSERT-RESOURCE-ID-HERE ID klienta back-endu mobilní aplikace. ID klienta můžete získat na kartě Upřesnit v části Azure Active Directory Nastavení na portálu.

    • Nahraďte INSERT-CLIENT-ID-HERE ID klienta, které jste zkopíroval z nativní klientské aplikace.

    • Nahraďte INSERT-REDIRECT-URI-HERE koncovým bodem webu /.auth/login/done pomocí schématu HTTPS. Tato hodnota by měla být podobná hodnotě https://contoso.azurewebsites.net/.auth/login/done.

      Kód potřebný pro každou platformu je následující:

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

Jeden Sign-On používající token z Facebooku nebo Google

Můžete použít tok klienta, jak je znázorněno v tomto fragmentu pro Facebook nebo 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();
    }
}

Ověřování spravované serverem

Po zaregistrování poskytovatele identity volejte metodu LoginAsync na [MobileServiceClient] s hodnotou MobileServiceAuthenticationProvider vašeho poskytovatele. Následující kód například inicializuje přihlášení k serveru pomocí služby 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();
    }
}

Pokud používáte jiného poskytovatele identity než Facebook, změňte hodnotu MobileServiceAuthenticationProvider na hodnotu pro vašeho poskytovatele.

v toku serveru Azure App Service spravuje tok ověřování OAuth zobrazením přihlašovací stránky vybraného zprostředkovatele. jakmile se zprostředkovatel identity vrátí, Azure App Service vygeneruje ověřovací token App Service. Metoda LoginAsync vrací hodnotu MobileServiceUser, která poskytuje ID uživatele ověřeného uživatele i MobileServiceAuthenticationTokenjako webový token JSON (Jwt). Tento token se může uložit do mezipaměti a znovu požívat do vypršení platnosti. další informace najdete v tématu Ukládání do mezipaměti ověřovacího tokenu.

Při použití Xamarin (Android nebo iOS) se používá webověřovatel Xamarin. Essentials. Do LoginAsync metody musíte předat výchozí kontext (Android) nebo UIViewController (iOS). Kromě toho je nutné zpracovat návrat z webové ověřovací služby. V Androidu se tato akce zpracovává v rámci MainActivity.cs :

public override void OnResume()
{
    base.OnResume();
    Xamarin.Essentials.Platform.OnResume();
}

V systému iOS se zpracovává v AppDelegate. cs:

public override bool OpenUrl(UIApplication app, NSUrl url, NSDictionary options)
{
    if (client.ResumeWithURL(app, url, options))
        return true;
    return base.OpenUrl(app, url, options);
}

Ukládání do mezipaměti ověřovací token

V některých případech se volání metody Login může vyhnout po prvním úspěšném ověření uložením ověřovacího tokenu od poskytovatele. aplikace Microsoft Store a UWP můžou používat PasswordVault k ukládání aktuálního ověřovacího tokenu do mezipaměti po úspěšném přihlášení, a to následujícím způsobem:

await client.LoginAsync(MobileServiceAuthenticationProvider.Facebook);

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

Hodnota ID uživatele je uložená jako uživatelské jméno přihlašovacích údajů a token je uložený jako heslo. Při dalších spuštěních se můžete podívat na přihlašovací údaje PasswordVault pro ukládání do mezipaměti. Následující příklad používá při jejich nalezení přihlašovací údaje uložené v mezipaměti a v opačném případě se pokusí znovu ověřit pomocí back-endu:

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

Když odhlásíte uživatele, musíte taky odebrat uložené přihlašovací údaje následujícím způsobem:

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

Aplikace Xamarin používají rozhraní API Xamarin. auth k bezpečnému ukládání přihlašovacích údajů do objektu účtu . Příklad použití těchto rozhraní API naleznete v souboru kódu AuthStore. cs v ukázce sdílení fotek ContosoMoments.

Když použijete ověřování spravované klientem, můžete také ukládat do mezipaměti přístupový token získaný od poskytovatele, jako je Facebook nebo Twitter. Tento token lze zadat pro vyžádání nového ověřovacího tokenu z back-endu následujícím způsobem:

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

Nabízená oznámení

Nabízená oznámení jsou pokrytá v následujících tématech:

Postupy: registrace nabízených oznámení

Klient Mobile Apps umožňuje registrovat nabízená oznámení pomocí Azure Notification Hubs. Při registraci získáte popisovač, který získáte ze služby nabízených oznámení specifických pro konkrétní platformu (PNS). Po vytvoření registrace pak tuto hodnotu zadejte spolu s jakýmikoli značkami. následující kód zaregistruje vaši aplikaci Windows pro nabízená oznámení se službou 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);
}

pokud předáváte do WNS, musíte získat Microsoft Store SID balíčku. další informace o aplikacích Windows, včetně toho, jak se zaregistrovat k registraci šablon, najdete v tématu přidání nabízených oznámení do vaší aplikace.

Vyžadování značek od klienta není podporováno. Požadavky na značky se tiše odcházejí z registrace. Pokud chcete zařízení zaregistrovat pomocí značek, vytvořte vlastní rozhraní API, které používá rozhraní Notification Hubs API k provedení registrace vaším jménem. Místo RegisterNativeAsync() metody zavolejte vlastní rozhraní API.

postupy: získání identifikátoru SID balíčku Microsoft Store

k povolení nabízených oznámení v aplikacích Microsoft Store se vyžaduje SID balíčku. Pokud chcete získat identifikátor SID balíčku, Zaregistrujte svoji aplikaci pomocí Microsoft Store.

Tuto hodnotu můžete získat takto:

  1. v Visual Studio Průzkumník řešení klikněte pravým tlačítkem na projekt Microsoft Store aplikace a klikněte na store>přidružit aplikaci k obchodu....
  2. V průvodci klikněte na Další, přihlaste se pomocí svého účet Microsoft, zadejte název vaší aplikace do pole rezervovat nový název aplikacea pak klikněte na rezervovat.
  3. Po úspěšném vytvoření registrace aplikace vyberte název aplikace, klikněte na Dalšía pak klikněte na přidružit.
  4. přihlaste se k Windows Dev Center pomocí svého účtu Microsoft. V části Moje aplikaceklikněte na registraci aplikace, kterou jste vytvořili.
  5. Klikněte na možnostIdentita aplikacesprávy> aplikací a potom přejděte dolů k vyhledání identifikátoru SID balíčku.

Mnohé použití identifikátoru SID balíčku považuje za identifikátor URI. v takovém případě je třeba použít aplikaci MS-App:// jako schéma. Poznamenejte si verzi vašeho balíčku SID vytvořenou zřetězením této hodnoty jako předpony.

Aplikace Xamarin vyžadují nějaký další kód, který by mohl Registrovat aplikaci běžící na platformách iOS nebo Android. Další informace najdete v tématu věnovaném vaší platformě:

Postupy: Registrace šablon nabízených oznámení pro odesílání oznámení pro různé platformy

Chcete-li registrovat šablony, použijte RegisterAsync() metodu se šablonami následujícím způsobem:

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

Vaše šablony by měly být JObject typy a mohou obsahovat více šablon v následujícím formátu JSON:

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

Metoda RegisterAsync () také přijímá sekundární dlaždice:

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

Všechny značky jsou během registrace odstraněny pro zabezpečení. Chcete-li přidat značky do instalací nebo šablon v rámci instalací, přečtěte si téma [práce s back-end serverem .NET SDK pro Azure Mobile Apps].

Pokud chcete odesílat oznámení s těmito registrovanými šablonami, přečtěte si téma rozhraní API pro Notification Hubs.

Různá témata

Postupy: zpracování chyb

Pokud dojde k chybě v back-endu, klientská sada SDK vyvolá MobileServiceInvalidOperationException . Následující příklad ukazuje, jak zpracovat výjimku vrácenou back-end:

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

Další příklad práce s chybovými stavy najdete v ukázce Mobile Apps Files. Příklad LoggingHandler poskytuje obslužnou rutinu delegáta protokolování pro protokolování požadavků do back-endu.

Postupy: přizpůsobení hlaviček požadavku

Aby bylo možné podporovat konkrétní scénář aplikace, může být nutné přizpůsobit komunikaci s back-endu mobilní aplikace. Například můžete chtít přidat vlastní hlavičku do každého odchozího požadavku nebo dokonce změnit stavové kódy odpovědí. Můžete použít vlastní DelegatingHandler, jak je znázorněno v následujícím příkladu:

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