Catatan
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba masuk atau mengubah direktori.
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba mengubah direktori.
oleh Robert McMurray
Dalam tutorial ini, Anda akan mempelajari cara membuat skenario end-to-end lengkap yang terdiri dari aplikasi ASP.NET Web API yang menyediakan katalog buku ke aplikasi Windows Phone 8.
Gambaran Umum
Layanan RESTful seperti ASP.NET Web API menyederhanakan pembuatan aplikasi berbasis HTTP untuk pengembang dengan mengabstraksi arsitektur untuk aplikasi sisi server dan sisi klien. Alih-alih membuat protokol berbasis soket eksklusif untuk komunikasi, pengembang Web API hanya perlu menerbitkan metode HTTP yang diperlukan untuk aplikasi mereka, (misalnya: GET, POST, PUT, DELETE), dan pengembang aplikasi klien hanya perlu menggunakan metode HTTP yang diperlukan untuk aplikasi mereka.
Dalam tutorial end-to-end ini, Anda akan mempelajari cara menggunakan API Web untuk membuat proyek berikut:
- Di bagian pertama tutorial ini, Anda akan membuat aplikasi ASP.NET Web API yang mendukung semua operasi Buat, Baca, Perbarui, dan Hapus (CRUD) untuk mengelola katalog buku. Aplikasi ini akan menggunakan File XML Sampel (books.xml) dari MSDN.
- Di bagian kedua tutorial ini, Anda akan membuat aplikasi Windows Phone 8 interaktif yang mengambil data dari aplikasi Web API Anda.
Prasyarat
- Visual Studio 2013 dengan Windows Phone 8 SDK terinstal
- Windows 8 atau yang lebih baru pada sistem 64-bit dengan Hyper-V terinstal
- Untuk daftar persyaratan tambahan, lihat bagian Persyaratan Sistem di halaman unduhan Windows Phone SDK 8.0 .
Catatan
Jika Anda akan menguji konektivitas antara proyek Web API dan Windows Phone 8 di sistem lokal Anda, Anda harus mengikuti instruksi dalam artikel Menyambungkan Emulator Windows Phone 8 ke Web API di Komputer Lokal untuk menyiapkan lingkungan pengujian Anda.
Langkah 1: Membuat Proyek Bookstore API Web
Langkah pertama dari tutorial end-to-end ini adalah membuat proyek WEB API yang mendukung semua operasi CRUD; perhatikan bahwa Anda akan menambahkan proyek aplikasi Windows Phone ke solusi ini di Langkah 2 tutorial ini.
Buka Visual Studio 2013.
Klik File, lalu Baru, lalu Proyek.
Saat kotak dialog Proyek Baru ditampilkan, perluas Terinstal, lalu Templat, lalu Visual C#, lalu Web.
Klik gambar untuk memperluas Sorot ASP.NET Aplikasi Web, masukkan BookStore untuk nama proyek, lalu klik OK.
Saat kotak dialog Proyek ASP.NET Baru ditampilkan, pilih templat API Web , lalu klik OK.
Klik gambar untuk memperluas Saat proyek Web API terbuka, hapus pengontrol sampel dari proyek:
- Perluas folder Pengontrol di penjelajah solusi.
- Klik kanan file ValuesController.cs , lalu klik Hapus.
- Klik OK saat diminta untuk mengonfirmasi penghapusan.
Tambahkan file data XML ke proyek API Web; file ini berisi isi katalog bookstore:
Klik kanan folder App_Data di penjelajah solusi, lalu klik Tambahkan, lalu klik Item Baru.
Saat kotak dialog Tambahkan Item Baru ditampilkan, sorot templat File XML .
Beri nama file Books.xml, lalu klik Tambahkan.
Saat file Books.xml dibuka, ganti kode dalam file dengan XML dari sampel file books.xml di MSDN:
<?xml version="1.0" encoding="utf-8"?> <catalog> <book id="bk101"> <author>Gambardella, Matthew</author> <title>XML Developer's Guide</title> <genre>Computer</genre> <price>44.95</price> <publish_date>2000-10-01</publish_date> <description> An in-depth look at creating applications with XML. </description> </book> <book id="bk102"> <author>Ralls, Kim</author> <title>Midnight Rain</title> <genre>Fantasy</genre> <price>5.95</price> <publish_date>2000-12-16</publish_date> <description> A former architect battles corporate zombies, an evil sorceress, and her own childhood to become queen of the world. </description> </book> <book id="bk103"> <author>Corets, Eva</author> <title>Maeve Ascendant</title> <genre>Fantasy</genre> <price>5.95</price> <publish_date>2000-11-17</publish_date> <description> After the collapse of a nanotechnology society in England, the young survivors lay the foundation for a new society. </description> </book> <book id="bk104"> <author>Corets, Eva</author> <title>Oberon's Legacy</title> <genre>Fantasy</genre> <price>5.95</price> <publish_date>2001-03-10</publish_date> <description> In post-apocalypse England, the mysterious agent known only as Oberon helps to create a new life for the inhabitants of London. Sequel to Maeve Ascendant. </description> </book> <book id="bk105"> <author>Corets, Eva</author> <title>The Sundered Grail</title> <genre>Fantasy</genre> <price>5.95</price> <publish_date>2001-09-10</publish_date> <description> The two daughters of Maeve, half-sisters, battle one another for control of England. Sequel to Oberon's Legacy. </description> </book> <book id="bk106"> <author>Randall, Cynthia</author> <title>Lover Birds</title> <genre>Romance</genre> <price>4.95</price> <publish_date>2000-09-02</publish_date> <description> When Carla meets Paul at an ornithology conference, tempers fly as feathers get ruffled. </description> </book> <book id="bk107"> <author>Thurman, Paula</author> <title>Splish Splash</title> <genre>Romance</genre> <price>4.95</price> <publish_date>2000-11-02</publish_date> <description> A deep sea diver finds true love twenty thousand leagues beneath the sea. </description> </book> <book id="bk108"> <author>Knorr, Stefan</author> <title>Creepy Crawlies</title> <genre>Horror</genre> <price>4.95</price> <publish_date>2000-12-06</publish_date> <description> An anthology of horror stories about roaches, centipedes, scorpions and other insects. </description> </book> <book id="bk109"> <author>Kress, Peter</author> <title>Paradox Lost</title> <genre>Science Fiction</genre> <price>6.95</price> <publish_date>2000-11-02</publish_date> <description> After an inadvertant trip through a Heisenberg Uncertainty Device, James Salway discovers the problems of being quantum. </description> </book> <book id="bk110"> <author>O'Brien, Tim</author> <title>Microsoft .NET: The Programming Bible</title> <genre>Computer</genre> <price>36.95</price> <publish_date>2000-12-09</publish_date> <description> Microsoft's .NET initiative is explored in detail in this deep programmer's reference. </description> </book> <book id="bk111"> <author>O'Brien, Tim</author> <title>MSXML3: A Comprehensive Guide</title> <genre>Computer</genre> <price>36.95</price> <publish_date>2000-12-01</publish_date> <description> The Microsoft MSXML3 parser is covered in detail, with attention to XML DOM interfaces, XSLT processing, SAX and more. </description> </book> <book id="bk112"> <author>Galos, Mike</author> <title>Visual Studio 7: A Comprehensive Guide</title> <genre>Computer</genre> <price>49.95</price> <publish_date>2001-04-16</publish_date> <description> Microsoft Visual Studio 7 is explored in depth, looking at how Visual Basic, Visual C++, C#, and ASP+ are integrated into a comprehensive development environment. </description> </book> </catalog>
Simpan dan tutup file XML.
Tambahkan model bookstore ke proyek API Web; model ini berisi logika Buat, Baca, Perbarui, dan Hapus (CRUD) untuk aplikasi bookstore:
Klik kanan folder Model di penjelajah solusi, lalu klik Tambahkan, lalu klik Kelas.
Saat kotak dialog Tambahkan Item Baru ditampilkan, beri nama file kelas BookDetails.cs, lalu klik Tambahkan.
Saat file BookDetails.cs dibuka, ganti kode dalam file dengan yang berikut:
using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.Linq; using System.Xml; using System.Xml.Linq; using System.Xml.XPath; using System.Web; namespace BookStore.Models { /// <summary> /// Define a class that will hold the detailed information for a book. /// </summary> public class BookDetails { [Required] public String Id { get; set; } [Required] public String Title { get; set; } public String Author { get; set; } public String Genre { get; set; } public Decimal Price { get; set; } public DateTime PublishDate { get; set; } public String Description { get; set; } } /// <summary> /// Define an interface which contains the methods for the book repository. /// </summary> public interface IBookRepository { BookDetails CreateBook(BookDetails book); IEnumerable<BookDetails> ReadAllBooks(); BookDetails ReadBook(String id); BookDetails UpdateBook(String id, BookDetails book); Boolean DeleteBook(String id); } /// <summary> /// Define a class based on the book repository interface which contains the method implementations. /// </summary> public class BookRepository : IBookRepository { private string xmlFilename = null; private XDocument xmlDocument = null; /// <summary> /// Define the class constructor. /// </summary> public BookRepository() { try { // Determine the path to the books.xml file. xmlFilename = HttpContext.Current.Server.MapPath("~/app_data/books.xml"); // Load the contents of the books.xml file into an XDocument object. xmlDocument = XDocument.Load(xmlFilename); } catch (Exception ex) { // Rethrow the exception. throw ex; } } /// <summary> /// Method to add a new book to the catalog. /// Defines the implementation of the POST method. /// </summary> public BookDetails CreateBook(BookDetails book) { try { // Retrieve the book with the highest ID from the catalog. var highestBook = ( from bookNode in xmlDocument.Elements("catalog").Elements("book") orderby bookNode.Attribute("id").Value descending select bookNode).Take(1); // Extract the ID from the book data. string highestId = highestBook.Attributes("id").First().Value; // Create an ID for the new book. string newId = "bk" + (Convert.ToInt32(highestId.Substring(2)) + 1).ToString(); // Verify that this book ID does not currently exist. if (this.ReadBook(newId) == null) { // Retrieve the parent element for the book catalog. XElement bookCatalogRoot = xmlDocument.Elements("catalog").Single(); // Create a new book element. XElement newBook = new XElement("book", new XAttribute("id", newId)); // Create elements for each of the book's data items. XElement[] bookInfo = FormatBookData(book); // Add the element to the book element. newBook.ReplaceNodes(bookInfo); // Append the new book to the XML document. bookCatalogRoot.Add(newBook); // Save the XML document. xmlDocument.Save(xmlFilename); // Return an object for the newly-added book. return this.ReadBook(newId); } } catch (Exception ex) { // Rethrow the exception. throw ex; } // Return null to signify failure. return null; } /// <summary> /// Method to retrieve all of the books in the catalog. /// Defines the implementation of the non-specific GET method. /// </summary> public IEnumerable<BookDetails> ReadAllBooks() { try { // Return a list that contains the catalog of book ids/titles. return ( // Query the catalog of books. from book in xmlDocument.Elements("catalog").Elements("book") // Sort the catalog based on book IDs. orderby book.Attribute("id").Value ascending // Create a new instance of the detailed book information class. select new BookDetails { // Populate the class with data from each of the book's elements. Id = book.Attribute("id").Value, Author = book.Element("author").Value, Title = book.Element("title").Value, Genre = book.Element("genre").Value, Price = Convert.ToDecimal(book.Element("price").Value), PublishDate = Convert.ToDateTime(book.Element("publish_date").Value), Description = book.Element("description").Value }).ToList(); } catch (Exception ex) { // Rethrow the exception. throw ex; } } /// <summary> /// Method to retrieve a specific book from the catalog. /// Defines the implementation of the ID-specific GET method. /// </summary> public BookDetails ReadBook(String id) { try { // Retrieve a specific book from the catalog. return ( // Query the catalog of books. from book in xmlDocument.Elements("catalog").Elements("book") // Specify the specific book ID to query. where book.Attribute("id").Value.Equals(id) // Create a new instance of the detailed book information class. select new BookDetails { // Populate the class with data from each of the book's elements. Id = book.Attribute("id").Value, Author = book.Element("author").Value, Title = book.Element("title").Value, Genre = book.Element("genre").Value, Price = Convert.ToDecimal(book.Element("price").Value), PublishDate = Convert.ToDateTime(book.Element("publish_date").Value), Description = book.Element("description").Value }).Single(); } catch { // Return null to signify failure. return null; } } /// <summary> /// Populates a book BookDetails class with the data for a book. /// </summary> private XElement[] FormatBookData(BookDetails book) { XElement[] bookInfo = { new XElement("author", book.Author), new XElement("title", book.Title), new XElement("genre", book.Genre), new XElement("price", book.Price.ToString()), new XElement("publish_date", book.PublishDate.ToString()), new XElement("description", book.Description) }; return bookInfo; } /// <summary> /// Method to update an existing book in the catalog. /// Defines the implementation of the PUT method. /// </summary> public BookDetails UpdateBook(String id, BookDetails book) { try { // Retrieve a specific book from the catalog. XElement updateBook = xmlDocument.XPathSelectElement(String.Format("catalog/book[@id='{0}']", id)); // Verify that the book exists. if (updateBook != null) { // Create elements for each of the book's data items. XElement[] bookInfo = FormatBookData(book); // Add the element to the book element. updateBook.ReplaceNodes(bookInfo); // Save the XML document. xmlDocument.Save(xmlFilename); // Return an object for the updated book. return this.ReadBook(id); } } catch (Exception ex) { // Rethrow the exception. throw ex; } // Return null to signify failure. return null; } /// <summary> /// Method to remove an existing book from the catalog. /// Defines the implementation of the DELETE method. /// </summary> public Boolean DeleteBook(String id) { try { if (this.ReadBook(id) != null) { // Remove the specific child node from the catalog. xmlDocument .Elements("catalog") .Elements("book") .Where(x => x.Attribute("id").Value.Equals(id)) .Remove(); // Save the XML document. xmlDocument.Save(xmlFilename); // Return a success status. return true; } else { // Return a failure status. return false; } } catch (Exception ex) { // Rethrow the exception. throw ex; } } } }
Simpan dan tutup file BookDetails.cs .
Tambahkan pengontrol bookstore ke proyek API Web:
Klik kanan folder Pengontrol di penjelajah solusi, lalu klik Tambahkan, lalu klik Pengontrol.
Saat kotak dialog Tambahkan Perancah ditampilkan, sorot Pengontrol WEB API 2 - Kosong, lalu klik Tambahkan.
Saat kotak dialog Tambahkan Pengontrol ditampilkan, beri nama pengontrol BooksController, lalu klik Tambahkan.
Saat file BooksController.cs dibuka, ganti kode dalam file dengan yang berikut:
using System; using System.Collections.Generic; using System.Linq; using System.Net; using System.Net.Http; using System.Web.Http; using BookStore.Models; namespace BookStore.Controllers { public class BooksController : ApiController { private BookRepository repository = null; // Define the class constructor. public BooksController() { this.repository = new BookRepository(); } /// <summary> /// Method to retrieve all of the books in the catalog. /// Example: GET api/books /// </summary> [HttpGet] public HttpResponseMessage Get() { IEnumerable<BookDetails> books = this.repository.ReadAllBooks(); if (books != null) { return Request.CreateResponse<IEnumerable<BookDetails>>(HttpStatusCode.OK, books); } else { return Request.CreateResponse(HttpStatusCode.NotFound); } } /// <summary> /// Method to retrieve a specific book from the catalog. /// Example: GET api/books/5 /// </summary> [HttpGet] public HttpResponseMessage Get(String id) { BookDetails book = this.repository.ReadBook(id); if (book != null) { return Request.CreateResponse<BookDetails>(HttpStatusCode.OK, book); } else { return Request.CreateResponse(HttpStatusCode.NotFound); } } /// <summary> /// Method to add a new book to the catalog. /// Example: POST api/books /// </summary> [HttpPost] public HttpResponseMessage Post(BookDetails book) { if ((this.ModelState.IsValid) && (book != null)) { BookDetails newBook = this.repository.CreateBook(book); if (newBook != null) { var httpResponse = Request.CreateResponse<BookDetails>(HttpStatusCode.Created, newBook); string uri = Url.Link("DefaultApi", new { id = newBook.Id }); httpResponse.Headers.Location = new Uri(uri); return httpResponse; } } return Request.CreateResponse(HttpStatusCode.BadRequest); } /// <summary> /// Method to update an existing book in the catalog. /// Example: PUT api/books/5 /// </summary> [HttpPut] public HttpResponseMessage Put(String id, BookDetails book) { if ((this.ModelState.IsValid) && (book != null) && (book.Id.Equals(id))) { BookDetails modifiedBook = this.repository.UpdateBook(id, book); if (modifiedBook != null) { return Request.CreateResponse<BookDetails>(HttpStatusCode.OK, modifiedBook); } else { return Request.CreateResponse(HttpStatusCode.NotFound); } } return Request.CreateResponse(HttpStatusCode.BadRequest); } /// <summary> /// Method to remove an existing book from the catalog. /// Example: DELETE api/books/5 /// </summary> [HttpDelete] public HttpResponseMessage Delete(String id) { BookDetails book = this.repository.ReadBook(id); if (book != null) { if (this.repository.DeleteBook(id)) { return Request.CreateResponse(HttpStatusCode.OK); } } else { return Request.CreateResponse(HttpStatusCode.NotFound); } return Request.CreateResponse(HttpStatusCode.BadRequest); } } }
Simpan dan tutup file BooksController.cs .
Buat aplikasi Web API untuk memeriksa kesalahan.
Langkah 2: Menambahkan Proyek Katalog Bookstore Windows Phone 8
Langkah selanjutnya dari skenario end-to-end ini adalah membuat aplikasi katalog untuk Windows Phone 8. Aplikasi ini akan menggunakan templat Aplikasi Databound Windows Phone untuk antarmuka pengguna default, dan akan menggunakan aplikasi API Web yang Anda buat di Langkah 1 tutorial ini sebagai sumber data.
Klik kanan solusi BookStore di penjelajah solusi, lalu klik Tambahkan, lalu Proyek Baru.
Saat kotak dialog Proyek Baru ditampilkan, perluas Terinstal, lalu Visual C#, lalu Windows Phone.
Sorot Aplikasi Databound Windows Phone, masukkan BookCatalog untuk nama tersebut, lalu klik OK.
Tambahkan paket Json.NET NuGet ke proyek BookCatalog :
- Klik kanan Referensi untuk proyek BookCatalog di penjelajah solusi, lalu klik Kelola Paket NuGet.
- Saat kotak dialog Kelola Paket NuGet ditampilkan, perluas bagian Online , dan sorot nuget.org.
- Masukkan Json.NET di bidang pencarian dan klik ikon pencarian.
- Sorot Json.NET dalam hasil pencarian, lalu klik Instal.
- Setelah penginstalan selesai, klik Tutup.
Tambahkan model BookDetails ke proyek BookCatalog ; ini berisi model generik kelas bookstore:
Klik kanan proyek BookCatalog di penjelajah solusi, lalu klik Tambahkan, lalu klik Folder Baru.
Beri nama folder baru Model.
Klik kanan folder Model di penjelajah solusi, lalu klik Tambahkan, lalu klik Kelas.
Saat kotak dialog Tambahkan Item Baru ditampilkan, beri nama file kelas BookDetails.cs, lalu klik Tambahkan.
Saat file BookDetails.cs dibuka, ganti kode dalam file dengan yang berikut:
using System; using System.Text; namespace BookCatalog.Models { /// <summary> /// Define a class that will hold the detailed information for a book. /// </summary> public class BookDetails { public String Id { get; set; } public String Title { get; set; } public String Author { get; set; } public String Genre { get; set; } public Decimal Price { get; set; } public DateTime PublishDate { get; set; } public String Description { get; set; } } }
Simpan dan tutup file BookDetails.cs .
Perbarui kelas MainViewModel.cs untuk menyertakan fungsionalitas untuk berkomunikasi dengan aplikasi BOOKStore Web API:
Perluas folder ViewModels di penjelajah solusi, lalu klik dua kali file MainViewModel.cs .
Saat file MainViewModel.cs dibuka, ganti kode dalam file dengan yang berikut; perhatikan bahwa Anda harus memperbarui nilai
apiUrl
konstanta dengan URL aktual API Web Anda:using System; using System.Collections.ObjectModel; using System.ComponentModel; using System.Net; using System.Net.NetworkInformation; using BookCatalog.Resources; using System.Collections.Generic; using Newtonsoft.Json; using BookCatalog.Models; namespace BookCatalog.ViewModels { public class MainViewModel : INotifyPropertyChanged { const string apiUrl = @"http://www.contoso.com/api/Books"; public MainViewModel() { this.Items = new ObservableCollection<ItemViewModel>(); } /// <summary> /// A collection for ItemViewModel objects. /// </summary> public ObservableCollection<ItemViewModel> Items { get; private set; } public bool IsDataLoaded { get; private set; } /// <summary> /// Creates and adds a few ItemViewModel objects into the Items collection. /// </summary> public void LoadData() { if (this.IsDataLoaded == false) { this.Items.Clear(); this.Items.Add(new ItemViewModel() { ID = "0", LineOne = "Please Wait...", LineTwo = "Please wait while the catalog is downloaded from the server.", LineThree = null }); WebClient webClient = new WebClient(); webClient.Headers["Accept"] = "application/json"; webClient.DownloadStringCompleted += new DownloadStringCompletedEventHandler(webClient_DownloadCatalogCompleted); webClient.DownloadStringAsync(new Uri(apiUrl)); } } private void webClient_DownloadCatalogCompleted(object sender, DownloadStringCompletedEventArgs e) { try { this.Items.Clear(); if (e.Result != null) { var books = JsonConvert.DeserializeObject<BookDetails[]>(e.Result); int id = 0; foreach (BookDetails book in books) { this.Items.Add(new ItemViewModel() { ID = (id++).ToString(), LineOne = book.Title, LineTwo = book.Author, LineThree = book.Description.Replace("\n", " ") }); } this.IsDataLoaded = true; } } catch (Exception ex) { this.Items.Add(new ItemViewModel() { ID = "0", LineOne = "An Error Occurred", LineTwo = String.Format("The following exception occured: {0}", ex.Message), LineThree = String.Format("Additional inner exception information: {0}", ex.InnerException.Message) }); } } public event PropertyChangedEventHandler PropertyChanged; private void NotifyPropertyChanged(String propertyName) { PropertyChangedEventHandler handler = PropertyChanged; if (null != handler) { handler(this, new PropertyChangedEventArgs(propertyName)); } } } }
Simpan dan tutup file MainViewModel.cs .
Perbarui file MainPage.xaml untuk menyesuaikan nama aplikasi:
Klik dua kali file MainPage.xaml di penjelajah solusi.
Saat file MainPage.xaml dibuka, temukan baris kode berikut:
<StackPanel Grid.Row="0" Margin="12,17,0,28"> <TextBlock Text="MY APPLICATION" Style="{StaticResource PhoneTextNormalStyle}"/> <TextBlock Text="page name" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}"/> </StackPanel>
Ganti baris tersebut dengan yang berikut ini:
<StackPanel Grid.Row="0" Margin="12,17,0,28"> <TextBlock Text="Book Store" Style="{StaticResource PhoneTextTitle1Style}"/> <TextBlock Text="Current Catalog" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle2Style}"/> </StackPanel>
Simpan dan tutup file MainPage.xaml .
Perbarui file DetailsPage.xaml untuk menyesuaikan item yang ditampilkan:
Klik dua kali file DetailsPage.xaml di penjelajah solusi.
Saat file DetailsPage.xaml dibuka, temukan baris kode berikut:
<StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28"> <TextBlock Text="MY APPLICATION" Style="{StaticResource PhoneTextNormalStyle}"/> <TextBlock Text="{Binding LineOne}" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}"/> </StackPanel>
Ganti baris tersebut dengan yang berikut ini:
<StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28"> <TextBlock Text="Book Store" Style="{StaticResource PhoneTextTitle1Style}"/> <TextBlock Text="{Binding LineOne}" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle2Style}"/> </StackPanel>
Simpan dan tutup file DetailsPage.xaml .
Buat aplikasi Windows Phone untuk memeriksa kesalahan.
Langkah 3: Menguji Solusi End-to-End
Seperti disebutkan di bagian Prasyarat tutorial ini, ketika Anda menguji konektivitas antara proyek Web API dan Windows Phone 8 pada sistem lokal Anda, Anda harus mengikuti instruksi dalam menyambungkan Emulator Windows Phone 8 ke Aplikasi API Web di artikel Komputer Lokal untuk menyiapkan lingkungan pengujian Anda.
Setelah lingkungan pengujian dikonfigurasi, Anda harus mengatur aplikasi Windows Phone sebagai proyek startup. Untuk melakukannya, sorot aplikasi BookCatalog di penjelajah solusi, lalu klik Atur sebagai Proyek StartUp:
![]() |
---|
Klik gambar untuk memperluas |
Saat Anda menekan F5, Visual Studio akan memulai Kedua Emulator Windows Phone, yang akan menampilkan pesan "Harap Tunggu" saat data aplikasi diambil dari API Web Anda:
![]() |
---|
Klik gambar untuk memperluas |
Jika semuanya berhasil, Anda akan melihat katalog ditampilkan:
![]() |
---|
Klik gambar untuk memperluas |
Jika Anda mengetuk judul buku apa pun, aplikasi akan menampilkan deskripsi buku:
![]() |
---|
Klik gambar untuk memperluas |
Jika aplikasi tidak dapat berkomunikasi dengan API Web Anda, pesan kesalahan akan ditampilkan:
![]() |
---|
Klik gambar untuk memperluas |
Jika Anda mengetuk pesan kesalahan, detail tambahan tentang kesalahan akan ditampilkan:
![]() |
---|
Klik gambar untuk memperluas |