前言

在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. React-native之持久化保存----AsyncStorage

    AsyncStorage AsyncStorage是一个简单的,未加密的,异步的,持久化,关键值存储系统,是全局的. iOS中存储类似于NSUserDefault,存储问plist文件存放在设备中. ...

  2. 客户端用javascript获取文件大小

    客户端用javascript获取文件大小 1 ie实现代码如下: <script type="text/javascript" language="javascri ...

  3. linux一句话轻松提权

    linux命令:‍ [b@fuckks~]$ printf "install uprobes /bin/sh" > exploit.conf; MODPROBE_OPTI** ...

  4. 第三方框架之ThinkAndroid 学习总结(一)

    ThinkAndroid是一个免费的开源的.简易的.遵循Apache2开源协议发布的Android开发框架,其开发宗旨是简单.快速的进行Android应用程序的开发,包含Android mvc.简易s ...

  5. sql编写将时间转换年月日 时分格式

    SELECT SUBSTRING(CONVERT(varchar(100),时间字段, 22),0,15) AS aa  FROM  表名

  6. VS快捷键总结(包括ReSharper)

    Shift+Alt+Enter 全屏显示代码Ctrl+E 最近文件列表Ctrl+B 转到定义Ctrl+Alt+B 转到继承类或接口处Ctrl+U 转到基类Ctrl+D 复制当前行或选定的块(Dupli ...

  7. 安卓刷机--fastboot线刷

    首先需要下载fastboot.exe,copy到system32文件夹下. 对于安卓系统的智能手机,同时按住开机键和音量减键,或手机连上电脑,输入adb reboot bootloader进入fast ...

  8. window下搭建c开发环境(GNU环境的安装)

    一.在windows平台上安装GNU环境 windows操作系统不自带GNU环境,如果需要开发跨平台的C语言程序,那么需要给windows安装GNU环境 windows下的两款GNU环境:MinGW和 ...

  9. Android安全开发之浅谈密钥硬编码

    Android安全开发之浅谈密钥硬编码 作者:伊樵.呆狐@阿里聚安全 1 简介 在阿里聚安全的漏洞扫描器中和人工APP安全审计中,经常发现有开发者将密钥硬编码在Java代码.文件中,这样做会引起很大风 ...

  10. 关于JQuery的一个Bug

    关于JQuery的什么问题了? .parents()这个方法与form放在一起有些不对 上码 <!DOCTYPE html> <html> <head> <m ...