[Windows 8] Win 8 App針對ASP.net WebAPI 的CRUD(新增、查詢、修改、刪除)基本範例

[Windows 8] Win 8 App針對ASP.net WebAPI 的CRUD(新增、查詢、修改、刪除)基本範例

為了12/29晚上的2012 Windows App 嘉年華,所做的筆記,方便日後寫程式時複製貼上

※寫完才知道Win 8 App真囉嗦Orz,MessageBox沒了,變成MessageDialog,WebClient沒了,變成HttpClient寫法

ASP.net WebAPI使用ASP.net MVC架設,把集合變數儲存進Application來替代資料庫(要換成存取資料庫寫法的話,請自行發揮)

ASP.net MVC 4

Global.asax.cs


 public class WebApiApplication : System.Web.HttpApplication
    {
        protected void Application_Start()
        {

            if (HttpContext.Current.Application["Persons"] == null)
            {
                HttpContext.Current.Application["Persons"] = new List<Person>() { new Person() { Id = "1", Name = "Shadow", Age = 26 } };
            }

            AreaRegistration.RegisterAllAreas();
            /*加這個*/
            WebApiConfig.Register(GlobalConfiguration.Configuration);
            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
            RouteConfig.RegisterRoutes(RouteTable.Routes);
            BundleConfig.RegisterBundles(BundleTable.Bundles);
            //本WebAPI都使用Json操作
            GlobalConfiguration.Configuration.Formatters.XmlFormatter.SupportedMediaTypes.Clear();
        }
    }

WebApiConfig.cs


public static class WebApiConfig
    {
        public static void Register(HttpConfiguration config)
        {
            config.Routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "api/{controller}/{id}",
                defaults: new { id = RouteParameter.Optional }
            );
        }
    }

Controller新增一個繼承ApiController類別的TestController.cs


 public class TestController : ApiController
    {
        //取得全部資料
        // GET api/Test
        public IEnumerable<Person> Get()
        {

            return (HttpContext.Current.Application["Persons"] as List<Person>);
        }

        //取得單筆資料
        // GET api/Test/5
        public Person Get(string Id)
        {
            List<Person> persons = (HttpContext.Current.Application["Persons"] as List<Person>);
            return persons.SingleOrDefault(x=>x.Id==Id);
            
        }

        //新增一筆資料
        // POST api/Test
        public void Post([FromBody]Person value)
        {
            List<Person> persons = HttpContext.Current.Application["Persons"] as List<Person>;
            var pp = from p in persons
                     where p.Id == value.Id
                     select p;
            if (!pp.Any())
            {//集合裡無此資料
                persons.Add(value);
                HttpContext.Current.Application["Persons"] = persons; 
            }
             

             

        }

        //修改一筆資料
        // PUT api/Test/5
        public void Put(string Id,[FromBody]Person value)
        {
            List<Person> persons = HttpContext.Current.Application["Persons"] as List<Person>;
            var pp = from p in persons
                     where p.Id == value.Id
                     select p;
            if (pp.Any())//集合裡有該筆Id
            {
                Person source = pp.SingleOrDefault();
                persons.Remove(source);//先移除掉,待會要重新加入
                source.Name = value.Name;
                source.Age = value.Age;
                persons.Add(source);   
            }
             
        }

        //刪除一筆資料
        // DELETE api/Test/5
        public void Delete(string Id)
        {
            List<Person> persons = HttpContext.Current.Application["Persons"] as List<Person>;

            var pp = from p in persons
                     where p.Id == Id
                     select p;
            
            if (pp.Any())//有該筆Id
            {
                persons.Remove(pp.SingleOrDefault());
                
            }
             
        }
    }

ASP.net Web API的設定到此結束

 

Windows 8 App端


