In this article we will learn how to achieve CRUD (Create, Read, Update, and Delete) operations in UWA (Universal Windows App) using Web API.

First of all create a new Web API.

Create Web API


Image 1.

Now select Web API template and click OK.


Image 2.

Without wasting no more time I am attaching a screenshot of my Web API Data.


Image 3.

Getting Started UWA

Here are the steps to get started with Windows Universal App:


Image 4.

First of all start App.xaml.cs and declare the members and initialize the singleton application object.

  1. // Declare the members
  2. public static Uri BaseUri = new Uri("http://localhost:40752/api/books");
  3. public static Frame RootFrame { get; set; }
  4. public static Book Books { get; set; }
  5. public App()
  6. {
  7. this.InitializeComponent();
  8. this.Suspending += OnSuspending;
  9. using (var client = new HttpClient())
  10. {
  11. var response = "";
  12. client.MaxResponseContentBufferSize = 266000;
  13. client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
  14. Task task = Task.Run(async () =>
  15. {
  16. response = await client.GetStringAsync(App.BaseUri);
  17. });
  18. task.Wait(); // Wait
  19. App.Books = JsonConvert.DeserializeObject<List<Book>>(response)[0];
  20. }
  21. }

Now change RootFrame which is initialized as Frame property in OnLaunched application event.

  1. protected override void OnLaunched(LaunchActivatedEventArgs e)
  2. {
  3. #if DEBUG
  4. if (System.Diagnostics.Debugger.IsAttached)
  5. {
  6. this.DebugSettings.EnableFrameRateCounter = true;
  7. }
  8. #endif
  9. RootFrame = Window.Current.Content as Frame;
  10. // Do not repeat app initialization when the Window already has content,
  11. // just ensure that the window is active
  12. if (RootFrame == null)
  13. {
  14. // Create a Frame to act as the navigation context and navigate to the first page
  15. RootFrame = new Frame();
  16. RootFrame.NavigationFailed += OnNavigationFailed;
  17. if (e.PreviousExecutionState == ApplicationExecutionState.Terminated)
  18. {
  19. //TODO: Load state from previously suspended application
  20. }
  21. // Place the frame in the current Window
  22. Window.Current.Content = RootFrame;
  23. }
  24. if (RootFrame.Content == null)
  25. {
  26. // When the navigation stack isn't restored navigate to the first page,
  27. // configuring the new page by passing required information as a navigation
  28. // parameter
  29. RootFrame.Navigate(typeof(MyBooks), e.Arguments);
  30. }
  31. // Ensure the current window is active
  32. Window.Current.Activate();
  33. }
Now let’s add some buttons on a page for CRUD operations and navigate to them on specific pages.

<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">

<Grid Margin="10">

<Grid.RowDefinitions>

<RowDefinition Height="110"/>

<RowDefinition />

</Grid.RowDefinitions>

<StackPanel Grid.Row="0">

<TextBlock FontSize="30" HorizontalAlignment="Center" FontWeight="Bold">Universal Windows App Using Web API</TextBlock>

<TextBlock HorizontalAlignment="Center" TextWrapping="Wrap" FontStyle="Italic">This application would guide you through different stages of performing CRUDs operations in Universal Windows APP using WebAPI.</TextBlock>

</StackPanel>

<StackPanel Grid.Row="1" Margin="10, 0, 10, 0">

<Button Margin="0, 10, 0, 0" Click="Button_Click">Create New Book</Button>

<Button Margin="0, 10, 0, 0" Click="Button_Click">My Books</Button>

<Button Margin="0, 10, 0, 0" Click="Button_Click">Update Book</Button>

<Button Margin="0, 10, 0, 0" Click="Button_Click">Delete a Book</Button>

</StackPanel>

</Grid>

</Grid>

  1. private void Button_Click(object sender, RoutedEventArgs e)
  2. {
  3. switch ((sender as Button).Content.ToString())
  4. {
  5. case "Create":
  6. App.RootFrame.Navigate(typeof(CreateOrUpdate), true);
  7. break;
  8. case "My Books":
  9. App.RootFrame.Navigate(typeof(ShowBooks));
  10. break;
  11. case "Update Book":
  12. App.RootFrame.Navigate(typeof(CreateOrUpdate), false);
  13. break;
  14. case "Delete":
  15. App.RootFrame.Navigate(typeof(DeleteBook));
  16. break;
  17. default:
  18. break;
  19. }
  20. }
Now let’s show books list on ShowBooks page.

<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}" >

<Grid Name="viewList">

<Grid.RowDefinitions>

<RowDefinition Height="100"/>

<RowDefinition />

</Grid.RowDefinitions>

<StackPanel Grid.Row="0">

<TextBlock FontSize="25" FontWeight="Bold" HorizontalAlignment="Center">Books</TextBlock>

