WebAPi添加常用扩展方法及思维发散
WebAPi常用扩展方法
(1)获取所有键值对
////// 获取所有键值 /// /// ///public static Dictionary GetQueryStrings(this HttpRequestMessage request) { return request.GetQueryNameValuePairs().ToDictionary(k => k.Key, v => v.Value, StringComparer.OrdinalIgnoreCase); }
(2)获取单个key对应value
////// 获取单个键值 /// /// /// ///public static string GetQueryString(this HttpRequestMessage request, string key) { var queryStrings = request.GetQueryNameValuePairs(); if (queryStrings == null) return null; var match = queryStrings.FirstOrDefault(kv => string.Compare(kv.Key, key, true) == 0); if (string.IsNullOrEmpty(match.Value)) return null; return match.Value; }
注意:请不要告诉我用HttpContext.Current.Request.QueryString["key"]去获取键值,在WebHost模式下是可以的,但是在SelfHost模式下该对象是为空的。
(3)获取请求头中对应键值
////// 依据键获取请求头中值数据 /// /// /// ///public static string GetHeader(this HttpRequestMessage request, string key) { IEnumerable keys = null; if (!request.Headers.TryGetValues(key, out keys)) return null; return keys.First(); }
(4)获取Cookie中键值
////// 获取Cookie /// /// /// ///public static string GetCookie(this HttpRequestMessage request, string cookieName) { CookieHeaderValue cookie = request.Headers.GetCookies(cookieName).FirstOrDefault(); if (cookie != null) return cookie[cookieName].Value; return null; }
思维发散
我们知道在ASP.NET中获取请求参数值时用QueryString、在获取获取Web.config配置中值时、以及请求头中有时候会用到NameValueCollection,在上述中我们返回的是Dictionary
NameValueCollection
我们来看看其具体用法,在此类中添加对应数据并获取:
static NameValueCollection GetCollection() { var collection = new NameValueCollection(); collection.Add("张三", "博客园"); collection.Add("李四", "csdn"); collection.Add("李四", "51cto"); collection.Add("张三", "IBM"); return collection; }
进行打印:
var collection = GetCollection(); foreach (string key in collection.AllKeys) { Console.WriteLine(key); Console.WriteLine(collection[key]); }
从上可以看出,此时的键没有重复返回,但是此时每一个键会映射到一个字符串数组即里面存的是相同的键所对应的值。所以我们可以得出结论通过AllKeys属性来进行遍历NameValueCollection集合时此时返回的键是所有未重复的键。
此时我们若取某个不存在的键结果会是怎样呢?
Console.WriteLine(collection["xpy0928"] == null);
此时会打印出True。
基于此我们可以得出结论:
当在NameValueCollection集合中依据键去取值时,若有多个值被找到,此时则会返回以逗号隔开的字符串数组,若未找到则返回空。
接下来我们看看该集合的其他方法:
Console.WriteLine(collection.HasKeys()); Console.WriteLine(collection.GetKey(0)); string value = collection.Get(0); Console.WriteLine(value);
(1)第一个显示该集合中是否存在键值(返回True)。
(2)获取该集合的第一个键(返回张三)。
(3)获取第一键对应的值(返回博客园,IBM)。
上述都是关于判断键以及取键值的情况,当然里面还有添加和移除的方法,添加我们不必多说,我们来看看移除的方法。
collection.Remove("张三"); collection.Remove("xpy0928"); foreach (var key in collection.AllKeys) { Console.WriteLine(key); Console.WriteLine(collection[key]); }
当移除已存在的键时,此时则会删除该键对应的所有值,但是很有意思的是移除一个不存在的键时根本不会抛出异常。
Dictionary
接下来我们看看Dictionary。
static DictionaryGetDict() { var dictionary = new Dictionary (); dictionary.Add("张三", "博客园"); dictionary.Add("李四", "csdn"); dictionary.Add("王五", "51cto"); dictionary.Add("赵六", "IBM"); return dictionary; }
我们添加一项看看
var dict = GetDict(); dict.Add("张三", "博客园");
在字典中不能添加重复项。
至此,我们可以得出结论:在NameValueCollection与Dictionary上最主要的区别在于NameValueCollection可以添加重复项,而Dictionary不行。
当然在字典中去移除不存在的键也不会抛出异常,如下:
dict.Remove("xpy928");
接下来我们来看看二者在查找数据时是否有性能上的差异,我们在Release模式来进行操作。
var collection = GetCollection(); var dict = GetDict(); var stopWatch = new Stopwatch(); stopWatch.Start(); for (int i = 0; i < 100000000; i++) { string value = collection["张三"]; } var time = stopWatch.ElapsedMilliseconds; Console.WriteLine(time); stopWatch.Stop(); var stopWatchDict = new Stopwatch(); stopWatchDict.Start(); for (int i = 0; i < 100000000; i++) { string value = dict["张三"]; } var time1 = stopWatchDict.ElapsedMilliseconds; Console.WriteLine(time1); stopWatchDict.Stop();
如上我们迭代10亿次来看看二者在查找数据上有没有性能差异:
这里我们可以看到用NameValueCollection去获取数据时耗时48秒,而用Dictionary则耗时4秒,从此可以看出二者除了在添加数据上的差异还有在迭代查询数据时也有很大的性能差异。