<Page
    x:Class="AppGrid.Demo"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:AppGrid"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">

    <Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
        <TextBlock FontSize="15" HorizontalAlignment="Left" Margin="51,51,0,0" TextWrapping="Wrap" Text="Id" VerticalAlignment="Top"/>
        <TextBox HorizontalAlignment="Left" Margin="74,44,0,0" TextWrapping="Wrap" x:Name="txtId" VerticalAlignment="Top" Height="7" Width="56" RenderTransformOrigin="0.5,0.5" />
        <TextBlock HorizontalAlignment="Left" Margin="160,51,0,0" TextWrapping="Wrap" Text="Name" VerticalAlignment="Top"/>
        <TextBox HorizontalAlignment="Left" Margin="194,44,0,0" TextWrapping="Wrap" x:Name="txtName" VerticalAlignment="Top"/>
        <TextBlock HorizontalAlignment="Left" Margin="280,51,0,0" TextWrapping="Wrap" Text="Age" VerticalAlignment="Top"/>
        <TextBox HorizontalAlignment="Left" Margin="314,44,0,0" TextWrapping="Wrap" x:Name="txtAge" VerticalAlignment="Top"/>
        <Button Content="新增" x:Name="btnAdd" HorizontalAlignment="Left" Margin="395,44,0,0" VerticalAlignment="Top" Click="btnAdd_Click"/>
        <Button Content="修改" x:Name="btnUpdate" HorizontalAlignment="Left" Margin="480,44,0,0" VerticalAlignment="Top" Click="btnUpdate_Click"/>
        <Button Content="刪除" x:Name="btnDelete" HorizontalAlignment="Left" Margin="565,44,0,0" VerticalAlignment="Top" Click="btnDelete_Click"/>
        <Button Content="查詢單筆" x:Name="btnSelectOne" HorizontalAlignment="Left" Margin="644,44,0,0" VerticalAlignment="Top" Click="btnSelectOne_Click"/>
        <Button Content="查詢全部" x:Name="btnSelectAll" HorizontalAlignment="Left" Margin="51,99,0,0" VerticalAlignment="Top" Click="btnSelectAll_Click"/>
        <GridView  x:Name="gv_Result" HorizontalAlignment="Left" Margin="64,166,0,0" VerticalAlignment="Top" Width="673" Height="116"  >
            <GridView.ItemTemplate>
                <DataTemplate>
                     
                    <Grid>
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="Auto"></ColumnDefinition>
                            <ColumnDefinition Width="Auto"></ColumnDefinition>
                            <ColumnDefinition Width="Auto"></ColumnDefinition>
                        </Grid.ColumnDefinitions>
                        <Grid.RowDefinitions>
                            <RowDefinition></RowDefinition>
                        </Grid.RowDefinitions>
                        <TextBlock Text="{Binding Id}" Grid.Column="0" Grid.Row="0"  Margin="0,0,10,0" />
                        <TextBlock Text="{Binding Name}" Grid.Column="1" Grid.Row="0" Margin="0,0,10,0"  />
                        <TextBlock Text="{Binding Age}" Grid.Column="2" Grid.Row="0"  Margin="0,0,10,0"/>
                    </Grid>
                </DataTemplate>
            </GridView.ItemTemplate>
        </GridView>


    </Grid>
</Page>

畫面:

image

以下才是本文的重點:


using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Json;
using Windows.Data.Json;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.UI.Popups;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;

// 空白頁項目範本已記錄在 http://go.microsoft.com/fwlink/?LinkId=234238

namespace AppGrid
{
    /// <summary>
    /// 可以在本身使用或巡覽至框架內的空白頁面。
    /// </summary>
    public sealed partial class Demo : Page
    {
        public Demo()
        {
            this.InitializeComponent();
        }

        /// <summary>
        /// 在此頁面即將顯示在框架中時叫用。
        /// </summary>
        /// <param name="e">描述如何到達此頁面的事件資料。Parameter
        /// 屬性通常用來設定頁面。</param>
        protected override void OnNavigatedTo(NavigationEventArgs e)
        {
        }

        //查詢全部
        private async void btnSelectAll_Click(object sender, RoutedEventArgs e)
        {
            HttpClient client = new HttpClient();
            //由HttpClient發出Get Method
            HttpResponseMessage response = await client.GetAsync("http://localhost:5590/api/Test/");

            //創建處理序列化的物件
            DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(IEnumerable<Person>));

