Ste*_*n V 6 c# asp.net-mvc parsing model-binding
我有一个具有整数属性的模型.提交模型时23443,模型绑定器工作正常,并且该操作中的值可用.但是如果使用千位分隔符提交模型23,443,则不会解析该值并且属性为零.但我发现一个十进制类型的属性可能有千位分隔符,它会解析并正确填充.
我发现默认情况下Int32.Parse()不解析千位分隔符但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");
[...]
}
Run Code Online (Sandbox Code Playgroud)
每次我处理这些领域.它看起来很丑陋,并将所有验证移出模型属性.将属性的类型更改为十进制只是为了使模型绑定工作似乎不是一个明智的想法.当我查看模型绑定器时,它看起来像是TypeConverter用来完成从字符串到类型的转换.它看起来像Int32Converter使用Int32.Parse()与NumberStyles.Integer.
有没有办法改变行为Int32Converter以允许默认情况下解析千位分隔符?也许替代默认NumberStyles的Int32.Parse()整个应用程序?或者是添加我自己的模型绑定器,它使用NumberStyles.AllowThousands唯一/正确的操作过程解析整数?
我认为,您可以为 int 类型添加自定义绑定器。
演示: http: //dotnetfiddle.net/VSMQzw
有用的链接:
更新
基于黑客文章:
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
}
Run Code Online (Sandbox Code Playgroud)
在 Application_Start 事件中(可能在 Global.asax 中),添加:
ModelBinders.Binders.Add(typeof(int), new IntModelBinder());
Run Code Online (Sandbox Code Playgroud)