Nic*_*ick 7 asp.net-mvc custom-attributes data-annotations
我在MVC4工作,想要使用Uppercase属性定义模型.我们的想法是,大写属性的存在会导致模型值在到达服务器时转换为大写.
目前我在模型中有以下代码:
[Required]
[Display(Name="Account Code")]
[StringValidation(RegExValidation.AccountCode, Uppercase=true)]
public string Account
{
get { return _account; }
set
{
if (value != null)
_account = value.ToUpper();
}
}
Run Code Online (Sandbox Code Playgroud)
但我真正喜欢的是:
[Required]
[Display(Name="Account Code")]
[StringValidation(RegExValidation.AccountCode)]
[Uppercase]
public string Account { get; set; }
Run Code Online (Sandbox Code Playgroud)
我认为我可能需要创建一个Uppercase属性,ValidationAttribute以确保在模型到达服务器时触发它.但这似乎有点不对,因为我并没有真正验证数据.有没有更好的办法?
另外,有没有办法确保属性的调用顺序?我真的想在自定义StringValidation属性触发之前将数据转换为大写,因为这会检查正则表达式模式中文本的大小写.
要为此添加一些背景知识,我希望减少添加代码以大写数据的需要.涅(nirvana)将是一个单一属性,它可以在模型绑定或验证阶段更新进入服务器的数据.然后可以在StringValidation属性中引用此属性以修改其检查中使用的RegEx值.然后我也可以在自定义TextBoxFor帮助器方法中查找此属性,这样我就可以添加text-transform: uppercase它,使其在客户端看起来正确.
有没有人有任何想法?
我已经设法让这个工作到了一定程度,所以这是我的解决方案供其他人评估.
一旦注意到,无法实现完整的解决方案,因为我无法获得属性Modelmetadata内部StringValidation.IsValid().具体问题我在这里是我能得到的元数据,但我无法得到的PropertyName来自它,只有DisplayName.有多种选择,但事实上我的一些属性具有相同的DisplayName意味着我无法确定那ProprtyName是我实际验证的那个.
这是以下代码ValidationAttribute:
public class StringValidationAttribute : ValidationAttribute, IClientValidatable, IMetadataAware {
private bool _uppercase;
public StringValidationAttribute(bool uppercase = false) {
_uppercase = uppercase;
}
...
public void OnMetadataCreated(ModelMetadata metadata)
{
metadata.AdditionalValues["Uppercase"] = _uppercase;
}
}
Run Code Online (Sandbox Code Playgroud)
然后我创建了一个新的IModelBinder实现:
public class StringBinder : IModelBinder
{
public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
ValueProviderResult result = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);
if (result == null)
return null;
if (bindingContext.ModelMetadata.AdditionalValues.ContainsKey("Uppercase")) {
if ((bool)bindingContext.ModelMetadata.AdditionalValues["Uppercase"]])
return result.AttemptedValue.ToUpper();
}
return result.AttemptedValue;
}
}
Run Code Online (Sandbox Code Playgroud)
并在我的Global.asax文件中注册:
ModelBinders.Binders.Add(typeof(string), new StringBinder());
Run Code Online (Sandbox Code Playgroud)
到目前为止,代码将导致进入MVC的任何字符串输入转换为大写,如果它已StringValidationAttribute在模型上附加到它,并且已设置大写指示符.
接下来,为了实现我的html表单也是大写的愿望,我实现了一个新EditorTemplate命名string.cshtml.在这个视图中,我补充说:
RouteValueDictionary htmlAttributes = new RouteValueDictionary();
if ((bool)ViewData.ModelMetadata.AdditionalValues["Uppercase"]) {
htmlAttributes.Add("class", "Uppercase");
}
@Html.TextBox("", Model, htmlAttributes)
Run Code Online (Sandbox Code Playgroud)
用CSS作为;
.Uppercase {
text-transform: uppercase;
}
Run Code Online (Sandbox Code Playgroud)
希望这篇文章可以帮助其他人.
| 归档时间: |
|
| 查看次数: |
15792 次 |
| 最近记录: |