重新想象 Windows 8 Store Apps (60) - 通訊: 獲取網路資訊, 序列化和反序列化
作者:webabcd
介紹
重新想象 Windows 8 Store Apps 之 通訊
- 獲取網路資訊
- 序列化 - json
- 序列化 - xml
- 序列化 - rss atom
示例
1、演示如何獲取網路的相關資訊
Communication/NetworkInfo.xaml.cs
/* * 演示如何獲取網路的相關資訊 */ using System; using System.Collections.Generic; using Windows.Networking.Connectivity; using Windows.UI.Xaml.Controls; using Windows.UI.Xaml.Navigation; using System.Linq; namespace XamlDemo.Communication { public sealed partial class NetworkInfo : Page { public NetworkInfo() { this.InitializeComponent(); } protected override void OnNavigatedTo(NavigationEventArgs e) { /* * NetworkInformation - 用於對網路資訊的訪問 */ // 獲取當前用於 Internet 連線的 ConnectionProfile 物件 ConnectionProfile connectionProfile = NetworkInformation.GetInternetConnectionProfile(); if (connectionProfile == null) return; // 此連線配置的名稱 lblMsg.Text = "ProfileName: " + connectionProfile.ProfileName; lblMsg.Text += Environment.NewLine; // 此連線的網路連線級別(Windows.Networking.Connectivity.NetworkConnectivityLevel 列舉) // None - 無連線 // LocalAccess - 僅允許訪問本地網路 // ConstrainedInternetAccess - 受限的 internet 訪問 // InternetAccess - 本地和 internet 訪問 lblMsg.Text += "NetworkConnectivityLevel: " + connectionProfile.GetNetworkConnectivityLevel(); lblMsg.Text += Environment.NewLine; // 網路狀態發生變化時所觸發的事件 NetworkInformation.NetworkStatusChanged += NetworkInformation_NetworkStatusChanged; NetworkAdapter networkAdapter = connectionProfile.NetworkAdapter; if (networkAdapter != null) { lblMsg.Text += "NetworkAdapterId: " + networkAdapter.NetworkAdapterId; // 網路介面卡 ID lblMsg.Text += Environment.NewLine; lblMsg.Text += "InboundMaxBitsPerSecond: " + networkAdapter.InboundMaxBitsPerSecond; // 最大入站資料傳輸速率(單位:bit/s) lblMsg.Text += Environment.NewLine; lblMsg.Text += "OutboundMaxBitsPerSecond: " + networkAdapter.OutboundMaxBitsPerSecond; // 最大出站資料傳輸速率(單位:bit/s) lblMsg.Text += Environment.NewLine; lblMsg.Text += "NetworkTypes: " + networkAdapter.NetworkItem.GetNetworkTypes(); // 網路型別 lblMsg.Text += Environment.NewLine; } lblMsg.Text += Environment.NewLine; // 獲取所有可用連線 IReadOnlyList<ConnectionProfile> connectionProfiles = NetworkInformation.GetConnectionProfiles(); foreach (ConnectionProfile cp in connectionProfiles) { lblMsg.Text += "ProfileName: " + cp.ProfileName; lblMsg.Text += Environment.NewLine; // 獲取此連線的指定時間段內的本地資料的使用情況 DataUsage dataUsage = cp.GetLocalUsage(DateTime.Now.AddHours(-1), DateTime.Now); lblMsg.Text += "BytesSent: " + dataUsage.BytesSent; // 已傳送的位元組數 lblMsg.Text += Environment.NewLine; lblMsg.Text += "BytesReceived: " + dataUsage.BytesReceived; // 已收到的位元組數 lblMsg.Text += Environment.NewLine; } // 以下是一些不常用的東西 ConnectionCost connectionCost = connectionProfile.GetConnectionCost(); DataPlanStatus dataPlanStatus = connectionProfile.GetDataPlanStatus(); NetworkSecuritySettings networkSecuritySettings = connectionProfile.NetworkSecuritySettings; IReadOnlyList<LanIdentifier> lanIdentifiers = NetworkInformation.GetLanIdentifiers(); } void NetworkInformation_NetworkStatusChanged(object sender) { } } }
用於演示序列化和反序列化的實體類
Communication/Serializer/Product.cs
/* * 用於演示序列化和反序列化的實體類 * * 通過 DataContractJsonSerializer 或 DataContractSerializer 做序列化和反序列化時,其支援 DataContract, DataMember, KnownType * 當然如果都不宣告 DataContract, DataMember 也沒問題 */ using System; using System.Collections.Generic; using System.Runtime.Serialization; namespace XamlDemo.Communication.Serializer { [DataContract(Name="product")] public class Product { [DataMember(Name = "productId", IsRequired = true, Order = 1)] public int ProductId { get; set; } [DataMember(Name = "name", IsRequired = true, Order = 2)] public string Name { get; set; } public decimal Price { get; set; } [DataMember(Name = "createTime", IsRequired = true, Order = 3)] public DateTime CreateTime { get; set; } public static List<Product> GetProducts() { List<Product> products = new List<Product>(); for (int i = 0; i < 5; i++) { products.Add(new Product { ProductId = i, Name = "name: " + i.ToString().PadLeft(4, '0'), Price = i * 100, CreateTime = DateTime.Now.AddDays(-i) }); } return products; } } }
2、演示 json 的序列化和反序列化,以及如何解析 json 字串
Communication/Serializer/Json.xaml.cs
/* * 演示 json 的序列化和反序列化,以及如何解析 json 字串 * * 1、通過 DataContractJsonSerializer 做 json 的序列化和反序列化 * 2、通過 JsonObject 和 JsonArray 解析 json 字串 */ using System; using System.Collections.Generic; using System.IO; using System.Runtime.Serialization; using System.Runtime.Serialization.Json; using System.Text; using Windows.Data.Json; using Windows.UI.Xaml.Controls; using Windows.UI.Xaml.Navigation; namespace XamlDemo.Communication.Serializer { public sealed partial class Json : Page { private string _jsonString = ""; public Json() { this.InitializeComponent(); } protected override void OnNavigatedTo(NavigationEventArgs e) { SerializeJson(); DeserializeJson(); ParseJson(); } private void SerializeJson() { // 需要序列化為 json 的物件 List<Product> products = Product.GetProducts(); // 序列化為 json 時,定義日期型別的字串格式 DataContractJsonSerializerSettings settings = new DataContractJsonSerializerSettings(); settings.DateTimeFormat = new DateTimeFormat("yyyy-MM-dd HH:mm:ss"); // 例項化 DataContractJsonSerializer 物件,用於 json 的序列化和反序列化 DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(List<Product>), settings); using (MemoryStream ms = new MemoryStream()) { // DataContractJsonSerializer.WriteObject() - 序列化 serializer.WriteObject(ms, products); var bytes = ms.ToArray(); _jsonString = Encoding.UTF8.GetString(bytes, 0, bytes.Length); lblMsg.Text = _jsonString; } } private void DeserializeJson() { // 反序列化時,定義日期型別的字串格式 DataContractJsonSerializerSettings settings = new DataContractJsonSerializerSettings(); settings.DateTimeFormat = new DateTimeFormat("yyyy-MM-dd HH:mm:ss"); // 例項化 DataContractJsonSerializer 物件,用於 json 的序列化和反序列化 DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(List<Product>), settings); using (MemoryStream ms = new MemoryStream()) { var bytes = Encoding.UTF8.GetBytes(_jsonString); ms.Write(bytes, 0, bytes.Length); ms.Position = 0; // 將流的當前位置定位到起點 // DataContractJsonSerializer.ReadObject() - 反序列化 var result = serializer.ReadObject(ms) as List<Product>; lblMsg.Text += Environment.NewLine; lblMsg.Text += "First Product Name: " + result[0].Name; } } private void ParseJson() { // JsonArray - json 陣列。可以通過 JsonArray.Parse() 將 json 字串解析為 JsonArray // JsonObject - json 物件。可以通過 JsonObject.Parse() 將 json 字串解析為 JsonObject JsonArray ja = JsonArray.Parse(_jsonString); JsonObject joFirst = ja[0].GetObject(); string firstProductName = joFirst["name"].GetString(); lblMsg.Text += Environment.NewLine; lblMsg.Text += "First Product Name: " + firstProductName; } } }
3、演示 xml 的序列化和反序列化,以及如何解析 xml 字串
Communication/Serializer/MyXmlWriter.cs
/* * 自定義 XmlWriter,用於去掉預設生成的 xmlns */ using System.Xml; namespace XamlDemo.Communication.Serializer { public class MyXmlWriter : XmlWriter { private XmlWriter _writer; private bool _ignoreEndAttrCall = false; public MyXmlWriter(XmlWriter writer) { _writer = writer; } /*關鍵程式碼開始*/ public override void WriteStartElement(string prefix, string localName, string ns) { if ((ns != null) && ns.StartsWith("http://schemas.datacontract.org")) { ns = null; } _writer.WriteStartElement(prefix, localName, ns); } public override void WriteStartAttribute(string prefix, string localName, string ns) { if ((ns == null) || (ns == "http://www.w3.org/2001/XMLSchema-instance")) { _ignoreEndAttrCall = true; return; } _writer.WriteStartAttribute(prefix, localName, ns); } public override void WriteEndAttribute() { if (_ignoreEndAttrCall) { _ignoreEndAttrCall = false; return; } _writer.WriteEndAttribute(); } public override void WriteString(string text) { if (_ignoreEndAttrCall) { return; } _writer.WriteString(text); } /*關鍵程式碼結束*/ #region 這部分程式碼保持原 XmlWriter 的邏輯不變 public override void Flush() { _writer.Flush(); } public override string LookupPrefix(string ns) { return _writer.LookupPrefix(ns); } public override void WriteBase64(byte[] buffer, int index, int count) { _writer.WriteBase64(buffer, index, count); } public override void WriteCData(string text) { _writer.WriteCData(text); } public override void WriteCharEntity(char ch) { _writer.WriteCharEntity(ch); } public override void WriteChars(char[] buffer, int index, int count) { _writer.WriteChars(buffer, index, count); } public override void WriteComment(string text) { _writer.WriteComment(text); } public override void WriteDocType(string name, string pubid, string sysid, string subset) { _writer.WriteDocType(name, pubid, sysid, subset); } public override void WriteEndDocument() { _writer.WriteEndDocument(); } public override void WriteEndElement() { _writer.WriteEndElement(); } public override void WriteEntityRef(string name) { _writer.WriteEntityRef(name); } public override void WriteFullEndElement() { _writer.WriteFullEndElement(); } public override void WriteProcessingInstruction(string name, string text) { _writer.WriteProcessingInstruction(name, text); } public override void WriteRaw(string data) { _writer.WriteRaw(data); } public override void WriteRaw(char[] buffer, int index, int count) { _writer.WriteRaw(buffer, index, count); } public override void WriteStartDocument(bool standalone) { _writer.WriteStartDocument(standalone); } public override void WriteStartDocument() { _writer.WriteStartDocument(); } public override WriteState WriteState { get { return _writer.WriteState; } } public override void WriteSurrogateCharEntity(char lowChar, char highChar) { _writer.WriteSurrogateCharEntity(lowChar, highChar); } public override void WriteWhitespace(string ws) { _writer.WriteWhitespace(ws); } #endregion } }
Communication/Serializer/Xml.xaml.cs
/* * 演示 xml 的序列化和反序列化,以及如何解析 xml 字串 * * 1、通過 DataContractSerializer 做 xml 的序列化和反序列化 * 2、通過 XLinq(linq to xml)解析 xml 字串,以及對 xml 做 crud 操作 * * 關於 xlinq 參見:http://www.cnblogs.com/webabcd/archive/2007/10/26/938122.html */ using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Runtime.Serialization; using System.Text; using System.Xml; using System.Xml.Linq; using Windows.UI.Xaml.Controls; using Windows.UI.Xaml.Navigation; namespace XamlDemo.Communication.Serializer { public sealed partial class Xml : Page { private string _xmlStringWithoutXmlns = ""; private string _xmlStringWithXmlns = ""; public Xml() { this.InitializeComponent(); } protected override void OnNavigatedTo(NavigationEventArgs e) { SerializeXml(); DeserializeXml(); ParseXml(); } private void SerializeXml() { // 需要序列化為 xml 的物件 List<Product> products = Product.GetProducts(); // 例項化 DataContractSerializer 物件,用於 xml 的序列化和反序列化,可以指定根節點的名稱 DataContractSerializer serializer = new DataContractSerializer(typeof(List<Product>), "root", ""); // 序列化,同時去掉多餘的 xmlns using (MemoryStream ms = new MemoryStream()) { // XmlWriterSettings - 用於配置 XmlWriter XmlWriterSettings settings = new XmlWriterSettings { Indent = true, IndentChars = "\t", NewLineChars = "\n", Encoding = Encoding.UTF8 }; settings.OmitXmlDeclaration = true; // 是否省略掉 xml 宣告 // 通過自定義 XmlWriter(參見:MyXmlWriter.cs)的方式,來去掉全部 xml 名稱空間 XmlWriter xmlWriter = MyXmlWriter.Create(ms, settings); MyXmlWriter myXmlWriter = new MyXmlWriter(xmlWriter); // DataContractSerializer.WriteObject() - 序列化 serializer.WriteObject(myXmlWriter, products); xmlWriter.Flush(); xmlWriter.Dispose(); var bytes = ms.ToArray(); _xmlStringWithoutXmlns = Encoding.UTF8.GetString(bytes, 0, bytes.Length); /* * 通過 XmlWriter 序列化的結果都具有相應編碼的 preamble * 比如如果序列化成 utf-8 編碼的 xml 字串,則對應的 preamble 為 3 個位元組:EF(239), BB(187), BF(191) * preamble 出現在字串的頭部 * 如果直接 WriteObject(MemoryStream, obj),則不會出現 preamble,但是就沒辦法通過自定義 XmlWriter 來去掉 xmlns 了 */ // 去掉 utf-8 的 preamble _xmlStringWithoutXmlns = TrimPreamble(_xmlStringWithoutXmlns, Encoding.UTF8); } lblMsg.Text = _xmlStringWithoutXmlns; // 序列化,結果不會出現 preamble,但是 xmlns 都會被保留 using (MemoryStream ms = new MemoryStream()) { serializer.WriteObject(ms, products); var bytes = ms.ToArray(); _xmlStringWithXmlns = Encoding.UTF8.GetString(bytes, 0, bytes.Length); } } private void DeserializeXml() { // 例項化 DataContractSerializer 物件,用於 xml 的序列化和反序列化,可以指定根節點的名稱 DataContractSerializer serializer = new DataContractSerializer(typeof(List<Product>), "root", ""); using (MemoryStream ms = new MemoryStream()) { var bytes = Encoding.UTF8.GetBytes(_xmlStringWithXmlns); ms.Write(bytes, 0, bytes.Length); ms.Seek(0, SeekOrigin.Begin); // 將流的當前位置定位到起點 // DataContractSerializer.ReadObject() - 反序列化 var result = serializer.ReadObject(ms) as List<Product>; lblMsg.Text += Environment.NewLine; lblMsg.Text += "First Product Name: " + result[0].Name; } } /// <summary> /// 通過 xlinq 解析 xml /// 注意 xml 字串不能有 preamble,否則解析失敗 /// 關於用 xlinq 對 xml 做 crud 操作,請參見:http://www.cnblogs.com/webabcd/archive/2007/10/26/938122.html /// </summary> private void ParseXml() { XDocument document = XDocument.Parse(_xmlStringWithoutXmlns); var products = from p in document.Root.Elements("product") select new Product { ProductId = int.Parse(p.Element("productId").Value), Name = p.Element("name").Value }; lblMsg.Text += Environment.NewLine; lblMsg.Text += "First Product Name: " + products.First().Name; } /// <summary> /// 去掉指定字串的指定編碼的 preamble /// </summary> public string TrimPreamble(string value, Encoding encoding) { if (string.IsNullOrEmpty(value)) return value; var bytes = encoding.GetPreamble(); string preamble = encoding.GetString(bytes, 0, bytes.Length); if (value.StartsWith(preamble)) value = value.Remove(0, preamble.Length); return value; } } }
4、演示 rss/atom 的解析
Communication/Serializer/RssAtom.xaml.cs
/* * 演示 rss/atom 的解析 * * 注: * 1、AtomPub: 利用 HTTP 方法(post, get, put, delete)的用於 crud web resources 的協議,其全稱為 Atom Publishing Protocol * 2、Windows.Web.AtomPub.AtomPubClient - 封裝了對 AtomPub 協議的實現 */ using System; using Windows.UI.Xaml; using Windows.UI.Xaml.Controls; using Windows.Web.Syndication; namespace XamlDemo.Communication.Serializer { public sealed partial class RssAtom : Page { public RssAtom() { this.InitializeComponent(); this.Loaded += Rss_Loaded; } async void Rss_Loaded(object sender, RoutedEventArgs e) { Uri rssUri = new Uri("http://feed.cnblogs.com/blog/u/18098/rss"); // SyndicationClient - 用於解析 rss/atom 的類 SyndicationClient client = new SyndicationClient(); // 是否繞過快取,即請求時是否增加頭 Pragma: no-cache client.BypassCacheOnRetrieve = true; // 設定 http 頭 client.SetRequestHeader("User-Agent", "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; WOW64; Trident/6.0)"); lblMsg.Text = "downloading feed: " + rssUri.ToString(); lblMsg.Text += Environment.NewLine; try { // 獲取資料 SyndicationFeed feed = await client.RetrieveFeedAsync(rssUri); ISyndicationText title = feed.Title; lblMsg.Text += "feed title: " + title.Text; lblMsg.Text += Environment.NewLine; lblMsg.Text += "items count: " + feed.Items.Count; lblMsg.Text += Environment.NewLine; foreach (SyndicationItem item in feed.Items) { lblMsg.Text += "item title: " + item.Title.Text; lblMsg.Text += Environment.NewLine; } } catch (Exception ex) { lblMsg.Text += Environment.NewLine; // 將 errCode 轉換為 SyndicationErrorStatus 列舉 SyndicationErrorStatus status = SyndicationError.GetStatus(ex.HResult); lblMsg.Text += status.ToString(); lblMsg.Text += Environment.NewLine; lblMsg.Text += ex.ToString(); } } } }
OK
[原始碼下載]