WebAPi添加常用扩展方法及思维发散

简介:

前言

在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模式下进行,不太肯定这样的测试是否严谨和正确,欢迎大家批评)。






本文转自Jeffcky博客园博客,原文链接:http://www.cnblogs.com/CreateMyself/p/5972214.html,如需转载请自行联系原作者

目录
相关文章
|
4月前
|
设计模式
二十三种设计模式全面解析-解密职责链模式:请求处理的设计艺术
二十三种设计模式全面解析-解密职责链模式:请求处理的设计艺术
|
4月前
|
设计模式 API 数据格式
二十三种设计模式全面解析-适配器模式:代码的奇迹之桥,连接你的世界!
二十三种设计模式全面解析-适配器模式:代码的奇迹之桥,连接你的世界!
|
4月前
|
设计模式 算法 Java
二十三种设计模式全面解析-当你的代码需要多种算法时,策略模式是你的救星!
二十三种设计模式全面解析-当你的代码需要多种算法时,策略模式是你的救星!
|
10月前
|
设计模式 SQL 开发框架
【Java设计模式 面向对象设计思想】六 再谈MVC贫血模式与DDD领域驱动开发
【Java设计模式 面向对象设计思想】六 再谈MVC贫血模式与DDD领域驱动开发
222 0
ABP框架学习之正面硬钢(二)
本文介绍另一种学习ABP框架的方法,该方法为正面硬钢学习法。。。 我们不去官网下载模板,直接引用DLL,直接使用。
ABP框架学习之正面硬钢(二)
|
前端开发 API
ABP框架学习之正面硬钢
本文介绍另一种学习ABP框架的方法,该方法为正面硬钢学习法。。。 我们不去官网下载模板,直接引用DLL,直接使用。
ABP框架学习之正面硬钢
|
Java Scala
教你利用Lambda将代码化繁为简 | 带你学《Java面向对象编程》之八十六
有没有觉得你的代码越来越繁琐呢?为了简化代码,JDK1.8推出了支持函数式编程的Lambda表达式。本节简单介绍了Lambda表达式的一些基本信息。
|
设计模式 Java
一起来看引用与现实的邂逅 | 带你学《Java面向对象编程》之二十二
本节通过三则分析为读者介绍了类关联结构、类自身关联等逻辑与合成设计模式的概念,带读者去理解类的灵活性。
一起来看引用与现实的邂逅    | 带你学《Java面向对象编程》之二十二
|
Java C++
保守VS开放?看清封装对象属性 | 带你学《Java面向对象编程》之四
高楼万丈,起于平地。本节通过对比正反几个实例剖析了封装对象属性的必要性,介绍了进行封装的基本原则。
保守VS开放?看清封装对象属性   |  带你学《Java面向对象编程》之四
|
SQL C# 数据安全/隐私保护
一起谈.NET技术,由扩展方法引申出的编程思维
  1. Helper大爆炸   .NET Framework为我们提供了丰富的类库,但是这并不是万能地,在大部分的时间,我们都需要为我们的项目特殊定制我们的通用类库。   常常,我们都可以构造一个类,类里封装一些方法。
1049 0