<TextBlock HorizontalAlignment="Center">On this page you will see a list of books.</TextBlock>

<Button Margin="10, 0, 0, 0" Click="Button_Click">Go Back</Button>

</StackPanel>

<StackPanel Grid.Row="1">

<ListView Name="listView" SelectionChanged="listView_SelectionChanged" >

<ListView.ItemTemplate>

<DataTemplate>

<Grid Margin="5" Background="AliceBlue" Width="900" >

<Grid.RowDefinitions>

<RowDefinition></RowDefinition>

<RowDefinition></RowDefinition>

<RowDefinition></RowDefinition>

</Grid.RowDefinitions>

<Grid.ColumnDefinitions>

<ColumnDefinition Width="300"></ColumnDefinition>

<ColumnDefinition Width="200"></ColumnDefinition>

<ColumnDefinition></ColumnDefinition>

</Grid.ColumnDefinitions>

<TextBlock Text="{Binding Title}" Grid.Row="0" Grid.Column="0" Style="{StaticResource BaseTextBlockStyle}"></TextBlock>

<TextBlock Text="{Binding PublishDate}" Grid.Row="0" Grid.Column="1" Style="{StaticResource CaptionTextBlockStyle}"></TextBlock>

<TextBlock Text="{Binding Author}" Grid.Row="0" Grid.Column="2" Style="{StaticResource CaptionTextBlockStyle}"></TextBlock>

<TextBlock Text="{Binding Description}" Grid.Row="1" Grid.ColumnSpan="2"></TextBlock>

<TextBlock Text="{Binding Price}" Grid.Row="2" Grid.Column="0"></TextBlock>

<TextBlock Text="{Binding Genre}" Grid.Row="2" Grid.Column="1" Grid.ColumnSpan="1"></TextBlock>

</Grid>

</DataTemplate>

</ListView.ItemTemplate>

</ListView>

</StackPanel>

</Grid>

<Grid Name="viewSingle" Visibility="Collapsed">

<StackPanel Margin="10">

<TextBlock Name="Title" Style="{StaticResource BaseTextBlockStyle}"></TextBlock>

<TextBlock Name="Author" FontStyle="Italic"></TextBlock>

<TextBlock Name="Genre" FontStyle="Italic"></TextBlock>

<TextBlock Name="Price" FontStyle="Italic"></TextBlock>

<TextBlock Name="PublishDate" FontStyle="Italic"></TextBlock>

<TextBlock Name="Descrition" FontStyle="Italic"></TextBlock>

<Button Click="Button_Click">View Books</Button>

</StackPanel>

</Grid>

</Grid>

  1. protected override void OnNavigatedTo(NavigationEventArgs e)
  2. {
  3. using (var client = new HttpClient())
  4. {
  5. var response = "";
  6. Task task = Task.Run(async () =>
  7. {
  8. response = await client.GetStringAsync(App.BaseUri);
  9. });
  10. task.Wait(); // Wait
  11. listView.ItemsSource = JsonConvert.DeserializeObject<List<Book>>(response);
  12. App.Books = JsonConvert.DeserializeObject<List<Book>>(response)[0];
  13. }
  14. }
  15. private void listView_SelectionChanged(object sender, SelectionChangedEventArgs e)
  16. {
  17. var item = ((sender as ListView).SelectedItem as Book);
  18. App.Books = item;
  19. Title.Text = item.Title;
  20. Author.Text = item.Author;
  21. Genre.Text = item.Genre;
  22. Price.Text = item.Price.ToString();
  23. PublishDate.Text = item.PublishDate.ToString();
  24. Descrition.Text = item.Description;
  25. // Change the UI
  26. viewList.Visibility = Windows.UI.Xaml.Visibility.Collapsed;
  27. viewSingle.Visibility = Windows.UI.Xaml.Visibility.Visible;
  28. }
  29. private void Button_Click(object sender, Windows.UI.Xaml.RoutedEventArgs e)
  30. {
  31. switch ((sender as Button).Content.ToString())
  32. {
  33. case "Go Back":
  34. App.RootFrame.Navigate(typeof(MyBooks));
  35. break;
  36. case "View Books":
  37. viewList.Visibility = Windows.UI.Xaml.Visibility.Visible;
  38. viewSingle.Visibility = Windows.UI.Xaml.Visibility.Collapsed;
  39. break;
  40. default:
  41. break;
  42. }
  43. }


Image 5.

If you click on a book.


Image 6.

Click on delete button

<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">

<StackPanel Name="panel" Margin="10">

<TextBlock Name="message"></TextBlock>

<Button Click="Button_Click">Yes</Button>

<Button Click="Button_Click" Margin="70, -33, 0, 0">Cancel</Button>

</StackPanel>

