Cara menggunakan klien terkelola untuk Azure Mobile Apps

Gambaran Umum

Panduan ini menunjukkan kepada Anda cara melakukan skenario umum menggunakan pustaka klien terkelola untuk aplikasi Azure App Service Mobile Apps for Windows dan Xamarin. Jika Anda baru mengenal Aplikasi Seluler, Anda harus mempertimbangkan untuk terlebih dahulu menyelesaikan tutorial mulai cepat Azure Mobile Apps . Dalam panduan ini, kami fokus pada SDK terkelola sisi klien. Untuk mempelajari lebih lanjut tentang SDK sisi server untuk Aplikasi Seluler, lihat dokumentasi untuk .NET Server SDK atau Node.js Server SDK.

Dokumentasi rujukan

Dokumentasi referensi untuk SDK klien terletak di sini: Referensi klien Azure Mobile Apps .NET. Anda juga dapat menemukan beberapa sampel klien di repositori GitHub Azure-Samples.

Platform yang Didukung

Platform .NET mendukung platform berikut:

  • Xamarin Android rilis untuk API 19 hingga 24 (KitKat melalui Nougat)
  • Xamarin iOS rilis untuk iOS versi 8.0 dan versi lebih baru
  • Universal Windows Platform
  • Windows Phone 8.1
  • Windows Phone 8.0 kecuali untuk aplikasi Silverlight

Autentikasi "alur server" menggunakan WebView untuk UI yang disajikan. Jika perangkat tidak dapat menyajikan UI WebView, maka metode otentikasi lain diperlukan. SDK ini dengan demikian tidak cocok untuk perangkat tipe Watch atau yang dibatasi serupa.

Penyiapan dan Prasyarat

Kami berasumsi bahwa Anda telah membuat dan menerbitkan proyek backend Aplikasi Seluler Anda, yang mencakup setidaknya satu tabel. Dalam kode yang digunakan dalam topik ini, tabel diberi nama TodoItem dan memiliki kolom berikut: Id, , Text, dan Complete. Tabel ini adalah tabel yang sama yang dibuat saat Anda menyelesaikan mulai cepat Azure Mobile Apps.

Tipe sisi klien yang diketik yang sesuai di C # adalah kelas berikut:

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 digunakan untuk menentukan pemetaan PropertyName antara bidang klien dan bidang tabel.

Untuk mempelajari cara membuat tabel di backend Aplikasi Seluler Anda, lihat topik .NET Server SDK atau topik SDK ServerNode.js. Jika Anda membuat backend Aplikasi Seluler di portal Azure menggunakan QuickStart, Anda juga dapat menggunakan pengaturan Tabel mudah di portal Azure.

Cara: Instal paket SDK klien terkelola

Gunakan salah satu metode berikut untuk menginstal paket SDK klien terkelola untuk Aplikasi Seluler dari NuGet:

  • Visual Studio Klik kanan proyek Anda, klik Kelola Paket NuGet, cari Microsoft.Azure.Mobile.Client paket, lalu klik Instal.
  • Studio Xamarin Klik kanan proyek Anda, klik TambahkanPaket NuGet AddAdd>, cari Microsoft.Azure.Mobile.Client paket, lalu klik Tambahkan Paket.

Di file aktivitas utama Anda, ingatlah untuk menambahkan yang berikut menggunakan pernyataan:

using Microsoft.WindowsAzure.MobileServices;

Catatan

Harap dicatat bahwa semua paket dukungan yang dirujuk dalam proyek Android Anda harus memiliki versi yang sama. SDK memiliki Xamarin.Android.Support.CustomTabs dependensi untuk platform Android, jadi jika proyek Anda menggunakan paket dukungan yang lebih baru, Anda perlu menginstal paket ini dengan versi yang diperlukan secara langsung untuk menghindari konflik.

Cara: Bekerja dengan simbol debug di Visual Studio

Simbol untuk namespace Microsoft.Azure.Mobile tersedia di SymbolSource. Lihat instruksi SymbolSource untuk mengintegrasikan SymbolSource dengan Visual Studio.

Membuat klien Aplikasi Seluler

Kode berikut membuat objek MobileServiceClient yang digunakan untuk mengakses backend Aplikasi Seluler Anda.

var client = new MobileServiceClient("MOBILE_APP_URL");

Pada kode sebelumnya, ganti MOBILE_APP_URL dengan URL backend Aplikasi Seluler, yang ditemukan di bilah untuk backend Aplikasi Seluler Anda di portal Azure. Objek MobileServiceClient harus menjadi singleton.