            Stream stream = await response.Content.ReadAsStreamAsync();
            //由於有可能抓到null,所以先轉型成IEnumerable<Person>來判斷
            IEnumerable<Person> persons = (IEnumerable<Person>)serializer.ReadObject(stream);
            if (persons!=null)
            {
                gv_Result.ItemsSource = persons;
            }
            else
            {
                MessageDialog dialog = new MessageDialog("內文:查無資料!", "訊息標題");
                dialog.Commands.Add(new UICommand("OK"));
               await dialog.ShowAsync();
            }
            
        }
        //查詢單筆
        private async void btnSelectOne_Click(object sender, RoutedEventArgs e)
        {
            HttpClient client = new HttpClient();
            //由HttpClient發出Get Method
            HttpResponseMessage response = await client.GetAsync("http://localhost:5590/api/Test/" + txtId.Text.Trim());

            //創建處理序列化的物件
            DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(Person));
            //把讀取內容轉成Stream
            Stream stream = await response.Content.ReadAsStreamAsync();
            //由於有可能抓到null,所以先宣告一個Person物件來接反序例化
            Person person = (Person)serializer.ReadObject(stream);
            //GridView的ItemSource只能接受集合
            ObservableCollection<Person> collection = new ObservableCollection<Person>();
            //有抓到
            if (person != null)
            {
                collection.Add(person);
            }
            else
            {
                MessageDialog dialog = new MessageDialog("內文:查無資料!", "訊息標題");
                dialog.Commands.Add(new UICommand("OK"));
                await dialog.ShowAsync();
            }
            gv_Result.ItemsSource = collection;
        }
        //新增
        private async void btnAdd_Click(object sender, RoutedEventArgs e)
        {
            //創建一個處理序列化的DataContractJsonSerializer
            DataContractJsonSerializer serializer=new DataContractJsonSerializer(typeof(Person));
            MemoryStream ms = new MemoryStream()  ;  
            //將資料寫入MemoryStream
            serializer.WriteObject(ms,new Person(){ Id=txtId.Text,Name=txtName.Text,Age=Convert.ToInt32( txtAge.Text)});
            //一定要在這設定Position
            ms.Position = 0;
            HttpContent content = new StreamContent(ms);//將MemoryStream轉成HttpContent
            //一定要設定Header
            content.Headers.ContentType=new System.Net.Http.Headers.MediaTypeHeaderValue("application/json");
            
            HttpClient client = new HttpClient();
            //由HttpClient發出Post Method
            HttpResponseMessage response = await client.PostAsync("http://localhost:5590/api/Test/", content );
           
            
        }
        //修改
        private async void btnUpdate_Click(object sender, RoutedEventArgs e)
        {

            //創建一個處理序列化的DataContractJsonSerializer
            DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(Person));
            MemoryStream ms = new MemoryStream();
            //將資料寫入MemoryStream
            serializer.WriteObject(ms, new Person() { Id = txtId.Text, Name = txtName.Text, Age = Convert.ToInt32(txtAge.Text) });
            //一定要在這設定Position
            ms.Position = 0;
            HttpContent content = new StreamContent(ms);//將MemoryStream轉成HttpContent
            //一定要設定Header
            content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/json");

            HttpClient client = new HttpClient();
            //由HttpClient發出Put Method
            HttpResponseMessage response = await client.PutAsync("http://localhost:5590/api/Test/"+txtId.Text,content);
           
            
        }
        //刪除
        private async  void btnDelete_Click(object sender, RoutedEventArgs e)
        {
 
            HttpClient client = new HttpClient();
            //由HttpClient發出Delete Method
            HttpResponseMessage response = await client.DeleteAsync("http://localhost:5590/api/Test/" +txtId.Text);
           
        }
    }
}

執行結果:

(查詢單筆)

image

(查無資料時)

image

 

參考文章:

Metro client for Web API CRUD

24.42.1.Simple Grid.xaml

[Windows 8] 开发初体验:对话框(MessageBox)和程序任务栏(ApplicationBar)