本以为系列文章已经Over,突然记起来前面留了个大坑还没填,真是自己给自己挖坑。

这个坑就是:

(body 只能被读取一次)Only one thing can read the body
MVC和WebAPI之间的一个关键不同点在于MVC缓存请求主体(request body)。这意味着MVC的参数绑定可以反复从body中查找参数片断。然而,在WebAPI中,请求主体(HttpContent) 只能被读取一次,不被缓存,只能向前读取的流。这意味着parameter binding需要谨慎对待stream,除非在需要绑定参数的情况下,否则stream不能被读取。 以下的action方法想直接读取stream,因而导致WebAPI不能保证其拥有用于参数绑定的stream。
引自:

[译]WebAPI下的如何实现参数绑定


这也就意味着,凡是参数中含有实体类型的,这个实体只能获取一次。

话说园子里WebApi安全性的文章也不少了,可是这个坑少有人提,也不晓得为啥,只好自己走一个大弯路先。

本人所在公司目前用MVC开发,Api做安全验证的时候,是将验证的系统参数和数据一起打包成一个匿名类,在Attribute中做验证,是可行的。同样的方式,拿到WebApi中,就死活走不下去。因为在ActionFilterAttribute中用请求的输入流(貌似只能以此种办法)获取实体后,在Action中就拿不到真正的数据了。

经过调整后的验证代码:

        /// WebAPI防篡改签名验证抽象基类Attribute

        /// </summary>
