这更容易用一个例子来解释。假设我有一个人员类
Public Person
{
string firstName;
string SocialSecurityNumber;
}
当用户在网页中进行某些更改时,Person 对象将回发到接受 Person 作为输入参数的控制器。社会安全号码已加密。我们有许多页面回发对象(不一定是人类),这些对象将加密的社会保障作为参数。现在我想修改模型绑定,以便如果发布的对象具有 SocialSecurityNumber 作为属性,则应自动解密它。我该怎么做?
您可以使用自定义模型绑定器。一些例子:
- http://www.dotnetcurry.com/ShowArticle.aspx?ID=584
- http://odetocode.com/blogs/scott/archive/2009/04/27/6-tips-for-asp-net-mvc-model-binding.aspx
- http://www.markeverard.com/blog/2011/07/18/creating-a-custom-modelbinder-allowing-validation-of-injected-composite-models/
这是我之前使用过的简单示例,您可以根据需要进行修改:
public class FormatterModelBinder : DefaultModelBinder
{
internal static string TrimValue([CanBeNull] string value, [CanBeNull] FormatAttribute formatter)
{
if (string.IsNullOrEmpty(value)) return value;
return ((formatter == null) || formatter.Trim) ? value.Trim() : value;
}
protected override void SetProperty(ControllerContext controllerContext, ModelBindingContext bindingContext, PropertyDescriptor propertyDescriptor, object value)
{
if ((propertyDescriptor != null) && (propertyDescriptor.PropertyType == typeof(string)))
{
var stringValue = value as string;
var formatter = propertyDescriptor.Attributes.OfType<FormatAttribute>().FirstOrDefault();
stringValue = TrimValue(stringValue, formatter);
value = stringValue;
}
base.SetProperty(controllerContext, bindingContext, propertyDescriptor, value);
}
}
然后,您可以根据需要创建一个属性来装饰属性:
[AttributeUsage(AttributeTargets.Property, AllowMultiple = false)]
public sealed class FormatAttribute : Attribute
{
public FormatAttribute()
{
Trim = true;
}
public bool Trim { get; set; }
}
这是由视图模型中属性上的属性"激活"的
Public Person
{
string firstName;
[Format(Trim = true)]
string SocialSecurityNumber;
}
修改它以允许加密应该相当简单。
也许你应该把它存储在它自己的类中
public class Person
{
public string firstName { get; set; }
public SocialSecurityNumber SSN { get; set; }
}
public class SocialSecurityNumber
{
public string SSN { get; set; }
}
也许该类也可以有自己的解密方法。
public class SocialSecurityNumber
{
public string SSN { get; set; }
public string Decrypt()
{
//TODO: Decrypt SSN
return decrypted ssn
}
}
现在在您的控制器中
[HttpPost]
public ActionResult PostedPerson (Person person)
{
string PersonName = person.firstName;
string SocialSecurityNumber = person.SSN.SSN;//or person.SSN.Decrypt();
//TODO: decrypt SocialSecurity number
}
在使用 FormCollection 进行模型绑定的情况下,则必须设置某种标志或使用抽象来标记字段已加密
public class Person
{
public string firstName { get; set; }
public SocialSecurityNumber SSN { get; set; }
}
public class SocialSecurityNumber
{
public string SSN { get; set; }
public string Encrypted { get; set; }//set this to "EncryptedTrue" or something
//similar in order to handle it in the post
}
然后使用您的表单集合
[HttpPost]
public ActionResult PostedPerson (FormCollection fc)
{
for( var val in fc )
{
if( val is InnerList ){
{
if( val.Contains("EncryptedTrue") )
{
//then val.SSN would be an encryped social security number
}
}
}
}