WebAPi添加常用扩展方法及思维发散
2016-10-18 13:42
267 查看
前言
在WebAPi中我们通常需要得到请求信息中的查询字符串或者请求头中数据再或者是Cookie中的数据,如果需要大量获取,此时我们应该想到封装一个扩展类来添加扩展方法,从而实现简便快捷的获取。WebAPi常用扩展方法
(1)获取所有键值对
/// <summary> /// 获取所有键值 /// </summary> /// <param name="request"></param> /// <returns></returns> public static Dictionary<string, string> GetQueryStrings(this HttpRequestMessage request) { return request.GetQueryNameValuePairs().ToDictionary(k => k.Key, v => v.Value, StringComparer.OrdinalIgnoreCase); }
(2)获取单个key对应value
/// <summary> /// 获取单个键值 /// </summary> /// <param name="request"></param> /// <param name="key"></param> /// <returns></returns> 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)获取请求头中对应键值
/// <summary> /// 依据键获取请求头中值数据 /// </summary> /// <param name="request"></param> /// <param name="key"></param> /// <returns></returns> public static string GetHeader(this HttpRequestMessage request, string key) { IEnumerable<string> keys = null; if (!request.Headers.TryGetValues(key, out keys)) return null; return keys.First(); }
(4)获取Cookie中键值
/// <summary> /// 获取Cookie /// </summary> /// <param name="request"></param> /// <param name="cookieName"></param> /// <returns></returns> 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<string,string>,那Dictionary和NameValueCollection在获取参数时有什么区别呢?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 Dictionary<string, string> GetDict() { var dictionary = new Dictionary<string, string>(); 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秒,从此可以看出二者除了在添加数据上的差异还有在迭代查询数据时也有很大的性能差异。
总结
上述我们主要讲述WebAPi中添加常用可能会用到获取参数的扩展方法,同时也比较了NameValueCollection和Dictionary除了在添加数据上是否可以允许有重复项外而且在迭代数据上也有很大的性能差异(上述迭代在Release模式下进行,不太肯定这样的测试是否严谨和正确,欢迎大家批评)。相关文章推荐
- WebAPi添加常用扩展方法及思维发散
- Javascript数组常用方法[包含MS AJAX.NET的prototype扩展方法]示例
- Javascript数组常用方法[包含MS AJAX.NET的prototype扩展方法]示例
- 函数$的扩展,返回带有常用方法的HTML元素对象
- 常用的几个ForEach扩展,外送一个First方法
- c#扩展方法奇思妙用基础篇三:byte 常用扩展
- PowerPoint功能扩展的几个常用方法
- c#扩展方法奇思妙用基础篇三:byte 常用扩展
- C#3.0扩展方法是给现有类型添加一个方法
- 常用的几个ForEach扩展,外送一个First方法
- [转]ListView控件中几个常用的扩展方法
- 使用扩展方法和接口给对象添加“重置状态”功能
- 向C#的String类添加按字节截取字符串的扩展方法
- 向C#的String类添加按字节截取字符串的扩展方法
- 自备贴之:常用扩展方法如下
- 在Javascript中对String的一些方法扩展,实现常用的字符串处理。
- 地磅称量系统之(53)在封装对象的类库中实现包括IDataErrorInfo接口提供的所有方法和并且扩展对异常具有添加和删除功能的基本业务对象基类
- 向C#的String类添加按字节截取字符串的扩展方法
- c#扩展方法奇思妙用基础篇二:string 常用扩展
- iBatis为业务对象添加可分页方法,扩展方法,调用Oracle