Windows Phone and JSON ในการเขียน Application เกือบทุกภาษาจะต้องมี JSON มาเกี่ยวข้องเสมอ เหตุผลที่ใช้ JSON หลัก ๆ แล้วก็คือ การที่เราจะสามารถแลกเปลี่ยนข้อมูลกับ Application อื่น ๆ ได้อย่างมีประสิทธิภาพ เนื่องจาก JSON ได้เป็นที่ยอมรับในหลาย ๆ ภาษาและมีมารตรฐานที่ภาษาต่าง ๆ ได้ออกแบบ function ที่จะจัดการกับข้อมูลชุดเหล่านั้นได้ และปัจจุบัน JSON ก็ได้ถูกใช้ในการแลกเปลี่ยนข้อมูลระหว่างกันอย่างกว้างขวาง และในบทความและตัวอย่างต่าง ๆ ทั้งหมดที่อยู่ในหมวดของ Windows Phone ผมจะเลือกใช้ JSON เกือบทุกตัวอย่างที่มีการรับส่งข้อมูลจาก Web Server และก็สามารถเข้าใจและเรียนรู้ได้โดยไม่ยาก
Windows Phone and JSON
ในการเขียนโปรแกรมเพื่ออ่าน JSON บน Windows Phone ด้วย .NET Framework เราจะใช้ NameSpace ของ System.Runtime.Serialization เข้ามาจัดการโดยไม่ต้องอาศัย Component จากแหล่งอื่น ๆ หรือถ้าใครสนใจตัว Library ก็ลองใช้ของ JSON.NET ก็น่าสนใจไม่น้อยเช่นเดียวกัน
JSON.NET
ในกรณีที่ใช้ Library ที่มีอยู่ใน .NET Framework ให้ Add Reference ต่าง ๆ เหล่านี้
System.Servicemodel.Web และ System.Xml.Linq
System.Runtime.Serialization และ Import Library ต่าง ๆ เหล่านี้เข้าไปใน Project ด้วยทุกครั้ง
Imports System.Runtime.Serialization
Imports System.Runtime.Serialization.Json
Imports System.Collections.ObjectModel
Example 1 การอ่าน JSON แบบข้อมูลชุดเดียว
ตัวอย่างแรกจะเป็นการใช้ Serialization อ่านข้อมูลที่อยู่ในรูปแบบของ JSON โดยข้อมูลที่อยู่ใน JSON เป็นข้อมูลที่มีชุดเดียว
{"MemberID":"1","Name":"Weerachai","Tel":"0819876107"}
รูปแบบ JSON Code
MainPage.xaml
<!--LayoutRoot is the root grid where all page content is placed-->
<Grid x:Name="LayoutRoot" Background="Transparent">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<!--TitlePanel contains the name of the application and page title-->
<StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28">
<TextBlock x:Name="ApplicationTitle" Text="MY APPLICATION" Style="{StaticResource PhoneTextNormalStyle}"/>
<TextBlock x:Name="PageTitle" Text="page name" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}"/>
</StackPanel>
<!--ContentPanel - place additional content here-->
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<TextBlock Height="30" HorizontalAlignment="Left" Margin="12,43,0,0" Text="MemberID : " VerticalAlignment="Top" />
<TextBox Height="72" HorizontalAlignment="Left" Margin="124,21,0,0" Name="txtMemberID" VerticalAlignment="Top" Width="116" />
<TextBlock Height="30" HorizontalAlignment="Left" Margin="10,118,0,0" Text="Name : " VerticalAlignment="Top" />
<TextBox Height="72" HorizontalAlignment="Left" Margin="124,99,0,0" Name="txtName" VerticalAlignment="Top" Width="276" />
<TextBlock Height="30" HorizontalAlignment="Left" Margin="12,196,0,0" Text="Tel : " VerticalAlignment="Top" />
<TextBox Height="72" HorizontalAlignment="Left" Margin="124,179,0,0" Name="txtTel" VerticalAlignment="Top" Width="276" />
</Grid>
</Grid>
MainPage.xaml.vb (VB.NET)
Imports System.Runtime.Serialization
Imports System.Runtime.Serialization.Json
Imports System.Collections.ObjectModel
Imports System.IO
Imports System.Text
Partial Public Class MainPage
Inherits PhoneApplicationPage
Public Sub New()
InitializeComponent()
AddHandler Loaded, AddressOf MainPage_Loaded
End Sub
Private Sub MainPage_Loaded(sender As Object, e As System.Windows.RoutedEventArgs)
Dim strJSON As String = ""
'JSON = {"MemberID":"1","Name":"Weerachai","Tel":"0819876107"}
strJSON = "{""MemberID"":""1"",""Name"":""Weerachai"",""Tel"":""0819876107""}"
Dim myMember As Member = ReadToObject(strJSON)
Me.txtMemberID.Text = myMember.MemberID.ToString()
Me.txtName.Text = myMember.Name.ToString()
Me.txtTel.Text = myMember.Tel.ToString()
End Sub
Public Shared Function ReadToObject(ByVal json As String) As Member
Dim deserializedMember As New Member()
Dim ms As New MemoryStream(Encoding.UTF8.GetBytes(json))
Dim ser As New DataContractJsonSerializer(deserializedMember.GetType())
deserializedMember = TryCast(ser.ReadObject(ms), Member)
ms.Close()
Return deserializedMember
End Function
<DataContract()> _
Public Class Member
<DataMember()> _
Public Property MemberID() As String
Get
Return m_MemberID
End Get
Set(value As String)
m_MemberID = value
End Set
End Property
<DataMember()> _
Public Property Name() As String
Get
Return m_Name
End Get
Set(value As String)
m_Name = value
End Set
End Property
<DataMember()> _
Public Property Tel() As String
Get
Return m_tel
End Get
Set(value As String)
m_tel = value
End Set
End Property
Private m_MemberID As String
Private m_Name As String
Private m_tel As String
Public Sub New()
End Sub
End Class
End Class
MainPage.xaml.cs (C#)
using System;
using System.Windows;
using Microsoft.Phone.Controls;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Json;
using System.IO;
using System.Text;
using Microsoft.Phone.Shell;
using System.Windows.Controls;
namespace PhoneApp
{
public partial class MainPage : PhoneApplicationPage
{
// Constructor
public MainPage()
{
InitializeComponent();
Loaded += MainPage_Loaded;
}
private void MainPage_Loaded(object sender, System.Windows.RoutedEventArgs e)
{
string strJSON = null;
// JSON = {"MemberID":"1","Name":"Weerachai","Tel":"0819876107"}
strJSON = " {\"MemberID\":\"1\",\"Name\":\"Weerachai\",\"Tel\":\"0819876107\"}";
Member myMember = ReadToObject(strJSON);
this.txtMemberID.Text = myMember.MemberID.ToString();
this.txtName.Text = myMember.Name.ToString();
this.txtTel.Text = myMember.Tel.ToString();
}
public static Member ReadToObject(string json)
{
Member deserializedMember = new Member();
MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(json));
DataContractJsonSerializer ser = new DataContractJsonSerializer(deserializedMember.GetType());
deserializedMember = ser.ReadObject(ms) as Member;
ms.Close();
return deserializedMember;
}
}
[DataContract]
public class Member
{
[DataMember]
public string MemberID { get; set; }
[DataMember]
public string Name { get; set; }
[DataMember]
public string Tel { get; set; }
public Member()
{
}
}
}
ในตัวอย่างนี้มี Code ทั้งที่เป็น VB.NET และ C# และสามารถดาวน์โหลด All Code ทั้งหมดได้จากส่วนท้ายของบทความ (Login สมาชิกก่อน)
Screenshot
แสดง JSON ที่ได้บน Textbox
Example 2 การอ่าน JSON จากข้อมูลที่อยู่ในรูปแบบหลายชุด ซึ่งเราจะแสดงข้อมูลนี้บน ListBox ผ่านการ Binding
ตัวอย่างที่สอง จะเป็นชุดข้อมูลของ JSON ที่อยู่ในรูปแบบมากกว่า 1 ชุด โดยจะมองว่าเป็นหลาย Rows หรือ Array ที่มีหลาย Index
[
{"MemberID":"1","Name":"Weerachai","Tel":"0819876107"},
{"MemberID":"2","Name":"Win","Tel":"021978032"},
{"MemberID":"3","Name":"Eak","Tel":"087654321"}
]
ข้อมูลจาก JSON ที่มีหลายชุด หรือหลายแถว ซึ่งเราจะแสดงข้อมูลนี้บน ListBox ผ่านการ Binding
MainPage.xaml
<!--LayoutRoot is the root grid where all page content is placed-->
<Grid x:Name="LayoutRoot" Background="Transparent">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<!--TitlePanel contains the name of the application and page title-->
<StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28">
<TextBlock x:Name="ApplicationTitle" Text="MY APPLICATION" Style="{StaticResource PhoneTextNormalStyle}"/>
<TextBlock x:Name="PageTitle" Text="page name" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}"/>
</StackPanel>
<!--ContentPanel - place additional content here-->
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<ListBox Margin="0,0,-12,0" x:Name="MemberList">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<StackPanel Orientation="Horizontal" Margin="0,0,0,17">
<TextBlock Text="{Binding MemberID}" TextWrapping="Wrap" Margin="5,0,0,0" Style="{StaticResource PhoneTextSubtleStyle}"/>
<TextBlock Text="{Binding Name}" TextWrapping="Wrap" Margin="5,0,0,0" Style="{StaticResource PhoneTextSubtleStyle}"/>
<TextBlock Text="{Binding Tel}" TextWrapping="Wrap" Margin="5,0,0,0" Style="{StaticResource PhoneTextSubtleStyle}"/>
</StackPanel>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
</Grid>
MainPage.xaml.vb (VB.NET)
Imports System.Runtime.Serialization
Imports System.Runtime.Serialization.Json
Imports System.Collections.ObjectModel
Imports System.IO
Imports System.Text
Partial Public Class MainPage
Inherits PhoneApplicationPage
' Constructor
Public Sub New()
InitializeComponent()
AddHandler Loaded, AddressOf MainPage_Loaded
End Sub
Private Sub MainPage_Loaded(sender As Object, e As System.Windows.RoutedEventArgs)
Dim strJSON As String
strJSON = " [ " & _
" {""MemberID"":""1"",""Name"":""Weerachai"",""Tel"":""0819876107""}," & _
" {""MemberID"":""2"",""Name"":""Win"",""Tel"":""021978032""}," & _
" {""MemberID"":""3"",""Name"":""Eak"",""Tel"":""087654321""}" & _
" ]"
Dim ms As New MemoryStream(Encoding.UTF8.GetBytes(strJSON))
Dim list As New ObservableCollection(Of Member)()
Dim serializer As New DataContractJsonSerializer(GetType(ObservableCollection(Of Member)))
list = DirectCast(serializer.ReadObject(ms), ObservableCollection(Of Member))
Dim myMember As New List(Of Member)
For Each cm As Member In list
Dim sMemberID As String = cm.MemberID.ToString()
Dim sName As String = cm.Name.ToString()
Dim sTel As String = cm.Tel.ToString()
myMember.Add(New Member(sMemberID, sName, sTel))
Next
Me.MemberList.ItemsSource = myMember
End Sub
<DataContract()> _
Public Class Member
<DataMember()> _
Public Property MemberID() As String
Get
Return m_MemberID
End Get
Set(value As String)
m_MemberID = value
End Set
End Property
<DataMember()> _
Public Property Name() As String
Get
Return m_Name
End Get
Set(value As String)
m_Name = value
End Set
End Property
<DataMember()> _
Public Property Tel() As String
Get
Return m_Tel
End Get
Set(value As String)
m_Tel = value
End Set
End Property
Private m_MemberID As String
Private m_Name As String
Private m_Tel As String
Public Sub New(ByVal strMemberID As String,
ByVal strName As String,
ByVal strTel As String)
Me.MemberID = strMemberID
Me.Name = strName
Me.Tel = strTel
End Sub
End Class
End Class
MainPage.xaml.cs (C#)
using System;
using System.Windows;
using Microsoft.Phone.Controls;
using System.Collections.Generic;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Json;
using System.Collections.ObjectModel;
using System.IO;
using System.Text;
namespace PhoneApp
{
public partial class MainPage : PhoneApplicationPage
{
// Constructor
public MainPage()
{
InitializeComponent();
Loaded += MainPage_Loaded;
}
private void MainPage_Loaded(object sender, System.Windows.RoutedEventArgs e)
{
string strJSON = null;
strJSON = " [ " + " {\"MemberID\":\"1\",\"Name\":\"Weerachai\",\"Tel\":\"0819876107\"}," + " {\"MemberID\":\"2\",\"Name\":\"Win\",\"Tel\":\"021978032\"}," + " {\"MemberID\":\"3\",\"Name\":\"Eak\",\"Tel\":\"087654321\"}" + " ]";
MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(strJSON));
ObservableCollection<Member> list = new ObservableCollection<Member>();
DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(ObservableCollection<Member>));
list = (ObservableCollection<Member>)serializer.ReadObject(ms);
List<Member> myMember = new List<Member>();
foreach (Member cm in list)
{
string sMemberID = cm.MemberID.ToString();
string sName = cm.Name.ToString();
string sTel = cm.Tel.ToString();
myMember.Add(new Member(sMemberID, sName, sTel));
}
this.MemberList.ItemsSource = myMember;
}
}
[DataContract]
public class Member
{
[DataMember]
public string MemberID { get; set; }
[DataMember]
public string Name { get; set; }
[DataMember]
public string Tel { get; set; }
public Member(string strMemberID, string strName, string strTel)
{
this.MemberID = strMemberID;
this.Name = strName;
this.Tel = strTel;
}
}
}
ในตัวอย่างนี้มี Code ทั้งที่เป็น VB.NET และ C# และสามารถดาวน์โหลด All Code ทั้งหมดได้จากส่วนท้ายของบทความ (Login สมาชิกก่อน)
Screenshot
แสดงข้อมูลจาก JSON ที่มีหลายชุดข้อมูล โดยผ่านการ Binding และแสดงผลบน ListBox
|