</Grid>

  1. protected override void OnNavigatedTo(NavigationEventArgs e)
  2. {
  3. message.Text = string.Format("Are you sure you want to delete {0}?", App.Books.Title);
  4. }
  5. private void Button_Click(object sender, RoutedEventArgs e)
  6. {
  7. switch ((sender as Button).Content.ToString())
  8. {
  9. case "Yes":
  10. // Send a request to delete the book
  11. using (var client = new HttpClient())
  12. {
  13. Task task = Task.Run(async () =>
  14. {
  15. await client.DeleteAsync(App.BaseUri + "/" + App.Books.Id.ToString());
  16. });
  17. task.Wait();
  18. }
  19. App.RootFrame.Navigate(typeof(ShowBooks));
  20. break;
  21. case "Cancel":
  22. App.RootFrame.Navigate(typeof(ShowBooks));
  23. break;
  24. default:
  25. break;
  26. }
  27. }

Image 7.

Create a new record

<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">

<Grid.RowDefinitions>

<RowDefinition Height="80"/>

<RowDefinition Height="220"/>

<RowDefinition Height="*"/>

</Grid.RowDefinitions>

<StackPanel Grid.Row="0">

<TextBlock FontSize="25" FontWeight="Bold" HorizontalAlignment="Center">Create a new Book</TextBlock>

<TextBlock FontStyle="Italic" HorizontalAlignment="Center">Update the following form and submit. It would update the current data source in Web API.</TextBlock>

</StackPanel>

<StackPanel Grid.Row="1" Margin="0,0,0,10" Grid.RowSpan="2">

<Grid Height="310" Margin="20, 10, 10, 0">

<Grid.ColumnDefinitions>

<ColumnDefinition Width="100"/>

<ColumnDefinition />

</Grid.ColumnDefinitions>

<StackPanel Grid.Column="0" Margin="0,0,0,60" d:LayoutOverrides="TopPosition, BottomPosition">

<TextBlock Margin="0, 10, 0, 8">

<Run Text="Id"/>

</TextBlock>

<TextBlock Margin="0, 6, 0, 8">

<Run Text="Title"/>

</TextBlock>

<TextBlock Margin="0, 7, 0, 6">

<Run Text="Author"/>

</TextBlock>

<TextBlock Margin="0, 10, 0, 0">

<Run Text="Genre"/>

</TextBlock>

<TextBlock Margin="0, 10, 0, 0">

<Run Text="Price"/>

</TextBlock>

<TextBlock Margin="0, 20, 0, 0">

<Run Text="Publish Date"/>

</TextBlock>

<TextBlock Margin="0, 20, 0, 0">

<Run Text="Description"/>

</TextBlock>

</StackPanel>

<StackPanel Grid.Column="1" Margin="0,0,0,60" d:LayoutOverrides="TopPosition, BottomPosition">

<TextBox x:Name="Id" Margin="0, 2, 0, 2"/>

<TextBox x:Name="Title" Margin="0, 2, 0, 2"/>

<TextBox x:Name="Author" Margin="0, 2, 0, 2"/>

<TextBox x:Name="Genre" Margin="0, 2, 0, 2"/>

<TextBox x:Name="Price" Margin="0, 2, 0, 2"/>

<TextBox x:Name="PublishDate" Margin="0, 2, 0, 2"/>

<TextBox x:Name="Description" Margin="0, 2, 0, 2"/>

</StackPanel>

<Button x:Name="actionButton" Grid.Column="1" Margin="0,0,0,4" Click="Button_Click" VerticalAlignment="Bottom" Content="Create"/>

</Grid>

<Button Margin="20, 0, 0, 0" Click="Button_Click">Cancel</Button>

</StackPanel>

</Grid>

  1. private void Button_Click(object sender, RoutedEventArgs e)
  2. {
  3. if ((sender as Button).Content.ToString() == "Cancel")
  4. {
  5. // Go to default page
  6. App.RootFrame.Navigate(typeof(ShowBooks));
  7. return; // and cancel the event.
  8. }
  9. // Otherwise
  10. var newbook = new Book
  11. {
  12. Id = Id.Text,
  13. Title = Title.Text,
  14. Author = Author.Text,
  15. Genre = Genre.Text,
  16. Price = decimal.Parse(Price.Text.ToString()),
  17. PublishDate = DateTime.Parse(PublishDate.Text.ToString()),
  18. Description = Description.Text
  19. };
  20. using (var client = new HttpClient())
  21. {
  22. var content = JsonConvert.SerializeObject(newbook);
  23. // Send a POST
  24. Task task = Task.Run(async () =>
  25. {
  26. var data = new HttpFormUrlEncodedContent(
  27. new Dictionary<string, string>
  28. {
  29. ["value"] = content
  30. }
  31. );
  32. await client.PostAsync(App.BaseUri, data);
  33. });
  34. task.Wait();
  35. }
  36. App.RootFrame.Navigate(typeof(ShowBooks));
  37. }