Bekerja dengan Tabel

Bagian berikut merinci cara mencari dan mengambil catatan dan memodifikasi data dalam tabel. Topik yang dibahas:

Cara: Membuat referensi tabel

Semua kode yang mengakses atau memodifikasi data dalam tabel backend memanggil fungsi pada MobileServiceTable objek. Dapatkan referensi ke tabel dengan memanggil metode GetTable , sebagai berikut:

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

Objek yang dikembalikan menggunakan model serialisasi yang diketik. Model serialisasi yang tidak diketik juga didukung. Contoh berikut membuat referensi ke tabel yang tidak diketik:

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

Dalam kueri yang tidak diketik, Anda harus menentukan string kueri OData yang mendasarinya.

Cara: Mengkueri data dari Aplikasi Seluler Anda

Bagian ini menjelaskan cara mengeluarkan kueri ke backend Aplikasi Seluler, yang mencakup fungsionalitas berikut:

Catatan

Ukuran halaman berbasis server diberlakukan untuk mencegah semua baris dikembalikan. Paging menyimpan permintaan default untuk kumpulan data besar agar tidak berdampak negatif pada layanan. Untuk mengembalikan lebih dari 50 baris, gunakan metode danTake, seperti yang Skip dijelaskan dalam Data kembali di halaman.

Cara: Memfilter data yang dikembalikan

Kode berikut mengilustrasikan cara memfilter data dengan Where menyertakan klausa dalam kueri. Ini mengembalikan semua item dari todoTable yang propertinya Complete sama dengan false. Fungsi Di mana menerapkan predikat pemfilteran baris ke kueri terhadap tabel.

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

Anda dapat melihat URI permintaan yang dikirim ke backend dengan menggunakan perangkat lunak inspeksi pesan, seperti alat pengembang browser atau Fiddler. Jika Anda melihat permintaan URI, perhatikan bahwa string kueri diubah:

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

Permintaan OData ini diterjemahkan ke dalam kueri SQL oleh SDK Server:

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

Fungsi yang diteruskan ke Where metode dapat memiliki jumlah kondisi yang sewenang-wenang.

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

Contoh ini akan diterjemahkan ke dalam kueri SQL oleh SDK Server:

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

Kueri ini juga dapat dibagi menjadi beberapa klausa:

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

Kedua metode tersebut setara dan dapat digunakan secara bergantian. Opsi sebelumnya—menggabungkan beberapa predikat dalam satu kueri—lebih ringkas dan direkomendasikan.

Klausa mendukung Where operasi yang diterjemahkan ke dalam subset OData. Operasi meliputi:

  • Operator relasional (==, !=, <, <=, >, >=),
  • Operator aritmatika (+, -, /, *, %),
  • Presisi angka (Math.Floor, Math.Ceiling),
  • Fungsi string (Panjang, Substring, Ganti, IndexOf, StartsWith, EndsWith),
  • Properti tanggal (Tahun, Bulan, Hari, Jam, Menit, Kedua),
  • Mengakses properti suatu objek, dan
  • Ekspresi yang menggabungkan salah satu operasi ini.

Saat mempertimbangkan apa yang didukung Sdk Server, Anda dapat mempertimbangkan Dokumentasi OData v3.

Cara: Mengurutkan data yang dikembalikan

Kode berikut mengilustrasikan cara mengurutkan data dengan menyertakan fungsi OrderBy atau OrderByDescending dalam kueri. Ini mengembalikan item dari todoTable ascending yang diurutkan berdasarkan Text bidang.

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

Cara: Mengembalikan data di halaman

Secara default, backend hanya mengembalikan 50 baris pertama. Anda dapat meningkatkan jumlah baris yang dikembalikan dengan memanggil metode Ambil . Gunakan Take bersama dengan metode Lewati untuk meminta "halaman" tertentu dari total himpunan data yang dikembalikan oleh kueri. Kueri berikut, saat dieksekusi, mengembalikan tiga item teratas dalam tabel.

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

Kueri revisi berikut melewati tiga hasil pertama dan mengembalikan tiga hasil berikutnya. Kueri ini menghasilkan "halaman" data kedua, di mana ukuran halaman adalah tiga item.

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

Metode IncludeTotalCount meminta jumlah total untuk semua catatan yang akan dikembalikan, mengabaikan klausa paging/batas yang ditentukan:

