https://blog.csdn.net/hesi726/article/details/83030415
这儿说了一下不修改数据库也不修改太多代码的情况下将数字加密的问题,(适应于Json)
现在问题来了,客户端传回来的也是加密后的字符串。。。噗通。。
绑定到 int 类型的属性,。
服务器端直接报 Model Validate 出错。。
所以,服务器端还需要一个反转的过程;
MVC 有很多地方可以对于上传的值进行处理;
例如最简单的 FormValueProvider,
不过这些 ValueProvider 很明显不适合,因为它们返回的是字符串,此时还没有参数类型;
自定义一个 NewtonsoftJsonValueProviderFactory 当然也不行,原因同上;
所以,只能在 构建了 ValueProvider 之后, 并在模型验证之前 进行处理;
ASP.Net MVC 默认使用 DefaultModelBinder 进行模型绑定,定义一个此类的继承类,
当然,你不嫌麻烦也可以自己写 IModelBinder 接口的实现类,我是懒人;
里面有一堆的方法,直观来看,覆盖
protected virtual void SetProperty(ControllerContext controllerContext, ModelBindingContext bindingContext, PropertyDescriptor propertyDescriptor, object value)
但是,实际一测试,这个时候传入进来的 value 已经是 null 了;
那么下面这个方法呢。。
protected override object GetPropertyValue(ControllerContext controllerContext, ModelBindingContext bindingContext, PropertyDescriptor propertyDescriptor, IModelBinder propertyBinder)
protected override object GetPropertyValue(ControllerContext controllerContext, ModelBindingContext bindingContext, PropertyDescriptor propertyDescriptor, IModelBinder propertyBinder)
{
var crypt = propertyDescriptor.Attributes[typeof(CryptIdAttribute)] as CryptIdAttribute;
if (crypt != null)
{
var value = bindingContext.ValueProvider.GetValue(propertyDescriptor.Name);
if (value != null)
{
var cryptValue = value.AttemptedValue;
if (string.IsNullOrEmpty(cryptValue)) return null;
return SecurityUtil.DecryptIdInGuid(cryptValue, crypt.CryptType, false);
}
}
var result = base.GetPropertyValue(controllerContext, bindingContext, propertyDescriptor, propertyBinder);
return result;
}
嗯,貌似很好; Get, Post, 都能够正确的把 PartnerId=b8feb9b3db27f6d0d3204774b353d6e2"
这样的传入参数转换回 PartnerId=123;
完整走一遍单元测试,噗通噗通噗通的错误冒出来了。。
Get下这样的参数不支持:
http://localhost/ne/debug/ValidateInput?testx.PartnerId=b8feb9b3db27f6d0d3204774b353d6e2
Post下这样的参数不支持:
testx[PartnerId]:b8feb9b3db27f6d0d3204774b353d6e2
Json下这样的参数不支持:
{testx: {PartnerId: "b8feb9b3db27f6d0d3204774b353d6e2"}}
很明细 bindingContext.ValueProvider.GetValue(propertyDescriptor.Name) 这个无法获取到类似于
propertyDescriptor.Name 这个值始终为 PartnerId , 所以获取到null 了;
propertyDescriptor 这个里面的 Convert 为只读,-- 否则自己写一个 TypeConvert 貌似很简单解决这个问题;
好吧,我构建一个 PropertyDescriptor 然后使用
base.GetPropertyValue(controllerContext, bindingContext, propertyDescriptor, propertyBinder) 去获取不久行了么。。
再一看, PropertyDescriptor 抽象类,实际类为 ReflectPropertyDescriptor,好吧;
俺就使用 ReflectedParameterDescriptor, 仔细一看 ReflectedParameterDescriptor构造函数需要一个 ParameterInfo 参数,
而 ParameterInfo 确是 protected 的。。。
貌似太麻烦了。。
再看看有没有其他属性。。发现一个
protected override object GetPropertyValue(ControllerContext controllerContext, ModelBindingContext bindingContext, PropertyDescriptor propertyDescriptor, IModelBinder propertyBinder)
{
var crypt = propertyDescriptor.Attributes[typeof(CryptIdAttribute)] as CryptIdAttribute;
if (crypt != null)
{
var value = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);
if (value != null)
{
var cryptValue = value.AttemptedValue;
if (string.IsNullOrEmpty(cryptValue)) return null;
return SecurityUtil.DecryptIdInGuid(cryptValue, crypt.CryptType, false);
}
}
var result = base.GetPropertyValue(controllerContext, bindingContext, propertyDescriptor, propertyBinder);
return result;
}
这个系列的文章说的比较细,但是代码实用价值太少;
可以看看。。。
https://www.cnblogs.com/artech/archive/2012/05/23/default-model-binding-01.html