Så här använder du den hanterade klienten för Azure Mobile Apps
Översikt
Den här guiden visar hur du utför vanliga scenarier med hjälp av det hanterade klient biblioteket för Azure App Service Mobile Apps för Windows-och Xamarin-appar. Om du är nybörjare på Mobile Apps bör du först följa självstudien för Azure Mobile Apps snabb start . I den här hand boken fokuserar vi på klient sidans hanterade SDK. Mer information om SDK: er för Server sidan för Mobile Apps finns i dokumentationen för .NET Server SDK eller Node.js Server SDK.
Referens dokumentation
Referens dokumentationen för klient-SDK: n finns här: Azure Mobile Apps .net-klient referens. Du kan också hitta flera klient exempel i Azure-samples GitHub-lagringsplatsen.
Plattformar som stöds
.NET-plattformen stöder följande plattformar:
- Xamarin Android-versioner för API 19 – 24 (KitKat via nougat)
- Xamarin iOS-versioner för iOS version 8,0 och senare
- Universell Windows-plattform
- Windows Phone 8.1
- Windows Phone 8,0 utom Silverlight-program
Autentiseringen "Server-Flow" använder en webbvy för det visade användar gränssnittet. Om enheten inte kan visa användar gränssnittet för WebView krävs andra metoder för autentisering. Detta SDK är därför inte lämpligt för bevakade eller liknande enheter.
Konfiguration och krav
Vi förutsätter att du redan har skapat och publicerat ditt mobil programs Server dels projekt, som innehåller minst en tabell. I den kod som används i det här avsnittet får tabellen namnet TodoItem och innehåller följande kolumner: Id , Text och Complete . Den här tabellen är samma tabell som skapas när du slutför snabb starten för Azure Mobile Apps.
Motsvarande typ av klient sidan i C# är följande klass:
public class TodoItem
{
public string Id { get; set; }
[JsonProperty(PropertyName = "text")]
public string Text { get; set; }
[JsonProperty(PropertyName = "complete")]
public bool Complete { get; set; }
}
JsonPropertyAttribute används för att definiera PropertyName -mappning mellan fältet klient och fältet tabell.
Information om hur du skapar tabeller i din Mobile Apps Server del finns i avsnittet .NET Server SDK eller avsnittetNode.js Server SDK. Om du har skapat en server del för mobilappen i Azure Portal med snabb starten kan du också använda inställningen enkla tabeller i [Azure Portal].
Gör så här: installera det hanterade klient-SDK-paketet
Använd någon av följande metoder för att installera SDK-paketet för den hanterade klienten för Mobile Apps från NuGet:
- Visual Studio Högerklicka på projektet, klicka på Hantera NuGet-paket , Sök efter
Microsoft.Azure.Mobile.Clientpaketet och klicka sedan på Installera. - Xamarin Studio Högerklicka på projektet, klicka på Lägg till > Lägg till NuGet-paket , Sök efter
Microsoft.Azure.Mobile.Clientpaketet och klicka sedan på Lägg till paket.
Kom ihåg att lägga till följande using -instruktion i huvud aktivitets filen:
using Microsoft.WindowsAzure.MobileServices;
Anteckning
Observera att alla supportpaket som det refereras till i ditt Android-projekt måste ha samma version. SDK är Xamarin.Android.Support.CustomTabs beroende av Android-plattform, så om ditt projekt använder nyare support paket måste du installera det här paketet med den version som krävs direkt för att undvika konflikter.
Gör så här: arbeta med fel söknings symboler i Visual Studio
Symbolerna för namn området Microsoft. Azure. Mobile finns på SymbolSource. Se SymbolSource- instruktionerna för att integrera SymbolSource med Visual Studio.
Skapa Mobile Apps-klienten
Följande kod skapar MobileServiceClient -objektet som används för att komma åt Server delen för mobilappar.
var client = new MobileServiceClient("MOBILE_APP_URL");
I föregående kod ersätter du MOBILE_APP_URL med URL: en för Server delen för mobilappar, som finns på bladet för Server delen för mobilappar i [Azure Portal]. MobileServiceClient-objektet ska vara en singleton.
Arbeta med tabeller
I följande avsnitt beskrivs hur du söker efter och hämtar poster och ändrar data i tabellen. Följande avsnitt beskrivs:
- Skapa en tabell referens
- Söka i data
- Filtrera returnerade data
- Sortera returnerade data
- Returnera data på sidor
- Välj vissa kolumner
- Leta upp en post efter ID
- Hantera frågor utan typ
- Infoga data
- Uppdaterar data
- Ta bort data
- Konflikt lösning och optimistisk samtidighet
- Bindning till ett Windows-användargränssnitt
- Ändra sid storlek
Gör så här: skapa en tabell referens
All kod som används för att komma åt eller ändra data i en server del tabell anropar funktioner på MobileServiceTable objektet. Hämta en referens till tabellen genom att anropa metoden GetTable enligt följande:
IMobileServiceTable<TodoItem> todoTable = client.GetTable<TodoItem>();
Det returnerade objektet använder den skrivna serialiserade modellen. En modell med en typ som inte är typ stöds också. I följande exempel [skapas en referens till en tabell som inte är av typen]:
// Get an untyped table reference
IMobileServiceTable untypedTodoTable = client.GetTable("TodoItem");
I frågor som inte har angets måste du ange den underliggande OData-frågesträngen.
Så här gör du: fråga efter data från mobilappen
I det här avsnittet beskrivs hur du skickar frågor till Server delen för mobilappar, som innehåller följande funktioner:
- Filtrera returnerade data
- Sortera returnerade data
- Returnera data på sidor
- Välj vissa kolumner
- Leta upp data efter ID
Anteckning
En server driven sid storlek tillämpas för att förhindra att alla rader returneras. Sid indelning behåller standard begär Anden för stora data mängder från att påverka tjänsten negativt. Om du vill returnera fler än 50 rader använder du Skip och Take -metoden enligt beskrivningen i returnera data på sidor.
Gör så här: filtrera returnerade data
Följande kod visar hur du filtrerar data genom att inkludera en Where sats i en fråga. Den returnerar alla objekt från todoTable vars Complete egenskap är lika med false . Funktionen [WHERE] använder ett rad filtrerings-predikat för frågan mot tabellen.
// This query filters out completed TodoItems and items without a timestamp.
List<TodoItem> items = await todoTable
.Where(todoItem => todoItem.Complete == false)
.ToListAsync();
Du kan visa URI: n för begäran som skickats till Server delen med hjälp av meddelande gransknings program vara, t. ex. webbläsarbaserade utvecklingsverktyg eller Fiddler. Lägg märke till att frågesträngen ändras om du tittar på URI: n för begäran:
GET /tables/todoitem?$filter=(complete+eq+false) HTTP/1.1
Denna OData-begäran översätts till en SQL-fråga av Server-SDK: n:
SELECT *
FROM TodoItem
WHERE ISNULL(complete, 0) = 0
Funktionen som skickas till Where metoden kan ha ett godtyckligt antal villkor.
// 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();
Det här exemplet skulle översättas till en SQL-fråga av Server-SDK: n:
SELECT *
FROM TodoItem
WHERE ISNULL(complete, 0) = 0
AND ISNULL(text, 0) = 0
Den här frågan kan också delas upp i flera satser:
List<TodoItem> items = await todoTable
.Where(todoItem => todoItem.Complete == false)
.Where(todoItem => todoItem.Text != null)
.ToListAsync();
De två metoderna är likvärdiga och kan användas utbytbart. Det tidigare alternativet — att sammanfoga flera predikat i en fråga — är mer kompakt och rekommenderat.
WhereSatsen stöder åtgärder som översätts till OData-delmängden. Åtgärderna omfattar:
- Relations operatorer (= =,! =, <, <=, >, >=),
- Aritmetiska operatorer (+,-,/, *,%),
- Tal precision (matematik. golv, matematik. tak)
- Sträng funktioner (längd, del sträng, ersätta, IndexOf, StartsWith, EndsWith),
- Datum egenskaper (år, månad, dag, timme, minut, sekund),
- Åtkomst egenskaper för ett objekt och
- Uttryck som kombinerar någon av dessa åtgärder.
När du överväger att Server-SDK: n stöder kan du överväga [OData v3-dokumentationen].
Så här: sortera returnerade data
Följande kod visar hur du sorterar data genom att inkludera en OrderBy -eller OrderByDescending -funktion i frågan. Den returnerar objekt från todoTable sorterad stigande efter Text fältet.
// 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();
Så här gör du: returnera data på sidor
Server delen returnerar som standard bara de första 50 raderna. Du kan öka antalet returnerade rader genom att anropa metoden [Take] . Använd Take tillsammans med [Skip] -metoden för att begära en speciell "sida" av den totala data mängden som returneras av frågan. Följande fråga, när den körs, returnerar de tre översta objekten i tabellen.
// Define a filtered query that returns the top 3 items.
MobileServiceTableQuery<TodoItem> query = todoTable.Take(3);
List<TodoItem> items = await query.ToListAsync();
Följande ändrade fråga hoppar över de första tre resultaten och returnerar följande tre resultat. Den här frågan genererar den andra "sidan" av data där sid storleken är tre objekt.
// 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();
Metoden IncludeTotalCount begär det totala antalet för alla poster som skulle ha returnerats, vilket ignorerar växling/gräns-satsen som har angetts:
query = query.IncludeTotalCount();
I en verklig världs-app kan du använda frågor som liknar föregående exempel med en pager-kontroll eller ett jämförbart gränssnitt för att navigera mellan sidor.
Anteckning
Om du vill åsidosätta gränsen på 50-rader i en server del för mobilappar, måste du även använda EnableQueryAttribute till den offentliga Get-metoden och ange växlings beteendet. När det tillämpas på-metoden ställer följande in maximalt antal returnerade rader till 1000:
[EnableQuery(MaxTop=1000)]
Gör så här: Välj vissa kolumner
Du kan ange vilken uppsättning egenskaper som ska ingå i resultatet genom att lägga till en [Select] -sats i frågan. Följande kod visar till exempel hur du väljer bara ett fält och hur du väljer och formaterar flera fält:
// 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();
Alla funktioner som beskrivs hittills är additiva så att vi kan fortsätta att länka dem. Varje länkat anrop påverkar mer av frågan. Ett annat exempel:
MobileServiceTableQuery<TodoItem> query = todoTable
.Where(todoItem => todoItem.Complete == false)
.Select(todoItem => todoItem.Text)
.Skip(3).
.Take(3);
List<string> items = await query.ToListAsync();
Gör så här: Leta upp data efter ID
Funktionen LookupAsync kan användas för att söka efter objekt från databasen med ett visst 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");
Gör så här: köra frågor som inte har påskrivits
När du kör en fråga med ett objekt som inte är av typen% måste du uttryckligen ange OData-frågesträngen genom att anropa ReadAsync, som i följande exempel:
// Lookup untyped data using OData
JToken untypedItems = await untypedTodoTable.ReadAsync("$filter=complete eq 0&$orderby=text");
Du får tillbaka JSON-värden som du kan använda som egenskaps uppsättning. Mer information om JToken och Newtonsoft Json.NET finns på JSON.net -webbplatsen.
Så här: infoga data i en server del för mobila appar
Alla klient typer måste innehålla en medlem med namnet ID , som är som standard en sträng. Detta ID krävs för att utföra CRUD-åtgärder och för synkronisering offline. Följande kod visar hur du använder InsertAsync -metoden för att infoga nya rader i en tabell. Parametern innehåller de data som ska infogas som ett .NET-objekt.
await todoTable.InsertAsync(todoItem);
Om ett unikt anpassat ID-värde inte ingår i todoItem under en infogning genereras ett GUID av servern.
Du kan hämta det genererade ID: t genom att inspektera objektet när anropet har returnerats.
För att infoga data som inte har matats in kan du dra nytta av Json.NET:
JObject jo = new JObject();
jo.Add("Text", "Hello World");
jo.Add("Complete", false);
var inserted = await table.InsertAsync(jo);
Här är ett exempel som använder en e-postadress som ett unikt sträng-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);
Arbeta med ID-värden
Mobile Apps stöder unika anpassade sträng värden för tabellens ID- kolumn. Med ett sträng värde kan program använda anpassade värden, till exempel e-postadresser eller användar namn för ID: t. Sträng-ID: n ger dig följande fördelar:
- ID: n genereras utan att göra en tur och retur i databasen.
- Poster är enklare att sammanfoga från olika tabeller och databaser.
- ID-värden kan integreras bättre med ett programs logik.
När ett sträng-ID-värde inte är inställt på en infogad post genererar mobilappen för mobilappen ett unikt värde för ID: t. Du kan använda metoden GUID. NewGuid för att generera egna ID-värden, antingen på klienten eller i Server delen.
JObject jo = new JObject();
jo.Add("id", Guid.NewGuid().ToString("N"));
Gör så här: ändra data i en server del för mobila appar
Följande kod visar hur du använder UpdateAsync -metoden för att uppdatera en befintlig post med samma ID med ny information. Parametern innehåller de data som ska uppdateras som ett .NET-objekt.
await todoTable.UpdateAsync(todoItem);
Om du vill uppdatera data som inte har skrivits kan du dra nytta av JSON.net på följande sätt:
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);
Ett id fält måste anges när en uppdatering görs. Server delen använder id fältet för att identifiera vilken rad som ska uppdateras. idFältet kan hämtas från resultatet av InsertAsync anropet. En ArgumentException aktive ras om du försöker uppdatera ett objekt utan att ange id värdet.
Så här gör du: ta bort data i en server del för mobila appar
Följande kod visar hur du använder DeleteAsync -metoden för att ta bort en befintlig instans. Instansen identifieras av id fältet som anges i todoItem .
await todoTable.DeleteAsync(todoItem);
För att ta bort data som inte har påskrivits kan du dra nytta av Json.NET på följande sätt:
JObject jo = new JObject();
jo.Add("id", "37BBF396-11F0-4B39-85C8-B319C729AF6D");
await table.DeleteAsync(jo);
När du gör en borttagnings förfrågan måste du ange ett ID. Andra egenskaper skickas inte till tjänsten eller ignoreras vid tjänsten. Resultatet av ett DeleteAsync anrop är vanligt vis null . Det ID som ska skickas kan hämtas från resultatet av InsertAsync anropet. En MobileServiceInvalidOperationException genereras när du försöker ta bort ett objekt utan att ange id fältet.
Gör så här: Använd optimistisk samtidighet för konflikt lösning
Två eller flera klienter kan skriva ändringar till samma objekt på samma tidpunkt. Utan konflikt identifiering skulle den senaste skrivningen skriva över alla tidigare uppdateringar. Optimistisk concurrency-kontroll förutsätter att varje transaktion kan genomföra och därför inte använder någon resurs låsning. Innan du genomför en transaktion verifierar optimistisk concurrency-kontrollen att ingen annan transaktion har ändrat data. Om data har ändrats återställs commit-transaktionen.
Mobile Apps stöder optimistisk concurrency-kontroll genom att spåra ändringar av varje objekt med hjälp av version kolumnen system egenskap som definieras för varje tabell i din server del för mobila appar. Varje gång en post uppdateras anger Mobile Apps version egenskapen för posten till ett nytt värde. Under varje uppdaterings förfrågan version jämförs egenskapen för posten som ingår i begäran med samma egenskap för posten på servern. Om versionen som skickades med begäran inte matchar Server delen genererar klient biblioteket ett MobileServicePreconditionFailedException<T> undantag. Den typ som ingår i undantaget är posten från Server delen som innehåller servrarnas version av posten. Programmet kan sedan använda den här informationen för att avgöra om du vill köra uppdateringsbegäran igen med rätt version värde från Server delen för att genomföra ändringar.
Definiera en kolumn i tabell klassen för version system egenskapen för att aktivera optimistisk samtidighet. Exempel:
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; }
}
Program som använder tabeller utan typ möjliggör optimistisk samtidighet genom att ställa in Version flaggan i SystemProperties tabellen enligt följande.
//Enable optimistic concurrency by retrieving version
todoTable.SystemProperties |= MobileServiceSystemProperties.Version;
Förutom att aktivera optimistisk samtidighet måste du också fånga MobileServicePreconditionFailedException<T> undantag i koden när du anropar UpdateAsync. Lös konflikten genom att använda rätt version till den uppdaterade posten och anropa UpdateAsync med den lösta posten. Följande kod visar hur du löser en Skriv konflikt när den har identifierats:
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();
}
Mer information finns i avsnittet [data synkronisering offline i Azure Mobile Apps] .
Gör så här: bind Mobile Apps data till ett Windows-användargränssnitt
I det här avsnittet visas hur du visar returnerade data objekt med hjälp av GRÄNSSNITTs element i en Windows-app. Följande exempel kod binder till källan för listan med en fråga för oavslutade objekt. MobileServiceCollection skapar en Mobile Apps medveten bindnings samling.
// 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;
Vissa kontroller i den hanterade körnings miljön stöder ett gränssnitt som kallas ISupportIncrementalLoading. Det här gränssnittet gör det möjligt för kontroller att begära extra data när användaren rullar. Det finns inbyggt stöd för det här gränssnittet för universella Windows-appar via MobileServiceIncrementalLoadingCollection, som automatiskt hanterar anropen från kontrollerna. Använd MobileServiceIncrementalLoadingCollection i Windows-appar på följande sätt:
MobileServiceIncrementalLoadingCollection<TodoItem,TodoItem> items;
items = todoTable.Where(todoItem => todoItem.Complete == false).ToIncrementalLoadingCollection();
ListBox lb = new ListBox();
lb.ItemsSource = items;
Om du vill använda den nya samlingen på Windows Phone 8-och "Silverlight"-appar använder du ToCollection tilläggs metoderna på IMobileServiceTableQuery<T> och IMobileServiceTable<T> . Om du vill läsa in data anropar du LoadMoreItemsAsync() .
MobileServiceCollection<TodoItem, TodoItem> items = todoTable.Where(todoItem => todoItem.Complete==false).ToCollection();
await items.LoadMoreItemsAsync();
När du använder samlingen som skapats genom att anropa ToCollectionAsync eller ToCollection , får du en samling som kan bindas till UI-kontroller. Den här samlingen är växlings medveten. Eftersom samlingen läser in data från nätverket går det ibland inte att läsa in. Om du vill hantera sådana fel kan du åsidosätta OnException metoden för MobileServiceIncrementalLoadingCollection att hantera undantag som orsakas av anrop till LoadMoreItemsAsync .
Överväg om din tabell har många fält men du bara vill visa några av dem i kontrollen. Du kan använda vägledningen i föregående avsnitt "Välj vissa kolumner" om du vill välja vissa kolumner som ska visas i användar gränssnittet.
Ändra sid storlek
Azure Mobile Apps returnerar högst 50 objekt per begäran som standard. Du kan ändra växlings storleken genom att öka den maximala sid storleken på både klienten och servern. Om du vill öka den begärda sid storleken anger du PullOptions när du använder PullAsync() :
PullOptions pullOptions = new PullOptions
{
MaxPageSize = 100
};
Förutsatt att du har gjort PageSize lika med eller större än 100 på servern returnerar en begäran upp till 100 objekt.
Arbeta med offline-tabeller
Offline-tabeller använder en lokal SQLite-lagring för att lagra data som ska användas när de är offline. Alla tabell åtgärder görs mot den lokala SQLite-butiken i stället för fjärrserverns lagrings plats. Om du vill skapa en offline-tabell förbereder du först ditt projekt:
I Visual Studio högerklickar du på lösningen > _ * hantera NuGet-paket för lösningen... * *. Sök sedan efter och installera Microsoft. Azure. Mobile. client. SQLiteStore NuGet-paketet för alla projekt i lösningen.
Valfritt Om du vill ha stöd för Windows-enheter installerar du ett av följande SQLite runtime-paket:
- Windows 8,1-körning: Installera sqlite för Windows 8,1.
- Windows Phone 8,1: Installera sqlite för Windows Phone 8,1.
- Universell Windows-plattform Installera sqlite för universella Windows.
(Valfritt). För Windows-enheter klickar du på referenser > Lägg till referens... , expandera Windows -mappen > tillägg och aktivera lämplig sqlite för Windows SDK tillsammans med Visual C++ 2013 runtime för Windows SDK. SQLite SDK-namnen skiljer sig något med varje Windows-plattform.
Innan en tabell referens kan skapas måste det lokala lagret förberedas:
var store = new MobileServiceSQLiteStore(Constants.OfflineDbPath);
store.DefineTable<TodoItem>();
//Initializes the SyncContext using the default IMobileServiceSyncHandler.
await this.client.SyncContext.InitializeAsync(store);
Lagrings initiering görs normalt omedelbart efter att klienten har skapats. OfflineDbPath bör vara ett fil namn som lämpar sig för användning på alla plattformar som du stöder. Om sökvägen är en fullständigt kvalificerad sökväg (dvs. den börjar med ett snedstreck) används den sökvägen. Om sökvägen inte är fullständigt kvalificerad placeras filen på en plattformsspecifik plats.
- För iOS-och Android-enheter är standard Sök vägen mappen "personliga filer".
- För Windows-enheter är standard Sök vägen den programspecifika "AppData"-mappen.
En tabell referens kan hämtas med hjälp av GetSyncTable<> metoden:
var table = client.GetSyncTable<TodoItem>();
Du behöver inte autentisera för att använda en offline-tabell. Du behöver bara autentisera när du kommunicerar med backend-tjänsten.
Synkronisera en offline-tabell
Offline-tabeller synkroniseras inte med Server delen som standard. Synkroniseringen delas upp i två delar. Du kan skicka ändringar separat från att hämta nya objekt. Här är en typisk synkroniseringsmetod:
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"]);
}
}
}
Om det första argumentet till PullAsync är null används inte stegvis synkronisering. Varje Sync-åtgärd hämtar alla poster.
SDK utför en implicit PushAsync() hämtning innan du hämtar poster.
Konflikt hantering sker i en PullAsync() metod. Du kan hantera konflikter på samma sätt som online-tabeller. Konflikten skapas när PullAsync() anropas i stället för under INSERT, Update eller Delete. Om flera konflikter sker paketeras de i en enda MobileServicePushFailedException. Hantera varje enskilt haveri separat.
Arbeta med ett anpassat API
Med ett anpassat API kan du definiera anpassade slut punkter som visar Server funktioner som inte mappas till en INSERT-, Update-, DELETE-eller Read-åtgärd. Genom att använda ett anpassat API kan du ha mer kontroll över meddelanden, inklusive läsa och ställa in HTTP-meddelandehuvuden och definiera ett annat text format än JSON.
Du anropar ett anpassat API genom att anropa en av InvokeApiAsync -metoderna på klienten. Följande kodrad skickar till exempel en POST-begäran till completeAll -API: et på Server delen:
var result = await client.InvokeApiAsync<MarkAllResult>("completeAll", System.Net.Http.HttpMethod.Post, null);
Det här formuläret är ett inskrivet metod anrop och kräver att RETUR typen MarkAllResult har definierats. Både skrivna och avskrivna metoder stöds.
Metoden InvokeApiAsync () prepends "/API/" till det API som du vill anropa om inte API: et börjar med "/". Exempel:
InvokeApiAsync("completeAll",...)anropar/api/completeAll på Server delenInvokeApiAsync("/.auth/me",...)anropar/.auth/me på Server delen
Du kan använda InvokeApiAsync för att anropa eventuella WebAPI, inklusive de WebAPI: er som inte har definierats med Azure Mobile Apps. När du använder InvokeApiAsync () skickas lämpliga huvuden, inklusive autentiseringsscheman, med begäran.
Autentisera användare
Mobile Apps stöder autentisering och auktorisering av App-användare med olika externa identitets leverantörer: Facebook, Google, Microsoft-konto, Twitter och Azure Active Directory. Du kan ange behörigheter för tabeller för att begränsa åtkomsten för vissa åtgärder till endast autentiserade användare. Du kan också använda identiteten för autentiserade användare för att implementera auktoriseringsregler i Server skript. Mer information finns i självstudierna [Lägg till autentisering till din app].
Två autentiserings flöden stöds: klient-hanterat och Server-hanterat flöde. Det Server-hanterade flödet ger den enklaste autentiseringen, eftersom det förlitar sig på providerns webbautentiserings-gränssnitt. Det klient-hanterade flödet möjliggör djupare integrering med enhetsspecifika funktioner eftersom det förlitar sig på providerspecifika, enhetsspecifika SDK: er.
Anteckning
Vi rekommenderar att du använder ett klient hanterat flöde i dina produktions program.
Om du vill konfigurera autentisering måste du registrera din app med en eller flera identitets leverantörer. Identitets leverantören genererar ett klient-ID och en klient hemlighet för din app. Dessa värden ställs sedan in i Server delen för att aktivera Azure App Service autentisering/auktorisering. Mer information finns i de detaljerade anvisningarna i självstudien [Lägg till autentisering i din app].
Följande avsnitt beskrivs i det här avsnittet:
Klient-hanterad autentisering
Din app kan kontakta identitets leverantören oberoende och sedan ange den returnerade token under inloggningen med din server del. Med det här klient flödet kan du tillhandahålla enkel inloggning för användare eller hämta ytterligare användar data från identitets leverantören. Autentisering med klient flöde föredras för att använda ett Server flöde eftersom Identity Provider SDK ger en mer enhetlig känsla och möjliggör ytterligare anpassning.
Exempel finns för följande mönster för autentisering av klient flöde:
Autentisera användare med Active Directory-autentiseringsbibliotek
Du kan använda Active Directory-autentiseringsbibliotek (ADAL) för att starta användarautentisering från klienten med Azure Active Directory autentisering.
Konfigurera din server del för mobilappen för AAD-inloggning genom att följa själv studie kursen [konfigurera App Service för Active Directory inloggning] . Se till att slutföra det valfria steget när du registrerar ett internt klient program.
Öppna projektet i Visual Studio eller Xamarin Studio och Lägg till en referens till NuGet-
Microsoft.IdentityModel.Clients.ActiveDirectorypaketet. Inkludera för hands versioner vid sökning.Lägg till följande kod i programmet, enligt den plattform som du använder. I vart och ett ska du göra följande ersättningar:
Ersätt insert-Authority – här visas namnet på den klient där du etablerade ditt program. Formatet ska vara https://login.microsoftonline.com/contoso.onmicrosoft.com . Det här värdet kan kopieras från fliken domän i Azure Active Directory i [Azure Portal].
Ersätt insert-Resource-ID – här med klient-ID: t för Server delen för mobilappen. Du kan hämta klient-ID: t från fliken Avancerat under Azure Active Directory inställningar i portalen.
Ersätt insert-Client-ID – här med det klient-ID som du kopierade från det interna klient programmet.
Ersätt insert-Redirect-URI – här med platsens /.auth/login/Done -slutpunkt, med hjälp av https-schemat. Det här värdet bör likna https://contoso.azurewebsites.net/.auth/login/done .
Den kod som krävs för varje plattform följer:
Aktivitets
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); }
Enkla Sign-On med en token från Facebook eller Google
Du kan använda klient flödet som det visas i det här kodfragmentet för Facebook eller 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();
}
}
Server-hanterad autentisering
När du har registrerat din identitetsprovider anropar du LoginAsync -metoden på [MobileServiceClient] med MobileServiceAuthenticationProvider -värdet för providern. Följande kod initierar till exempel en server flödes inloggning genom att använda 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();
}
}
Om du använder en annan identitets leverantör än Facebook ändrar du värdet för MobileServiceAuthenticationProvider till värdet för din Provider.
Azure App Service hanterar flödet OAuth-autentisering i ett Server flöde genom att Visa inloggnings sidan för den valda providern. När identitets leverantören returnerar Azure App Service genererar en token för App Service autentisering. Metoden LoginAsync returnerar en MobileServiceUser, som tillhandahåller både UserID för den autentiserade användaren och MobileServiceAuthenticationToken, som en JSON Web token (JWT). Den här token kan cachelagras och återanvändas tills den upphör att gälla. Mer information finns i caching Authentication token.
När du använder Xamarin (antingen Android eller iOS) används Xamarin. Essentials webautentiserare. Du måste skicka standard kontexten (Android) eller UIViewController (iOS) till- LoginAsync metoden. Dessutom måste du hantera returen från webbautentiseraren. I Android hanteras detta i MainActivity.cs :
public override void OnResume()
{
base.OnResume();
Xamarin.Essentials.Platform.OnResume();
}
I iOS hanteras detta i 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);
}
Cachelagring av autentiseringstoken
I vissa fall kan anropet till inloggnings metoden undvikas efter den första lyckade autentiseringen genom att lagra autentiseringstoken från providern. Microsoft Store-och UWP-appar kan använda PasswordVault för att cachelagra aktuell autentiseringstoken efter en lyckad inloggning, enligt följande:
await client.LoginAsync(MobileServiceAuthenticationProvider.Facebook);
PasswordVault vault = new PasswordVault();
vault.Add(new PasswordCredential("Facebook", client.currentUser.UserId,
client.currentUser.MobileServiceAuthenticationToken));
UserId-värdet lagras som användar namn för autentiseringsuppgiften och token är lagrat som lösen ord. I efterföljande start fönster kan du kontrol lera PasswordVault för cachelagrade autentiseringsuppgifter. I följande exempel används cachelagrade autentiseringsuppgifter när de hittas och försöker på annat sätt autentisera igen med Server delen:
// 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.
}
När du loggar ut en användare måste du också ta bort den lagrade autentiseringsuppgiften enligt följande:
client.Logout();
vault.Remove(vault.Retrieve("Facebook", client.currentUser.UserId));
Xamarin-appar använder API: erna Xamarin. auth för att lagra autentiseringsuppgifter på ett säkert sätt i ett konto objekt. Ett exempel på hur du använder dessa API: er finns i AuthStore.cs -kod filen i exempel på ContosoMoments-bilddelning.
När du använder klient-hanterad autentisering kan du också cachelagra den åtkomsttoken som hämtats från leverantören, till exempel Facebook eller Twitter. Denna token kan anges för att begära en ny autentiseringstoken från Server delen, enligt följande:
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);
Push-meddelanden
Följande avsnitt beskriver push-meddelanden:
- Registrera dig för push-meddelanden
- Hämta ett Microsoft Store-paket-SID
- Registrera med mallar för fler plattformar
Gör så här: registrera dig för push-meddelanden
Med Mobile Apps-klienten kan du registrera dig för push-meddelanden med Azure Notification Hubs. När du registrerar dig får du en referens som du får från den plattformsspecifika PNS (Push Notification Service). Du anger detta värde tillsammans med alla Taggar när du skapar registreringen. Följande kod registrerar Windows-appen för push-meddelanden med 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);
}
Om du skickar till WNS måste du Skaffa ett Microsoft Store-paket-sid. Mer information om Windows-appar, inklusive hur du registrerar för mall registreringar finns i [lägga till push-meddelanden till din app].
Det finns inte stöd för att begära taggar från klienten. Tagg begär Anden tas bort tyst från registreringen.
Om du vill registrera din enhet med Taggar skapar du en anpassad API som använder Notification Hubs API för att utföra registreringen för din räkning. Anropa det anpassade API: t i stället för- RegisterNativeAsync() metoden.
Gör så här: Hämta ett Microsoft Store-paket-SID
Ett paket-SID krävs för att aktivera push-meddelanden i Microsoft Store appar. Registrera ditt program med Microsoft Store för att ta emot ett paket-SID.
Så här hämtar du det här värdet:
- Högerklicka på projektet Microsoft Store app i Visual Studio Solution Explorer, klicka på Store > associera app med Store....
- I guiden klickar du på Nästa , loggar in med ditt Microsoft-konto, skriver ett namn för din app i reservera ett nytt namn på appen och klickar sedan på reservera.
- När appens registrering har skapats väljer du appens namn, klickar på Nästa och klickar sedan på associera.
- Logga in på Windows Dev Center med ditt Microsoft-konto. Under Mina appar klickar du på den app-registrering som du skapade.
- Klicka på app Management > - appens identitet och bläddra sedan ned för att hitta paket-sid.
Många användnings områden i paket-SID: et behandlar det som en URI, i så fall måste du använda MS-app:// som schema. Anteckna vilken version av paket-SID som är utformad genom att sammanfoga det här värdet som ett prefix.
Xamarin-appar kräver ytterligare kod för att kunna registrera en app som körs på iOS-eller Android-plattformarna. Mer information finns i avsnittet för din plattform:
Gör så här: registrera push-mallar för att skicka meddelanden mellan plattformar
Om du vill registrera mallar använder du RegisterAsync() metoden med mallarna enligt följande:
JObject templates = myTemplates();
MobileService.GetPush().RegisterAsync(channel.Uri, templates);
Mallarna bör vara JObject typer och kan innehålla flera mallar i följande 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;
}
Metoden RegisterAsync () accepterar också sekundära paneler:
MobileService.GetPush().RegisterAsync(string channelUri, JObject templates, JObject secondaryTiles);
Alla Taggar rensas bort under registreringen för säkerhet. Om du vill lägga till taggar till installationer eller mallar i installationer, se [arbeta med .NET-Server del Server SDK för Azure Mobile Apps].
Information om hur du skickar meddelanden med hjälp av de här registrerade mallarna finns i [Notification Hubs API: er].
Diverse ämnen
Så här gör du: hantera fel
När ett fel uppstår i Server delen genererar klient-SDK: n en MobileServiceInvalidOperationException . I följande exempel visas hur du hanterar ett undantag som returneras av Server delen:
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
}
}
Ett annat exempel på hur du hanterar fel villkor finns i exemplet på [Mobile Apps-filer]. LoggingHandler -exemplet innehåller en hanterare för loggning av ombud för att logga de begär Anden som görs till Server delen.
Gör så här: anpassa begärandehuvuden
För att stödja ditt speciella program scenario kan du behöva anpassa kommunikationen med Server delen för mobilappar. Du kanske exempelvis vill lägga till en anpassad rubrik till varje utgående begäran eller till och med ändra svars status koder. Du kan använda en anpassad DelegatingHandler, som i följande exempel:
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;
}
}