Json
涉及命名空间
using System.IO;
using System.Net;
using System.Runtime.Serialization.Json;
using Newtonsoft.Json;
序列化、反序列化、Post/Get方法
public class JsonOperation
{
/// <summary>
/// 序列化对象成JSON
/// </summary>
/// <param name="item"></param>
/// <returns></returns>
public static string ObjectSerialize(Object item)
{
DataContractJsonSerializer serializer = new DataContractJsonSerializer(item.GetType());
using (MemoryStream ms = new MemoryStream())
{
serializer.WriteObject(ms, item);
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.Append(Encoding.UTF8.GetString(ms.ToArray()));
return stringBuilder.ToString();
}
}
/// <summary>
/// JSON反序列化
/// </summary>
public static T JsonDeserialize<T>(string jsonString)
{
DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(T));
using (MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(jsonString)))
{
T obj = (T)ser.ReadObject(ms);
return obj;
}
}
/// <summary>
/// post方法
/// </summary>
/// <param name="url">地址</param>
/// <param name="json">json对象</param>
/// <param name="resultValue">返回的string类型的JSON字符串</param>
/// <returns></returns>
public static bool PostJson(string url, string json, out string resultValue, out string errMsg)
{
errMsg = "";
// 创建一个HTTP请求
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
resultValue = "";
request.Method = "POST";// Post请求方式
request.ContentType = "application/json";// 内容类型
// 将Json字符串转化为字节
byte[] payload = System.Text.Encoding.UTF8.GetBytes(json);
request.ContentLength = payload.Length;// 设置请求的ContentLength
// 发送请求,获得请求流
Stream writer;
try
{
writer = request.GetRequestStream();// 获取用于写入请求数据的Stream对象
}
catch (Exception)
{
writer = null;
errMsg = "连接服务器失败!";
return false;
}
writer.Write(payload, 0, payload.Length);// 将请求参数写入流
writer.Close();
// strValue为http响应所返回的字符流
HttpWebResponse response = null;
Stream stream = null;
StreamReader myStreamReader = null;
try
{
response = (HttpWebResponse)request.GetResponse();// 获得响应流
stream = response.GetResponseStream();
myStreamReader = new StreamReader(stream, Encoding.UTF8);
resultValue = myStreamReader.ReadToEnd();
return true;
}
catch (WebException ex)
{
response = ex.Response as HttpWebResponse;
errMsg = "调用PostJson方法异常:" + ex.Message;
return false;
}
finally
{
if (stream != null)
{
stream.Close();
stream.Dispose();
}
if (myStreamReader != null)
{
myStreamReader.Close();
myStreamReader.Dispose();
}
if (response != null)
{
response.Close();
}
}
}
/// <summary>
/// get方法
/// </summary>
/// <param name="url">地址</param>
/// <param name="resultValue">返回的string类型的JSON字符串</param>
/// <returns></returns>
public static bool GetJson(string url, out string resultValue, out string errMsg)
{
errMsg = "";
resultValue = "";
Encoding encoding = Encoding.UTF8;
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
request.Method = "GET";
request.Accept = "text/html, application/xhtml+xml, */*";
request.ContentType = "application/json";
HttpWebResponse response = null;
try
{
response = (HttpWebResponse)request.GetResponse();
using (StreamReader reader = new StreamReader(response.GetResponseStream(), Encoding.UTF8))
{
resultValue = reader.ReadToEnd();
}
return true;
}
catch (Exception e)
{
errMsg = "调用GetJson方法异常:" + e.Message;
return false;
}
finally
{
if (response != null)
{
response.Close();
}
}
}
}
其中,using Newtonsoft.Json 需要引用 Newtonsoft.Json.dll。在进行Json格式数据传输时,通常涉及到:DataContractJsonSerializer、JavaScriptSerializer 和 Json.Net。Json.Net 即 Newtonsoft.Json,非微软类库,开源的世界级Json操作类库,性能以及通用性较好。
50% faster than DataContractJsonSerializer, and 250% faster than JavaScriptSerializer
详细信息参考:Json.Net;
利用 Json.Net 序列化/反序列化
/// <summary>
/// 序列化对象成JSON
/// </summary>
public static string SerializeByJsonNet(Object item)
{
// JsonSerializerSettings 序列化配置
// Formatting 格式配置
return JsonConvert.SerializeObject(item);
}
/// <summary>
/// JSON反序列化
/// </summary>
public static T DeserializeByJsonNet<T>(string jsonString)
{
// JsonSerializerSettings 序列化配置
return JsonConvert.DeserializeObject<T>(jsonString);
}
序列化时,指定字段:[JsonProperty],忽略字段:[JsonIgnore]
也可以通过如下辅助类,通过传入props数组指定或忽略某些字段
/// <summary>
/// Summary description for LimitPropsContractResolver
/// </summary>
public class LimitPropsContractResolver : DefaultContractResolver
{
string[] props = null;
bool retain;
/// <summary>
/// 构造函数
/// </summary>
/// <param name="props">传入的属性数组</param>
/// <param name="retain">true:表示props是需要保留的字段 false:表示props是要排除的字段</param>
public LimitPropsContractResolver(string[] props, bool retain = true)
{
//指定或剔除序列化属性的清单
this.props = props;
this.retain = retain;
}
protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization)
{
IList<JsonProperty> list = base.CreateProperties(type, memberSerialization);
//只[保留或剔除]清单有列出的属性
return list.Where(p => {
if (retain)
{
return props.Contains(p.PropertyName);
}
else
{
return !props.Contains(p.PropertyName);
}
}).ToList();
}
}
调用方式如下
var jSetting = new JsonSerializerSettings {
NullValueHandling = NullValueHandling.Ignore
};
jSetting.ContractResolver = new LimitPropsContractResolver(props, false);
return JsonConvert.SerializeObject(item, Formatting.None, jSetting);
若待序列化对象包含DateTime类型字段属性时请用该方法
public static string SerializeWithDateTime(object data, string DateTimeFormats = "yyyy-MM-dd HH:mm:ss")
{
var timeConverter = new Newtonsoft.Json.Converters.IsoDateTimeConverter {
DateTimeFormat = DateTimeFormats
};
return JsonConvert.SerializeObject(data, Formatting.Indented, timeConverter);
}
序列化 Dictionary<> 或 Hashtable、DataTable 时,推荐使用 Json.Net。否则,json 字符串格式有问题
// Json.Net
{"beijing":"001","shanghai":"002"}
// DataContractJsonSerializer
[{"Key":"beijing","Value":"001"},{"Key":"shanghai","Value":"002"}]
关于 Json.Net 的其他用法,具体参考:Newtonsoft.Json的高级用法;
除此之外,还可以用 Linq to Json 定向解析需要的数据,实现快速查询、修改和创建 Json 对象。
JObject:用来生成一个JSON对象,简单来说就是生成”{}”
JArray:用来生成一个JSON数组,也就是”[]”
JProperty:用来生成一个JSON数据,格式为key/value的值
深入详细信息参见:Querying JSON with LINQ;
Xml
涉及命名空间
using System.IO;
using System.Xml;
using System.Xml.Serialization;
using System.Xml.Linq;
using System.Xml.XPath;
对象和XML字符串相互转化
/// <summary>
/// UTF8字节数组 ---> 字符串
/// </summary>
private static string UTF8BytesToString(byte[] bytes)
{
UTF8Encoding encoding = new UTF8Encoding();
return (encoding.GetString(bytes));
}
/// <summary>
/// 字符串 ---> UTF8字节数组
/// </summary>
private static byte[] StringToUTF8Bytes(String pXmlString)
{
UTF8Encoding encoding = new UTF8Encoding();
return (encoding.GetBytes(pXmlString));
}
/// <summary>
/// 数据对象转换成XML字符串
/// </summary>
private static string SerializeObject(object obj, Type type)
{
string XmlizedStr = string.Empty;
MemoryStream ms = null;
XmlTextWriter xtw = null;
try
{
ms = new MemoryStream();
xtw = new XmlTextWriter(ms, Encoding.UTF8);
XmlSerializer xs = new XmlSerializer(type);
xs.Serialize(xtw, obj);
ms = (MemoryStream)xtw.BaseStream;
XmlizedStr = UTF8BytesToString(ms.ToArray());
return XmlizedStr;
}
catch (Exception ex)
{
return "";
}
finally
{
// 释放资源
if (xtw != null)
{
xtw.Close();
ms.Close();
ms.Dispose();
}
}
}
/// <summary>
/// xml字符串转换数据对象
/// </summary>
private static object DeserializeObject(string XmlizedStr, Type type)
{
MemoryStream ms = null;
XmlTextWriter xtw = null;
try
{
XmlSerializer xs = new XmlSerializer(type);
ms = new MemoryStream(StringToUTF8Bytes(XmlizedStr));
xtw = new XmlTextWriter(ms, Encoding.UTF8);
return xs.Deserialize(ms);
}
catch (Exception ex)
{
return null;
}
finally
{
// 释放资源
if (xtw != null)
{
xtw.Close();
ms.Close();
ms.Dispose();
}
}
}
Internet
涉及命名空间
using System.Net;
using System.Net.Sockets;
// 方法1:Net2.0新增类库
using System.Net.NetworkInformation;
// 方法2:外部方法
using System.Runtime.InteropServices;
测试网络连通性、端口是否正常
/// <summary>
/// 获取主机名
/// </summary>
public static string GetHostname()
{
return System.Net.Dns.GetHostName();
}
/// <summary>
/// 主机名 ---> IP
/// </summary>
public static string GetIpByHostname(string hostname)
{
if (string.IsNullOrWhiteSpace(hostname)) {
return "";
}
try
{
System.Net.IPHostEntry host = System.Net.Dns.GetHostEntry(hostname);
return host.AddressList.GetValue(0).ToString();
}
catch (Exception ex)
{
return null;
}
}
/// <summary>
/// IP ---> 主机名
/// </summary>
public static string GetHostnameByIp(string ip)
{
if (string.IsNullOrWhiteSpace(ip)) {
return "";
}
try
{
System.Net.IPHostEntry host = System.Net.Dns.GetHostEntry(ip);
return host.HostName;
}
catch (Exception ex)
{
return null;
}
}
/// <summary>
/// 只是测试网络连通性,不能检测端口
/// (C#实现ping的基本方法)
/// </summary>
/// 方法1 基于TCP/IP协议访问 ///
public static bool PingIpOrDomainName(string strIpOrDName)
{
try
{
Ping pingSender = new Ping();
PingOptions pingOpts = new PingOptions();
pingOpts.DontFragment = true;
int intTimeout = 60;
string data = "";
byte[] buffer = Encoding.UTF8.GetBytes(data);
PingReply pingReply = pingSender.Send(strIpOrDName, intTimeout, buffer, pingOpts);
string strInfo = pingReply.Status.ToString();
if (strInfo == "Success")
{
return true;
}
else
{
return false;
}
}
catch (Exception)
{
return false;
}
}
/// 方法2 ///
public static bool PingIpOrDomainName2(string strIpOrDName)
{
int Description = 0;
return InternetGetConnectedState(Description, 0);
}
[DllImport("wininet.dll")]
private extern static bool InternetGetConnectedState(int Description, int ReservedValue);
/// <summary>
/// 具体到某个端口是否联通的
/// (C#实现telnet的基本方法)
/// </summary>
public static bool ConnectTest(string ip, int port)
{
IPAddress ipAddr = IPAddress.Parse(ip);
try
{
IPEndPoint point = new IPEndPoint(ipAddr, port);
Socket sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
sock.Connect(point);
Console.WriteLine("连接端口{0}成功!", point);
//sock.Disconnect(true);
sock.Shutdown(SocketShutdown.Both);
sock.Close();
sock = null;
}
catch (SocketException e)
{
if (e.ErrorCode != 10061)
{
Console.WriteLine(e.Message);
}
return false;
}
return true;
}
直接在命令行窗口测试亦可
ping IP地址
telnet IP地址 Port
Cache
业务中需要在前端缓存卡图片,顺带了解下几种缓存的实现方式
首先需要引用命名空间
using System.Runtime.Caching;
using System.Windows.Threading;
(1)字典集 + 定时器
/// <summary>
/// 基于字典集的缓存帮助类
/// </summary>
public class CacheHelper
{
// 缓存字典集
private static IDictionary<string, object> cacheDic = new Dictionary<string, object>();
// key-->Timer
private static IDictionary<string, object> keyToTimerDict = new Dictionary<string, object>();
// Timer-->key
private static IDictionary<object, object> timerToKeyDict = new Dictionary<object, object>();
public static bool Contains(string _key)
{
return cacheDic.ContainsKey(_key);
}
public static void Set(string _key, Object obj, TimeSpan? expireTimeSpan = null)
{
if (string.IsNullOrWhiteSpace(_key))
{
throw new ArgumentException("Set||key不允许为空");
}
cacheDic[_key] = obj;
if (expireTimeSpan.HasValue)
{
DispatcherTimer timer = new DispatcherTimer();
keyToTimerDict.Add(_key, timer);
timerToKeyDict.Add(timer, _key);
timer.Tick += new EventHandler(RecycleKey);
timer.Interval = expireTimeSpan.Value;
timer.Start();
}
}
public static Object Get(string _key)
{
if (string.IsNullOrWhiteSpace(_key))
{
throw new ArgumentException("Get||key不允许为空");
}
if (Contains(_key))
{
return cacheDic[_key];
}
return null;
}
public static void Remove(string _key)
{
if (string.IsNullOrWhiteSpace(_key))
{
throw new ArgumentException("Remove||key不允许为空");
}
if (Contains(_key))
{
cacheDic.Remove(_key);
if (keyToTimerDict.ContainsKey(_key))
{
keyToTimerDict.Remove(_key);
RemoveTimer((DispatcherTimer)timerToKeyDict[_key]);
}
}
}
private static void RemoveTimer(DispatcherTimer _timer)
{
if (timerToKeyDict.ContainsKey(_timer))
{
timerToKeyDict.Remove(_timer);
_timer.Stop();
_timer = null;
}
}
private static void RecycleKey(object o, EventArgs e)
{
string key = (string)timerToKeyDict[(DispatcherTimer)o];
Remove(key);
}
public static void RemoveAll()
{
foreach (string key in cacheDic.Keys)
{
if (keyToTimerDict.ContainsKey(key))
{
keyToTimerDict.Remove(key);
RemoveTimer((DispatcherTimer)timerToKeyDict[key]);
}
}
cacheDic.Clear();
}
}
(2)MemoryCache + CachePolicy
注意在get()前,先用Contains()检查键key是否存在。
/// <summary>
/// 基于系统MemoryCache的缓存帮助类
/// </summary>
public class MemoryCacheHelper
{
///内部锁对象
private static readonly object _lockerObj = new object();
public static bool Contains(string _key)
{
return MemoryCache.Default.Contains(_key);
}
/// <param name="expireTimeSpan">相对到期时间段</param>
/// <param name="expireDateTime">绝对到期时间点</param>
public static void Set(string _key, Object obj,
TimeSpan? expireTimeSpan = null, DateTime? expireDateTime = null)
{
if (string.IsNullOrWhiteSpace(_key))
{
throw new System.ArgumentException("Set||key不能为空!");
}
CacheItem item = new CacheItem(_key, obj);
CacheItemPolicy policy = CreateCachePolicy(expireTimeSpan, expireDateTime);
lock (_lockerObj)
{
MemoryCache.Default.Set(item, policy);
}
}
// Get前,先用Contains判断
public static T Get<T>(string _key)
{
if (string.IsNullOrWhiteSpace(_key))
{
throw new System.ArgumentException("Get||key不能为空!");
}
return (T)((object)MemoryCache.Default[_key]);
}
public static void Remove(string _key)
{
if (string.IsNullOrWhiteSpace(_key))
{
throw new System.ArgumentException("Remove||key不能为空!");
}
if (Contains(_key))
{
MemoryCache.Default.Remove(_key);
}
}
public static void RemoveAll()
{
while (MemoryCache.Default.GetCount() > 0L)
{
Remove(MemoryCache.Default.ElementAt(0).Key);
}
}
private static CacheItemPolicy CreateCachePolicy(TimeSpan? expireTimeSpan = null, DateTime? expireDateTime = null)
{
CacheItemPolicy policy = new CacheItemPolicy();
if (expireDateTime.HasValue)
{
policy.AbsoluteExpiration = expireDateTime.Value;
}
else if (expireTimeSpan.HasValue)
{
policy.SlidingExpiration = expireTimeSpan.Value;
}
policy.Priority = CacheItemPriority.Default;
return policy;
}
}
也可以直接使用系统自带的MemoryCache类。
对系统自带的缓存策略CacheItemPolicy的几个属性了解下
/// <summary>
/// 缓存策略
/// </summary>
public class CacheItemPolicy
{
// 摘要: 获取或设置一个值,该值指示是否应在指定持续时间过后逐出某个缓存项
// 返回结果:在逐出某个缓存项之前必须经过的时间段,默认Caching.ObjectCache.InfiniteAbsoluteExpiration
public DateTimeOffset AbsoluteExpiration { get; set; }
// 摘要: 获取或设置一个值,该值指示如果某个缓存项在给定时段内未被访问,是否应被逐出
// 返回结果:一个时段,必须在此时段内访问某个缓存项,否则将从内存中逐出该缓存项。默认Caching.ObjectCache.NoSlidingExpiration
public TimeSpan SlidingExpiration { get; set; }
// 摘要: 委托引用,从缓存中移除某个项后调用该委托
public CacheEntryUpdateCallback UpdateCallback { get; set; }
// 摘要: 委托引用,从缓存中移除某个缓存项之前调用该委托
public CacheEntryRemovedCallback RemovedCallback { get; set; }
}
给出实际使用时的几种形式,仅供参考
public class CacheOperation
{
// RVC.SLBase:前端框架缓存(随当前运行程序的存在周期)
public static void SetCacheWay(string key, Object obj, TimeSpan span)
{
CacheHelper.Set(key, obj, span);
}
public static Object GetCacheWay(string key)
{
return CacheHelper.Get(key);
}
// RVC.MVCBase:内存缓存-1
public static void SetCacheWay1(string key, Object obj, int Cache_Minutes)
{
MemoryCache cache = MemoryCache.Default;
cache[key] = obj;
CacheItemPolicy policy = new CacheItemPolicy();
policy.AbsoluteExpiration = DateTimeOffset.Now.AddMinutes(Cache_Minutes);
cache.Add(key, obj, policy);
}
public static Object GetCacheWay1(string key)
{
MemoryCache cache = MemoryCache.Default;
return cache[key];
}
// RVC.MVCBase:内存缓存-2
// 高级版的MemoryCache实现
public static void SetCacheWay2(string key, Object obj,
TimeSpan? expireTimeSpan = null, DateTime? expireDateTime = null)
{
MemoryCacheHelper.Set(key, obj, expireTimeSpan, expireDateTime);
}
public static Object GetCacheWay2(string key)
{
if (MemoryCacheHelper.Contains(key))
{
return MemoryCacheHelper.Get<object>(key);
}
else
{
return null;
}
}
}
其中,对于如下特例,实际生命时长只有5秒:绝对到期时间优先级高于相对到期时间
CacheOperation.SetCacheWay2("KEY", "VALUE",
new TimeSpan(0, 0, 60), DateTime.Now.AddSeconds(5));
关于 HttpContext的问题,参见:https://www.cnblogs.com/wjcx-sqh/p/11093956.html
Timer
工作中对定时器的应用颇多,对几种定时器做简单的梳理
/// 线程池执行
// System.Threading.Timer
private static System.Threading.Timer _timer1 =
new System.Threading.Timer(ExecuteAction1, null, 0, 2000);
private static void ExecuteAction1(object sender)
{
Console.WriteLine("ExecuteAction1():[{0}] " + DateTime.Now.ToString(), Thread.CurrentThread.ManagedThreadId);
}
/// 线程池执行
// System.Timers.Timer
private static System.Timers.Timer _timer2 =
new System.Timers.Timer();
_timer2.Interval = 1000;
_timer2.Elapsed += new ElapsedEventHandler(ExecuteAction2);
private static void ExecuteAction2(object sender, ElapsedEventArgs e)
{
Console.WriteLine("ExecuteAction2():[{0}] " + DateTime.Now.ToString(), Thread.CurrentThread.ManagedThreadId);
}
/// 最宜用于页面定时(Tick事件在主线程中执行)
// System.Windows.Threading.DispatcherTimer
private static System.Windows.Threading.DispatcherTimer _timer3 =
new System.Windows.Threading.DispatcherTimer();
_timer3.Interval = TimeSpan.FromSeconds(2);
_timer3.Tick += new EventHandler(ExecuteAction3);
private static void ExecuteAction3(object sender, EventArgs e)
{
Console.WriteLine("ExecuteAction3():" + DateTime.Now.ToString());
}
/// 最宜用于Windows窗体应用程序中,并且必须在窗口中使用(事件线程与主窗体的线程是同一个)
// System.Windows.Forms.Timer
private static System.Windows.Forms.Timer _timer4 =
new System.Windows.Forms.Timer();
_timer4.Interval = 2000;
_timer4.Tick += new EventHandler(ExecuteAction4);
private static void ExecuteAction4(object sender, EventArgs e)
{
Console.WriteLine("ExecuteAction4():" + DateTime.Now.ToString());
}
计时器
精确计算目标程序,特别是多线程程序的性能。
QueryPerformanceFrequency:从硬件的实时计算器获取主频频率
QueryPerformanceCounte:从硬件的实时计算器中获取当前计数值,实时计算器由硬件驱动和进程线程无关
public static class QueryPerformanceMethd
{
[DllImport("kernel32.dll")]
public extern static short QueryPerformanceCounter(ref long x);
[DllImport("kernel32.dll")]
public extern static short QueryPerformanceFrequency(ref long x);
}
关于具体使用可参见:https://www.cnblogs.com/Van-Bumblebee/p/5483432.html
在定时前先调用QueryPerformanceFrequency()函数获得机器内部计时器的时钟频率,再前后分别调用QueryPerformanceCounter(),利用两次计数之差和时钟频率,可计算出事件经历的精确时间。
在 C#中几种常见计时器,可供参考。