重新想象 Windows 8 Store Apps (60) - 通信: 获取网络信息, 序列化和反序列化

本文涉及的产品
全局流量管理 GTM,标准版 1个月
云解析 DNS,旗舰版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
简介: 原文:重新想象 Windows 8 Store Apps (60) - 通信: 获取网络信息, 序列化和反序列化[源码下载] 重新想象 Windows 8 Store Apps (60) - 通信: 获取网络信息, 序列化和反序列化 作者:webabcd介绍重新想象 Windows 8 Sto...
原文: 重新想象 Windows 8 Store Apps (60) - 通信: 获取网络信息, 序列化和反序列化

[源码下载]


重新想象 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
[源码下载]

目录
打赏
0
0
0
0
213
分享
相关文章
|
2月前
|
【Azure App Service】在App Service for Windows上验证能占用的内存最大值
根据以上测验,当使用App Service内存没有达到预期的值,且应用异常日志出现OutOfMemory时,就需要检查Platform的设置是否位64bit。
48 11
计算机网络的常用的网络通信命令(Windows)
本文介绍了网络技术中常用的命令,如ping用于检测网络连通性,ipconfig查看TCP/IP配置,netstat监控网络状态,arp显示和修改ARP缓存,at安排任务执行,tracert追踪路由,以及nbtstat获取NetBIOS信息。
57 1
怎样利用 Windows XP实现网络统一关机
怎样利用 Windows XP实现网络统一关机
怎样利用 Windows XP实现网络统一关机
|
4月前
|
redis序列化数据时,如何包含clsss类型信息?
通过配置 `com.fasterxml.jackson.databind.ObjectMapper` 的 `enableDefaultTyping` 方法,可以使序列化后的 JSON 包含类信息。
62 2
[App Service for Windows]通过 KUDU 查看 Tomcat 配置信息
[App Service for Windows]通过 KUDU 查看 Tomcat 配置信息
【App Service for Windows】为 App Service 配置自定义 Tomcat 环境
【App Service for Windows】为 App Service 配置自定义 Tomcat 环境
【Azure App Service for Windows】 PHP应用出现500 : The page cannot be displayed because an internal server error has occurred. 错误
【Azure App Service for Windows】 PHP应用出现500 : The page cannot be displayed because an internal server error has occurred. 错误
【Azure App Service】.NET代码实验App Service应用中获取TLS/SSL 证书 (App Service Windows)
【Azure App Service】.NET代码实验App Service应用中获取TLS/SSL 证书 (App Service Windows)
【Azure App Service】Web Job 报错 UNC paths are not supported. Defaulting to Windows directory.
【Azure App Service】Web Job 报错 UNC paths are not supported. Defaulting to Windows directory.
【应用服务 App Service】App Service For Windows 如何挂载Storage Account File Share 示例
【应用服务 App Service】App Service For Windows 如何挂载Storage Account File Share 示例
AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等