Image 8.

Update a record

<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">

<Grid.RowDefinitions>

<RowDefinition Height="80"/>

<RowDefinition Height="220"/>

<RowDefinition Height="*"/>

</Grid.RowDefinitions>

<StackPanel Grid.Row="0">

<TextBlock FontSize="25" FontWeight="Bold" HorizontalAlignment="Center">Create a new Book</TextBlock>

<TextBlock FontStyle="Italic" HorizontalAlignment="Center">Update the following form and submit. It would update the current data source in Web API.</TextBlock>

</StackPanel>

<StackPanel Grid.Row="1" Margin="0,0,0,10" Grid.RowSpan="2">

<Grid Height="310" Margin="20, 10, 10, 0">

<Grid.ColumnDefinitions>

<ColumnDefinition Width="100"/>

<ColumnDefinition />

</Grid.ColumnDefinitions>

<StackPanel Grid.Column="0" Margin="0,0,0,60" d:LayoutOverrides="TopPosition, BottomPosition">

<TextBlock Margin="0, 10, 0, 8">

<Run Text="Id"/>

</TextBlock>

<TextBlock Margin="0, 6, 0, 8">

<Run Text="Title"/>

</TextBlock>

<TextBlock Margin="0, 7, 0, 6">

<Run Text="Author"/>

</TextBlock>

<TextBlock Margin="0, 10, 0, 0">

<Run Text="Genre"/>

</TextBlock>

<TextBlock Margin="0, 10, 0, 0">

<Run Text="Price"/>

</TextBlock>

<TextBlock Margin="0, 20, 0, 0">

<Run Text="Publish Date"/>

</TextBlock>

<TextBlock Margin="0, 20, 0, 0">

<Run Text="Description"/>

</TextBlock>

</StackPanel>

<StackPanel Grid.Column="1" Margin="0,0,0,60" d:LayoutOverrides="TopPosition, BottomPosition">

<TextBox x:Name="Id" Margin="0, 2, 0, 2"/>

<TextBox x:Name="Title" Margin="0, 2, 0, 2"/>

<TextBox x:Name="Author" Margin="0, 2, 0, 2"/>

<TextBox x:Name="Genre" Margin="0, 2, 0, 2"/>

<TextBox x:Name="Price" Margin="0, 2, 0, 2"/>

<TextBox x:Name="PublishDate" Margin="0, 2, 0, 2"/>

<TextBox x:Name="Description" Margin="0, 2, 0, 2"/>

</StackPanel>

<Button x:Name="actionButton" Grid.Column="1" Margin="0,0,0,4" Click="Button_Click" VerticalAlignment="Bottom" Content="Update"/>

</Grid>

<Button Margin="20, 0, 0, 0" Click="Button_Click">Cancel</Button>

</StackPanel>

</Grid>

  1. protected override void OnNavigatedTo(NavigationEventArgs e)
  2. {
  3. if (e.Parameter as bool? == false)
  4. {
  5. var book = App.Books;
  6. Id.Text = book.Id.ToString();
  7. Title.Text = book.Title;
  8. Author.Text = book.Author;
  9. Genre.Text = book.Genre;
  10. Price.Text = book.Price.ToString();
  11. PublishDate.Text = book.PublishDate.ToString();
  12. Description.Text = book.Description;
  13. }
  14. }
  15. private void Button_Click(object sender, RoutedEventArgs e)
  16. {
  17. if ((sender as Button).Content.ToString() == "Cancel")
  18. {
  19. // Go to default page
  20. App.RootFrame.Navigate(typeof(ShowBooks));
  21. return; // and cancel the event.
  22. }
  23. // Otherwise
  24. var existingbook = new Book
  25. {
  26. Id = Id.Text,
  27. Title = Title.Text,
  28. Author = Author.Text,
  29. Genre = Genre.Text,
  30. Price = decimal.Parse(Price.Text.ToString()),
  31. PublishDate = DateTime.Parse(PublishDate.Text.ToString()),
  32. Description = Description.Text
  33. };
  34. using (var client = new HttpClient())
  35. {
  36. var content = JsonConvert.SerializeObject(existingbook);
  37. // Send a PUT
  38. Task task = Task.Run(async () =>
  39. {
  40. var data = new HttpFormUrlEncodedContent(
  41. new Dictionary<string, string>
  42. {
  43. ["value"] = content,
  44. ["id"] = App.Books.Id.ToString()
  45. }
  46. );
  47. await client.PutAsync(App.BaseUri, data);
  48. });
  49. task.Wait();
  50. }
  51. App.RootFrame.Navigate(typeof(ShowBooks));
  52. }

Image 9