前言

在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) == );
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());

            string value = collection.Get();

            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 = ; i < ; i++)
{
string value = collection["张三"];
}
var time = stopWatch.ElapsedMilliseconds;
Console.WriteLine(time);
stopWatch.Stop(); var stopWatchDict = new Stopwatch();
stopWatchDict.Start();
for (int i = ; i < ; i++)
{
string value = dict["张三"];
}
var time1 = stopWatchDict.ElapsedMilliseconds;
Console.WriteLine(time1);
stopWatchDict.Stop();

如上我们迭代10亿次来看看二者在查找数据上有没有性能差异:

这里我们可以看到用NameValueCollection去获取数据时耗时48秒,而用Dictionary则耗时4秒,从此可以看出二者除了在添加数据上的差异还有在迭代查询数据时也有很大的性能差异。

总结

上述我们主要讲述WebAPi中添加常用可能会用到获取参数的扩展方法,同时也比较了NameValueCollection和Dictionary除了在添加数据上是否可以允许有重复项外而且在迭代数据上也有很大的性能差异(上述迭代在Release模式下进行,不太肯定这样的测试是否严谨和正确,欢迎大家批评)。

WebAPi添加常用扩展方法及思维发散的更多相关文章

  1. Javascript 常用扩展方法

    这篇文章纯粹是为了保存这些方法,供以后翻阅,其实一直保存在 evernote 里面,但觉得还是放到对的地方会好点. 现在收录的很少,希望以后会慢慢增多. 数组扩展 contains,remove 扩展 ...

  2. js常用扩展方法

    在日常的开发过程中,经常会碰到javaScript原生对象方法不够用的情况,所以经常会对javaScript原生方法进行扩展.下面就是在实际工作时,经常使用的一些方法,做一下记录,有需要的可以拿去. ...

  3. C#常用扩展方法

    /// <summary> /// 转换 /// </summary> public static class ConversionHelper { #region 数据格式转 ...

  4. 由ASP.NET Core WebApi添加Swagger报错引发的探究

    缘起 在使用ASP.NET Core进行WebApi项目开发的时候,相信很多人都会使用Swagger作为接口文档呈现工具.相信大家也用过或者了解过Swagger,这里咱们就不过多的介绍了.本篇文章记录 ...

  5. .NET 扩展方法 (一)

    我还记得刚刚学编程的时候,老师经常会提到一句话:注意空指针.所以经常在某些“入口”位置,进行代码校验,空指针的判断就是其中的一项工作. string类型作为常用的数据类型,它在项目中出现的机率极高,所 ...

  6. 从扩展方法到匿名方法再到LINQ

    1.首先我们应该知道什么是扩展方法: 扩展方法使您能够向现有类型“添加”方法,而无需创建新的派生类型.重新编译或以其他方式修改原始类型. 扩展方法是一种特殊的静态方法,但可以像扩展类型上的实例方法一样 ...

  7. ASP.NET MVC学前篇之扩展方法、链式编程

    ASP.NET MVC学前篇之扩展方法.链式编程 前言 目的没有别的,就是介绍几点在ASP.NETMVC 用到C#语言特性,还有一些其他琐碎的知识点,强行的划分一个范围的话,只能说都跟MVC有关,有的 ...

  8. .NET 扩展方法 (二)

    上一篇随笔 .NET 扩展方法 (一) 已经对 扩展方法有了大致的介绍,这篇算是一个补充,让我们来看一下扩展方法的几个细节: 一.扩展方法具有继承性 当使用扩展方法扩展一个类型的时候,其也扩展了派生类 ...

  9. C#中this在扩展方法的应用

    给类添加扩展方法 1.定义一个类Service public class Service { private string _name; public string Name { get { retu ...

随机推荐

  1. jenkins 登录提示无效

    在自己电脑上的jenkins,有一段时间没有登录,jenkins 登录提示无效 <useSecurity>true</useSecurity>   修改成false <a ...

  2. 关于.9.png格式图片的制作与使用

    .9.png图片其实就是png格式图片,不过它比普通的png图片外围多了1px(像素)的边框,另外就是使用这种格式的图片可以实现背景自适应大小且不失真的效果. 制作使用步骤: 1.制作属于你自己的pn ...

  3. 2014 summer training总结篇

    还有一周暑期集训就要结束了,从7月份结束军训到现在一个多月的时间,收获也是有的只不过与之前预想的相比显得十分微薄. 无论是前两天的两场个人赛还是之前的组队赛自己始终是在ranklist的后半部分.一开 ...

  4. unison+inotify

    hostnamectl --static set-hostname tCentos 1.下载文件到/usr/local/srcocamlunisoninotify-tools 2.安装inotify- ...

  5. 【luogu】 P1880 石子合并

    原题原题原题原题原题 先贴上错误代码... ↓错误代码↓ #include <iostream> #include <cstdio> #include <cstring& ...

  6. viso

  7. advstringgrid笔记

    一下操作是在advstringgrid7.4.6.3版本下有效,advstringgrid控件名设置为 zy 一.属性设置 1.修改单元格内的值:zy.cells[col,row]='value'; ...

  8. Sql Server 2012新特性 Online添加非空栏位.

    我们都知道,Sql Server在一个数据量巨大的表中添加一个非空栏位是比较费心的,缺乏经验的DBA或是开发人员甚至可能鲁莽地直接添加导致阻塞相应业务,甚至可能因为资源欠缺造成实例的全局问题.当然这都 ...

  9. 一步步学习javascript基础篇(5):面向对象设计之对象继承(原型链继承)

    上一篇介绍了对象创建的几种基本方式,今天我们看分析下对象的继承. 一.原型链继承 1.通过设置prototype指向“父类”的实例来实现继承. function Obj1() { this.name1 ...

  10. ABP理论学习之Web API控制器(新增)

    返回总目录 本篇目录 介绍 AbpApiController基类 本地化 审计日志 授权 工作单元 其他 介绍 ABP通过Abp.Web.ApiNuget包集成了 ASP.NET Web API控制器 ...