前面写了三篇文章,都是为了这一步做准备,现在就开始进入最后的正题吧
首先对于用户请求中的合作号和签名部分,定义一个专门的类来接收此部分信息(这里要注意的是,在FromUri获取时,方法里面的参数名不能起属性名一样的参数名,否则会导致类实例化,但属性却均为null的问题,这个在做demo时纠结了我1个多小时,汗一个)
public class PartnerSign { public string Partner { get; set; } public string Sign { get; set; } }然后是Controller例子,既然WebAPI创建时,默认自带的例子是Product,那这里也就用Product做例子
public class ProductController : ApiControllerBase { [HttpGet] public IEnumerable<Product> GetAllProducts([FromUri]PartnerSign partnerSign) { throw new NotImplementedException(); } [HttpGet] public Product GetProduct([FromUri]PartnerSign partnerSign, [FromUri]int id) { throw new NotImplementedException(); } [HttpPost] public bool AddProduct([FromUri]PartnerSign partnerSign, [FromBody]Product product) { throw new NotImplementedException(); } [HttpPut] public bool ChangeProduct([FromUri]PartnerSign partnerSign, [FromBody]Product product) { throw new NotImplementedException(); } [HttpDelete] public bool RemoveProuct([FromUri]PartnerSign partnerSign, [FromUri]int id) { throw new NotImplementedException(); } }在这里所有的参数我都做了显示声明数据来源,如果不带声明时,对于基础数据,WebAPI默认FromUri,对于实体,WebAPI默认FromBody,另外因为FromUri可以声明多个,所以完全可以将Get请求参数声明为两个,一个为[FromUri]PartnerSign,另一个为其它类,比如[FromUri]OtherClass
再次补充下:对于方法支持的HTTP请求方式(GET,POST,PUT,DELETE),请遵循Restful规范,别搞出新增用PUT、修改用POST、查询用DELETE的事情,虽然这在运行时没有任何错误,但这会导致API实际用意与规范不符
好了,到了这里,简易但完整的WebAPI防篡改就完全实现了,然后……我会在后面再在发一个WebAPI签名测试小工具,方便开发时自测……
忘记补充一个及其重要的事情了:因为签名是通过QueryString方式获取的,所以在API请求时,请求的Url格式必须为?partner=zhangsan&sign=AAFDAFAFA这种格式,即API的Route只能作用到action就结束了,不能Route方法内的参数