我有一个具有整数属性的模型。使用23443
提交模型时,模型绑定器工作正常,并且该操作中的值可用。但是,如果使用千位分隔符23,443
提交模型,则不会解析该值,并且属性为零。但我发现一个十进制类型的属性可能有千位分隔符,它会解析并正确填充。
我发现by default Int32.Parse()
doesn't parse thousands separator但Decimal.Parse()
确实允许千位分隔符。我不想写一张支票,如:
public ActionResult Save(Car model, FormCollection form) {
Int32 milage;
if(model.MyProperty == 0 && Int32.TryParse(form["MyProperty"], NumberStyles.AllowThousands, CultureInfo.InvariantCulture, out milage) {
model.MyProperty = milage;
} else
ModelState.AddModelError("Invalid", "Property looks invalid");
[...]
}
每次我处理这些领域。它看起来很丑陋,并将所有验证移出模型属性。将属性的类型更改为十进制只是为了使模型绑定工作似乎不是一个明智的想法。当我查看模型绑定器时,看起来它正在使用TypeConverter
来完成从字符串到类型的转换。它looks like Int32Converter
uses Int32.Parse()
with NumberStyles.Integer
。
是否有办法更改Int32Converter
的行为以允许默认情况下解析千位分隔符?也许在整个应用中覆盖NumberStyles
上的默认Int32.Parse()
?或者是添加我自己的模型绑定器,用NumberStyles.AllowThousands
解析整数只有/正确的行动方案?
答案 0 :(得分:0)
我认为,您可以为int类型添加自定义绑定器。
演示:http://dotnetfiddle.net/VSMQzw
有用的链接:
<强>更新强>
基于Haacked文章:
using System;
using System.Globalization;
using System.Web.Mvc;
public class IntModelBinder : IModelBinder
{
#region Implementation of IModelBinder
public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
ValueProviderResult valueResult = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);
ModelState modelState = new ModelState { Value = valueResult };
bindingContext.ModelState[bindingContext.ModelName] = modelState;
object actualValue = null;
try
{
actualValue = Int32.Parse(valueResult.AttemptedValue, NumberStyles.Number, CultureInfo.InvariantCulture);
}
catch (FormatException e)
{
modelState.Errors.Add(e);
}
bindingContext.ModelState.Add(bindingContext.ModelName, modelState);
return actualValue;
}
#endregion
}
在Application_Start事件中(可能在Global.asax中),添加:
ModelBinders.Binders.Add(typeof(int), new IntModelBinder());