query = query.IncludeTotalCount();

Dalam aplikasi dunia nyata, Anda dapat menggunakan kueri yang mirip dengan contoh sebelumnya dengan kontrol pager atau UI yang sebanding untuk menavigasi antar halaman.

Catatan

Untuk mengganti batas 50 baris di backend Aplikasi Seluler, Anda juga harus menerapkan metode EnableQueryAttribute ke GET publik dan menentukan perilaku paging. Saat diterapkan ke metode, berikut ini menetapkan baris maksimum yang dikembalikan ke 1000:

[EnableQuery(MaxTop=1000)]

Cara: Pilih kolom tertentu

Anda dapat menentukan kumpulan properti mana yang akan disertakan dalam hasil dengan menambahkan klausa Pilih ke kueri Anda. Misalnya, kode berikut menunjukkan cara memilih hanya satu bidang dan juga cara memilih dan memformat beberapa bidang:

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

Semua fungsi yang dijelaskan sejauh ini adalah aditif, sehingga kita dapat terus merantainya. Setiap panggilan yang dirantai memengaruhi lebih banyak kueri. Satu contoh lagi:

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

Cara: Mencari data berdasarkan ID

Fungsi LookupAsync dapat digunakan untuk mencari objek dari database dengan ID tertentu.

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

Cara: Jalankan kueri yang tidak diketik

Saat mengeksekusi kueri menggunakan objek tabel yang tidak diketik, Anda harus secara eksplisit menentukan string kueri OData dengan memanggil ReadAsync, seperti pada contoh berikut:

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

Anda mendapatkan kembali nilai JSON yang dapat Anda gunakan seperti tas properti. Untuk informasi selengkapnya tentang JToken dan Newtonsoft Json.NET, lihat situs Json.NET .

Cara: Menyisipkan data ke backend Aplikasi Seluler

Semua jenis klien harus berisi anggota bernama Id, yang secara default adalah string. Id ini diperlukan untuk melakukan operasi CRUD dan untuk sinkronisasi offline. Kode berikut mengilustrasikan cara menggunakan metode InsertAsync untuk menyisipkan baris baru ke dalam tabel. Parameter berisi data yang akan dimasukkan sebagai objek .NET.

await todoTable.InsertAsync(todoItem);

Jika nilai ID kustom unik tidak disertakan dalam todoItem penyisipan selama, GUID dihasilkan oleh server. Anda dapat mengambil Id yang dihasilkan dengan memeriksa objek setelah panggilan kembali.

Untuk menyisipkan data yang tidak diketik, Anda dapat memanfaatkan Json.NET:

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

Berikut adalah contoh menggunakan alamat email sebagai id string unik:

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

Bekerja dengan nilai ID

Aplikasi Seluler mendukung nilai string kustom unik untuk kolom id tabel. Nilai string memungkinkan aplikasi untuk menggunakan nilai kustom seperti alamat email atau nama pengguna untuk ID. ID string memberi Anda manfaat berikut:

  • ID dihasilkan tanpa melakukan perjalanan pulang pergi ke database.
  • Catatan lebih mudah digabungkan dari tabel atau database yang berbeda.
  • Nilai-nilai ID dapat berintegrasi lebih baik dengan logika aplikasi.

Ketika nilai ID string tidak ditetapkan pada rekaman yang disisipkan, backend Aplikasi Seluler menghasilkan nilai unik untuk ID. Anda dapat menggunakan metode Guid.NewGuid untuk menghasilkan nilai ID Anda sendiri, baik pada klien atau di backend.

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

Cara: Memodifikasi data di backend Aplikasi Seluler

Kode berikut mengilustrasikan cara menggunakan metode UpdateAsync untuk memperbarui rekaman yang ada dengan ID yang sama dengan informasi baru. Parameter berisi data yang akan diperbarui sebagai objek .NET.

await todoTable.UpdateAsync(todoItem);

Untuk memperbarui data yang tidak diketik, Anda dapat memanfaatkan Json.NET sebagai berikut:

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

Bidang id harus ditentukan saat melakukan pembaruan. Backend menggunakan id bidang untuk mengidentifikasi baris mana yang akan diperbarui. Bidang id dapat diperoleh dari hasil InsertAsync panggilan. An ArgumentException dinaikkan jika Anda mencoba memperbarui item tanpa memberikan nilainya id .

Cara: Menghapus data di backend Aplikasi Seluler