public override void OnActionExecuting(HttpActionContext actionContext)
{ //获取Asp.Net对应的Request var request = ((HttpContextWrapper)actionContext.Request.Properties["MS_HttpContext"]).Request; NameValueCollection getCollection = request.QueryString;//此签名要求client_id、token及timestamp均通过QueryString传递
string outMessage = "未经过验证的请求!";
if (getCollection != null && getCollection.Count > )
{ string client_id = getCollection["client_id"];
string timestamp = getCollection["timestamp"];
string token = getCollection["token"];
if (!string.IsNullOrWhiteSpace(client_id)//必须包含client_id
&& !string.IsNullOrWhiteSpace(timestamp)//必须包换时间戳 && !string.IsNullOrWhiteSpace(token))
//&& Regex.IsMatch(client_key, "^[0-9A-Za-z]{32}$"))//sign必须为32位Md5摘要
{
Config.Service.SignCalculation sc = new Config.Service.SignCalculation();
if (sc.VerifyClientParam(client_id, token, timestamp, out outMessage))
{//验证通过,执行基类方法
base.OnActionExecuting(actionContext);
return;
}
}
var html = "<p>" + outMessage + "</p>"; //此处暂时以401返回,可调整为其它返回
actionContext.Response = actionContext.Request.CreateResponse(HttpStatusCode.Unauthorized,"验证失败");
actionContext.Response.Content = new StringContent(html, Encoding.UTF8, "text/html");
}
}

调整后,验证参数从请求QueryString中获得,Action可以用本系列的几种办法均可以顺利获取实际的数据。

填坑完毕。

本系列为本人原创,解决了本人实际工作中碰到的问题。

写文章不易,欢迎转载。但转载的时候,带上原文链接,可好?

WebApi传参总动员(填坑)的更多相关文章

  1. WebApi传参总动员(一)

    目前自己的工作和WebApi相关,免不了传入.接收参数.以前的老办法是从请求流中获取json,再反序列化,这中间有2个不能控制的地方,一个是流,一个是反序列化,都需要try,总感觉非常的不爽.因此对W ...

  2. WebApi传参总动员(四)

    前文介绍了Form Data 形式传参,本文介绍json传参. WebApi及Model: public class ValuesController : ApiController { [HttpP ...

  3. WebApi传参总动员(五)

    上回说到涉及多个实体的传参,用常规的方法已经不能解决了.这回我们用终极大招搞定她. WebApi:注意要引用JSON.Net [HttpPost] public string GetData(stri ...

  4. WebApi传参总动员(三)

    上篇介绍了如何从输入流中获取实体对象.本篇介绍以url形式传递参数.简单的参数不再赘述,这里主要实现形如(string name,Woman woman)这样的参数传递. 本篇及后面几章均涉及js调用 ...

  5. WebApi传参总动员(二)

    上篇,从最简单的string入手.本篇演示了从请求的输入流中获取实体.api: public class ValuesController : ApiController { [HttpPost] p ...

  6. C# WebApi传参之Post请求-AJAX

    最近悟出来一个道理,在这儿分享给大家:学历代表你的过去,能力代表你的现在,学习代表你的将来. 十年河东十年河西,莫欺少年穷.  学无止境,精益求精    上一节讲述了C# WebApi传参之Get请求 ...

  7. C# WebApi传参之Get请求-AJAX

    最近悟出来一个道理,在这儿分享给大家:学历代表你的过去,能力代表你的现在,学习代表你的将来. 十年河东十年河西,莫欺少年穷.  学无止境,精益求精    在介绍本篇博客之前,先来温故下AJax的请求, ...

  8. WebAPI传参

    1.GET请求传递参数 URL传参:http://localhost/ApiTest/test?id=1 API接收参数 [HttpGet] public string GetUser(int id) ...

  9. C#进阶系列——WebApi 传参详解

    本篇打算通过get.post.put.delete四种请求方式分别谈谈基础类型(包括int/string/datetime等).实体.数组等类型的参数如何传递. 回到顶部 一.get请求 对于取数据, ...

随机推荐

  1. 4M宽带一般最大的下载速度是多少?

    4M宽带理论速度=4Mbit/s=4096 Kbit/s=512 KByte/s宽带速度其实是有两个参数的:上行(上传速度).下行(下载速度),一般宽带标为4M其实是说下载速度是4M(即512KB/每 ...

  2. BTrace入门教程

    bin版:https://kenai.com/projects/btrace/downloads/directory/releases 源码:https://github.com/btraceio/b ...

  3. LESS详解之函数(四)

    之前已经为大家介绍了一些LESS函数,大家应该对之前介绍的有所了解了.下面依旧为大家介绍LESS的函数,附加着一些小例子.希望这些有关LESS的函数能在大家编写LESS的时候有所帮助. saturat ...

  4. string-->wstring-->string

    std::string src("三毛三毛三毛三毛三三三三流浪记"); size_t size = mbstowcs(NULL,src.c_str(),0); std::wstri ...

  5. Android-NDK编译:cocos2d-x(三) eclipse 导入工程

    NDK 编译后,用eclipse导入cocos2d-x工程 菜单[File]-->[New]-->[Project] ,弹出New Project 对话框 窗口下方 选 [Android] ...

  6. CSS基础(三):选择器

    常用选择器 元素选择器,即html标记如div,ul,li,p,h1~h6,table等. p { font-size:14px; } h1 { color:#F00; } 复合选择器, 由两个选择器 ...

  7. c++ 访问者模式(visitor pattern)

    概述: 我们去银行柜台办业务,一般情况下会开几个个人业务柜台的,你去其中任何一个柜台办理都是可以的.我们的访问者模式可以很好付诸在这个场景中:对于银行柜 台来说,他们是不用变化的,就是说今天和明天提供 ...

  8. tcp/ip协议listen函数中backlog参数的含义与php-fpm的502 Bad Gateway

    To understand the backlog argument, we must realize that for a given listening socket, the kernel ma ...

  9. JavaScript中的String对象

        String对象提供的方法用于处理字符串及字符. 常用的一些方法: charAt(index):返回字符串中index处的字符. indexOf(searchValue,[fromIndex] ...

  10. 二十五、【开源】EFW框架Winform前端开发之强大的自定义控件库

    回<[开源]EFW框架系列文章索引>        EFW框架源代码下载V1.2:http://pan.baidu.com/s/1hcnuA EFW框架实例源代码下载:http://pan ...