Kode berikut mengilustrasikan cara menggunakan metode DeleteAsync untuk menghapus instans yang ada. Instans diidentifikasi oleh bidang yang id ditetapkan pada todoItem.

await todoTable.DeleteAsync(todoItem);

Untuk menghapus data yang tidak diketik, Anda dapat memanfaatkan Json.NET sebagai berikut:

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

Saat Anda membuat permintaan hapus, ID harus ditentukan. Properti lain tidak diteruskan ke layanan atau diabaikan di layanan. Hasil dari panggilan DeleteAsync biasanya null. ID untuk masuk dapat diperoleh dari hasil InsertAsync panggilan. A MobileServiceInvalidOperationException dilemparkan ketika Anda mencoba menghapus item tanpa menentukan bidang id .

Cara: Gunakan Konkurensi Optimis untuk resolusi konflik

Dua atau lebih klien dapat menulis perubahan pada item yang sama pada saat yang bersamaan. Tanpa deteksi konflik, tulisan terakhir akan menimpa pembaruan sebelumnya. Kontrol konkurensi optimis mengasumsikan bahwa setiap transaksi dapat melakukan dan oleh karena itu tidak menggunakan penguncian sumber daya. Sebelum melakukan transaksi, kontrol konkurensi optimis memverifikasi bahwa tidak ada transaksi lain yang mengubah data. Jika data telah dimodifikasi, transaksi yang dilakukan akan digulirkan kembali.

Aplikasi Seluler mendukung kontrol konkurensi optimis dengan melacak perubahan pada setiap item menggunakan version kolom properti sistem yang ditentukan untuk setiap tabel di backend Aplikasi Seluler Anda. Setiap kali rekaman diperbarui, Aplikasi Seluler menetapkan properti untuk rekaman tersebut version ke nilai baru. Selama setiap permintaan pembaruan, version properti catatan yang disertakan dengan permintaan dibandingkan dengan properti yang sama untuk catatan di server. Jika versi yang diteruskan dengan permintaan tidak cocok dengan backend, maka pustaka klien menimbulkan MobileServicePreconditionFailedException<T> pengecualian. Jenis yang disertakan dengan pengecualian adalah catatan dari backend yang berisi versi server dari catatan. Aplikasi kemudian dapat menggunakan informasi ini untuk memutuskan apakah akan menjalankan permintaan pembaruan lagi dengan nilai yang benar version dari backend untuk melakukan perubahan.

Tentukan kolom pada kelas tabel untuk version properti sistem untuk mengaktifkan konkurensi optimis. Contohnya:

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

Aplikasi menggunakan tabel yang tidak diketik memungkinkan konkurensi optimis dengan mengatur Version bendera pada SystemProperties tabel sebagai berikut.

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

Selain mengaktifkan konkurensi optimis, Anda juga harus menangkap pengecualian dalam kode Anda saat MobileServicePreconditionFailedException<T> memanggil UpdateAsync. Selesaikan konflik dengan menerapkan yang benar version ke catatan yang diperbarui dan memanggil UpdateAsync dengan catatan yang diselesaikan. Kode berikut menunjukkan cara menyelesaikan konflik tulis setelah terdeteksi:

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

Untuk informasi selengkapnya, lihat topik Sinkronisasi Data Offline di Azure Mobile Apps .

Cara: Mengikat data Aplikasi Seluler ke antarmuka pengguna Windows

Bagian ini menunjukkan cara menampilkan objek data yang dikembalikan menggunakan elemen UI dalam aplikasi Windows. Kode contoh berikut mengikat ke sumber daftar dengan kueri untuk item yang tidak lengkap. MobileServiceCollection membuat koleksi pengikatan sadar Aplikasi Seluler.

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

Beberapa kontrol dalam runtime terkelola mendukung antarmuka yang disebut ISupportIncrementalLoading. Antarmuka ini memungkinkan kontrol untuk meminta data tambahan saat pengguna menggulir. Ada dukungan bawaan untuk antarmuka ini untuk aplikasi Windows universal melalui MobileServiceIncrementalLoadingCollection, yang secara otomatis menangani panggilan dari kontrol. Gunakan MobileServiceIncrementalLoadingCollection di aplikasi Windows sebagai berikut:

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

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

Untuk menggunakan koleksi baru pada aplikasi Windows Phone 8 dan "Silverlight", gunakan ToCollection metode ekstensi pada IMobileServiceTableQuery<T> dan IMobileServiceTable<T>. Untuk memuat data, hubungi LoadMoreItemsAsync().

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

Saat Anda menggunakan koleksi yang dibuat dengan menelepon ToCollectionAsync atau ToCollection, Anda mendapatkan koleksi yang dapat terikat ke kontrol UI. Koleksi ini sangat sadar. Karena pengumpulan memuat data dari jaringan, pemuatan terkadang gagal. Untuk menangani kegagalan tersebut OnException , ganti metode MobileServiceIncrementalLoadingCollection untuk menangani pengecualian yang dihasilkan dari panggilan ke LoadMoreItemsAsync.

Pertimbangkan apakah tabel Anda memiliki banyak bidang tetapi Anda hanya ingin menampilkan beberapa di antaranya dalam kendali Anda. Anda dapat menggunakan panduan di bagian sebelumnya "Pilih kolom tertentu" untuk memilih kolom tertentu untuk ditampilkan di UI.

Mengubah ukuran Halaman

Azure Mobile Apps mengembalikan maksimal 50 item per permintaan secara default. Anda dapat mengubah ukuran paging dengan meningkatkan ukuran halaman maksimum pada klien dan server. Untuk meningkatkan ukuran halaman yang diminta, tentukan PullOptions saat menggunakan PullAsync():

PullOptions pullOptions = new PullOptions
    {
        MaxPageSize = 100
    };

Dengan asumsi Anda telah membuat PageSize sama dengan atau lebih besar dari 100 di dalam server, permintaan mengembalikan hingga 100 item.

Bekerja dengan Tabel Offline

Tabel offline menggunakan penyimpanan SQLite lokal untuk menyimpan data untuk digunakan saat offline. Semua operasi tabel dilakukan terhadap toko SQLite lokal, bukan toko server jarak jauh. Untuk membuat tabel offline, pertama-tama siapkan proyek Anda:

  1. Di Visual Studio, klik kanan solusi >Kelola Paket NuGet untuk Solusi..., lalu cari dan instal paket Microsoft.Azure.Mobile.Client.SQLiteStore NuGet untuk semua proyek dalam solusi.

  2. (Opsional) Untuk mendukung perangkat Windows, instal salah satu paket runtime SQLite berikut:

  3. (Opsional). Untuk perangkat Windows, klik ReferensiAdd> Reference..., perluas ekstensi folder > Windows, lalu aktifkan SQLite yang sesuai untuk SDK Windows bersama dengan Visual C ++ 2013 Runtime for Windows SDK. Nama SDK SQLite sedikit berbeda dengan setiap platform Windows.

Sebelum referensi tabel dapat dibuat, toko lokal harus disiapkan:

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

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

Inisialisasi toko biasanya dilakukan segera setelah klien dibuat. OfflineDbPath harus menjadi nama file yang cocok untuk digunakan di semua platform yang Anda dukung. Jika jalur adalah jalur yang sepenuhnya memenuhi syarat (yaitu, itu dimulai dengan garis miring), maka jalur itu digunakan. Jika jalur tidak sepenuhnya memenuhi syarat, file ditempatkan di lokasi khusus platform.

  • Untuk perangkat iOS dan Android, jalur default adalah folder "File Pribadi".
  • Untuk perangkat Windows, jalur default adalah folder "AppData" khusus aplikasi.

Referensi tabel dapat diperoleh dengan menggunakan metode:GetSyncTable<>

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

Anda tidak perlu mengautentikasi untuk menggunakan tabel offline. Anda hanya perlu mengautentikasi saat berkomunikasi dengan layanan backend.

Menyinkronkan Tabel Offline

Tabel offline tidak disinkronkan dengan backend secara default. Sinkronisasi dibagi menjadi dua bagian. Anda dapat mendorong perubahan secara terpisah dari mengunduh item baru. Berikut adalah metode sinkronisasi yang khas:

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

Jika argumen PullAsync pertama adalah null, maka sinkronisasi inkremental tidak digunakan. Setiap operasi sinkronisasi mengambil semua catatan.

SDK melakukan implisit PushAsync() sebelum menarik catatan.

Penanganan konflik terjadi dengan suatu PullAsync() metode. Anda dapat menangani konflik dengan cara yang sama seperti tabel online. Konflik dihasilkan ketika PullAsync() dipanggil, bukan selama penyisipan, pembaruan, atau hapus. Jika beberapa konflik terjadi, mereka dibundel ke dalam satu MobileServicePushFailedException. Tangani setiap kegagalan secara terpisah.

Bekerja dengan API kustom

API kustom memungkinkan Anda menentukan titik akhir kustom yang mengekspos fungsionalitas server yang tidak memetakan ke operasi sisipkan, perbarui, hapus, atau baca. Dengan menggunakan API khusus, Anda dapat memiliki kontrol lebih besar atas pesan, termasuk membaca dan mengatur header pesan HTTP dan menentukan format isi pesan selain JSON.

Anda memanggil API kustom dengan memanggil salah satu metode InvokeApiAsync pada klien. Misalnya, baris kode berikut mengirimkan permintaan POST ke completeAll API di backend:

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

Formulir ini adalah panggilan metode yang diketik dan mengharuskan jenis pengembalian MarkAllResult ditentukan. Metode yang diketik dan tidak diketik didukung.

Metode InvokeApiAsync() melakukan prepends '/api/' ke API yang ingin Anda panggil kecuali API dimulai dengan '/'. Contohnya:

  • InvokeApiAsync("completeAll",...) panggilan /api/completeSemua di backend
  • InvokeApiAsync("/.auth/me",...) panggilan /.auth/me di backend

Anda dapat menggunakan InvokeApiAsync untuk memanggil WebAPI apa pun, termasuk WebAPIs yang tidak ditentukan dengan Azure Mobile Apps. Saat Anda menggunakan InvokeApiAsync(), header yang sesuai, termasuk header autentikasi, dikirim dengan permintaan.

Mengautentikasi pengguna

Aplikasi Seluler mendukung pengautentikasian dan otorisasi pengguna aplikasi menggunakan berbagai penyedia identitas eksternal: Facebook, Google, Akun Microsoft, Twitter, dan Azure Active Directory. Anda dapat mengatur izin pada tabel untuk membatasi akses untuk operasi tertentu hanya untuk pengguna yang diautentikasi. Anda juga dapat menggunakan identitas pengguna yang diautentikasi untuk menerapkan aturan otorisasi dalam skrip server. Untuk informasi selengkapnya, lihat tutorial Menambahkan autentikasi ke aplikasi Anda.

Dua alur autentikasi didukung: alur yang dikelola klien dan dikelola server . Alur yang dikelola server memberikan pengalaman autentikasi yang paling sederhana, karena bergantung pada antarmuka autentikasi web penyedia. Alur yang dikelola klien memungkinkan integrasi yang lebih dalam dengan kemampuan khusus perangkat karena bergantung pada SDK khusus perangkat khusus penyedia.

Catatan

Sebaiknya gunakan alur yang dikelola klien di aplikasi produksi Anda.

Untuk menyiapkan autentikasi, Anda harus mendaftarkan aplikasi dengan satu atau beberapa penyedia identitas. Penyedia identitas menghasilkan ID klien dan rahasia klien untuk aplikasi Anda. Nilai-nilai ini kemudian diatur di backend Anda untuk mengaktifkan autentikasi/otorisasi Azure App Service. Untuk informasi selengkapnya, ikuti petunjuk terperinci dalam tutorial Tambahkan autentikasi ke aplikasi Anda.

Topik-topik berikut dibahas dalam bagian ini:

Autentikasi yang dikelola klien

Aplikasi Anda dapat secara independen menghubungi penyedia identitas dan kemudian memberikan token yang dikembalikan selama login dengan backend Anda. Alur klien ini memungkinkan Anda untuk memberikan pengalaman masuk tunggal bagi pengguna atau untuk mengambil data pengguna tambahan dari penyedia identitas. Autentikasi alur klien lebih disukai menggunakan alur server karena SDK penyedia identitas memberikan nuansa UX yang lebih asli dan memungkinkan penyesuaian tambahan.

Contoh disediakan untuk pola autentikasi alur klien berikut:

Mengautentikasi pengguna dengan Pustaka Autentikasi Direktori Aktif

Anda dapat menggunakan Active Directory Authentication Library (ADAL) untuk memulai autentikasi pengguna dari klien menggunakan autentikasi Azure Active Directory.

  1. Konfigurasikan backend aplikasi seluler Anda untuk AAD masuk dengan mengikuti tutorial login App Service for Active Directory. Pastikan untuk menyelesaikan langkah opsional mendaftarkan aplikasi klien asli.

  2. Di Visual Studio atau Xamarin Studio, buka proyek Anda dan tambahkan referensi ke Microsoft.IdentityModel.Clients.ActiveDirectory paket NuGet. Saat mencari, sertakan versi pra-rilis.

  3. Tambahkan kode berikut ke aplikasi Anda, sesuai dengan platform yang Anda gunakan. Di masing-masing, lakukan penggantian berikut:

    • Ganti INSERT-AUTHORITY-HERE dengan nama penyewa tempat Anda menyediakan aplikasi Anda. Formatnya harus https://login.microsoftonline.com/contoso.onmicrosoft.com. Nilai ini dapat disalin dari tab Domain di Azure Active Directory Anda di portal Azure.

    • Ganti INSERT-RESOURCE-ID-HERE dengan ID klien untuk backend aplikasi seluler Anda. Anda dapat memperoleh ID klien dari tab Tingkat Lanjut di bawah Azure Active Directory Pengaturan di portal.

    • Ganti INSERT-CLIENT-ID-HERE dengan ID klien yang Anda salin dari aplikasi klien asli.

    • Ganti INSERT-REDIRECT-URI-HERE dengan titik akhir /.auth/login/done situs Anda, menggunakan skema HTTPS. Nilai ini harus mirip https://contoso.azurewebsites.net/.auth/login/donedengan .

      Kode yang diperlukan untuk setiap platform berikut:

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

Sign-On tunggal menggunakan token dari Facebook atau Google

Anda dapat menggunakan alur klien seperti yang ditunjukkan dalam cuplikan ini untuk Facebook atau 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();
    }
}

Autentikasi yang dikelola server

Setelah Anda mendaftarkan penyedia identitas Anda, hubungi metode LoginAsync di [MobileServiceClient] dengan nilai MobileServiceAuthenticationProvider dari penyedia Anda. Misalnya, kode berikut memulai proses masuk alur server dengan menggunakan 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();
    }
}

Jika Anda menggunakan penyedia identitas selain Facebook, ubah nilai MobileServiceAuthenticationProvider menjadi nilai untuk penyedia Anda.

Dalam alur server, Azure App Service mengelola alur autentikasi OAuth dengan menampilkan halaman masuk penyedia yang dipilih. Setelah penyedia identitas kembali, Azure App Service menghasilkan token autentikasi App Service. Metode LoginAsync mengembalikan MobileServiceUser, yang menyediakan UserId dari pengguna yang diautentikasi dan MobileServiceAuthenticationToken, sebagai token web JSON (JWT). Token ini dapat di-cache dan digunakan kembali sampai kedaluwarsa. Untuk informasi selengkapnya, lihat Caching token autentikasi.

Saat menggunakan Xamarin (baik Android atau iOS), Xamarin.Essentials WebAuthenticator digunakan. Anda harus meneruskan konteks default (Android) atau UIViewController (iOS) ke metode.LoginAsync Selain itu, Anda harus menangani pengembalian dari pengautentikasi web. Di Android, ini ditangani dalam MainActivity.cs:

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

Di iOS, ini ditangani di 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);
}

Caching token autentikasi

Dalam beberapa kasus, panggilan ke metode login dapat dihindari setelah otentikasi pertama yang berhasil dengan menyimpan token otentikasi dari penyedia. Microsoft Store dan aplikasi UWP dapat menggunakan PasswordVault untuk menyimpan token autentikasi saat ini setelah berhasil masuk, sebagai berikut:

await client.LoginAsync(MobileServiceAuthenticationProvider.Facebook);

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

Nilai UserId disimpan sebagai UserName kredensial dan token disimpan sebagai Kata Sandi. Pada start-up berikutnya, Anda dapat memeriksa PasswordVault untuk kredensial yang di-cache. Contoh berikut menggunakan kredensial yang di-cache saat ditemukan, dan jika tidak, mencoba mengautentikasi lagi dengan backend:

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

Saat Anda keluar sebagai pengguna, Anda juga harus menghapus kredensial yang disimpan, sebagai berikut:

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

Aplikasi Xamarin menggunakan API Xamarin.Auth untuk menyimpan kredensial dengan aman di objek Akun . Untuk contoh menggunakan API ini, lihat file kode AuthStore.cs di sampel berbagi foto ContosoMoments.

Saat menggunakan autentikasi yang dikelola klien, Anda juga dapat menyimpan cache token akses yang diperoleh dari penyedia Anda seperti Facebook atau Twitter. Token ini dapat disediakan untuk meminta token autentikasi baru dari backend, sebagai berikut:

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

Pemberitahuan Push

Topik berikut mencakup Pemberitahuan Push:

Cara: Daftar Untuk Pemberitahuan Push

Klien Aplikasi Seluler memungkinkan Anda mendaftar untuk pemberitahuan push dengan Azure Notification Hubs. Saat mendaftar, Anda mendapatkan pegangan yang Anda dapatkan dari Layanan Pemberitahuan Push (PNS) khusus platform. Anda kemudian memberikan nilai ini bersama dengan tag apa pun saat Anda membuat pendaftaran. Kode berikut mendaftarkan aplikasi Windows Anda untuk pemberitahuan push dengan 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);
}

Jika Anda mendorong ke WNS, maka Anda HARUS mendapatkan SID paket Microsoft Store. Untuk informasi selengkapnya tentang aplikasi Windows, termasuk cara mendaftar pendaftaran templat, lihat Menambahkan pemberitahuan push ke aplikasi Anda.

Meminta tag dari klien tidak didukung. Permintaan Tag diam-diam dikeluarkan dari pendaftaran. Jika Anda ingin mendaftarkan perangkat Anda dengan tag, buat API Kustom yang menggunakan API Hub Pemberitahuan untuk melakukan pendaftaran atas nama Anda. Panggil API Kustom alih-alih RegisterNativeAsync() metode.

Cara: Dapatkan paket Microsoft Store SID

Paket SID diperlukan untuk mengaktifkan pemberitahuan push di aplikasi Microsoft Store. Untuk menerima paket SID, daftarkan aplikasi Anda dengan Microsoft Store.

Untuk mendapatkan nilai ini:

  1. Di Visual Studio Penjelajah Solusi, klik kanan proyek aplikasi Microsoft Store, klik Aplikasi StoreAssociate> dengan Store....
  2. Di panduan, klik Berikutnya, masuk dengan akun Microsoft Anda, ketik nama untuk aplikasi Anda di Pesan nama aplikasi baru, lalu klik Cadangan.
  3. Setelah pendaftaran aplikasi berhasil dibuat, pilih nama aplikasi, klik Berikutnya, lalu klik Kaitkan.
  4. Masuk ke Windows Dev Center menggunakan Akun Microsoft Anda. Di bawah Aplikasi saya, klik pendaftaran aplikasi yang Anda buat.
  5. Klik Identitas App ManagementApp>, lalu gulir ke bawah untuk menemukan SID Paket Anda.

Banyak penggunaan paket SID memperlakukannya sebagai URI, dalam hal ini Anda perlu menggunakan ms-app:// sebagai skema. Catat versi SID paket Anda yang dibentuk dengan menggabungkan nilai ini sebagai awalan.

Aplikasi Xamarin memerlukan beberapa kode tambahan untuk dapat mendaftarkan aplikasi yang berjalan di platform iOS atau Android. Untuk informasi lebih lanjut, lihat topik untuk platform Anda:

Cara: Daftarkan templat push untuk mengirim notifikasi lintas platform

Untuk mendaftarkan templat, gunakan RegisterAsync() metode dengan templat, sebagai berikut:

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

Template Anda harus JObject disekan dan dapat berisi beberapa templat dalam format JSON berikut:

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

Metode RegisterAsync() juga menerima Ubin Sekunder:

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

Semua tag dilucuti selama pendaftaran untuk keamanan. Untuk menambahkan tag ke instalasi atau templat dalam penginstalan, lihat [Bekerja dengan SDK server backend .NET untuk Azure Mobile Apps].

Untuk mengirim pemberitahuan menggunakan templat terdaftar ini, lihat API Hub Notifikasi.

Topik Lain-lain

Cara: Menangani kesalahan

Ketika kesalahan terjadi di backend, SDK klien memunculkan MobileServiceInvalidOperationException. Contoh berikut menunjukkan cara menangani pengecualian yang dikembalikan oleh backend:

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

Contoh lain dari berurusan dengan kondisi kesalahan dapat ditemukan di Mobile Apps Files Sample. Contoh LoggingHandler menyediakan penangan delegasi pencatatan untuk mencatat permintaan yang dibuat ke backend.

Cara: Mengkustomisasi header permintaan

Untuk mendukung skenario aplikasi tertentu, Anda mungkin perlu menyesuaikan komunikasi dengan backend Aplikasi Seluler. Misalnya, Anda mungkin ingin menambahkan header kustom ke setiap permintaan keluar atau bahkan mengubah kode status respons. Anda dapat menggunakan DelegatingHandler kustom, seperti dalam contoh berikut:

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