我有十进制价格的字段,例如20,00并且想要编写我自己的验证消息而不是默认"字段价格必须是数字"。正如我很快就明白的那样,由于数字中的逗号,我得到验证错误,视图将其解释为字符串。所以我也应该解决这个问题。
我找到了@DarinDimitrov编写的this解决方案,我编写自定义模型绑定器
public class PriceModelBinder : DefaultModelBinder
{
public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
var displayFormat = bindingContext.ModelMetadata.DisplayFormatString;
var value = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);
if (!string.IsNullOrEmpty(displayFormat) && value != null)
{
decimal price;
if (decimal.TryParse(value.AttemptedValue, NumberStyles.AllowDecimalPoint, CultureInfo.CurrentCulture, out price))
{
return price;
}
bindingContext.ModelState.AddModelError(bindingContext.ModelName, "Неверный формат числа");
}
return base.BindModel(controllerContext, bindingContext);
}
}
我也在Global.asax
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
ModelBinders.Binders.Add(typeof(decimal), new PriceModelBinder());
}
此外,我在<globalization culture="ru-RU" uiCulture="ru-RU" />
中添加了web.config <system.web>
。当我放置一个断点并尝试从视图中添加实体,但没有任何变化时,我得到相同的默认错误字符串。此外,断点并没有被抓住。
经过一番搜索,我发现模型绑定器只在POST方法调用时才有效,但我的方法已经是POST,因为我添加了实体。我尝试添加check in controller ModelState.IsValid
,但它没有效果,因为表单没有发送到服务器。
在这里我的想法结束了,也许有人可以提供帮助。我写下模型,视图和控制器的部分内容。
public class ServiceDto
{
//other properties
[Display(Name = "Цена"), DataType(DataType.Currency, ErrorMessage = "Неверный формат числа")]
[Required(ErrorMessage = "Цена услуги обязательна")]
public decimal Price { get; set; }
}
@Html.EditorFor(model => model.Price, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.Price, "", new { @class = "text-danger" })
public class OperatorController : Controller
{
[HttpPost]
public ActionResult CreateService(ServiceDto serviceDto)
{
//mapping here
_unitOfWork.Services.Create(service);
_unitOfWork.Save();
return RedirectToAction("Index");
}
}
更新
我添加了这个js脚本来查看所有其他脚本,但没有任何改变。
<script src="/Scripts/jquery-1.10.2.js"></script>
<script src="/Scripts/jquery.validate.js"></script>
<script src="/Scripts/jquery.validate.unobtrusive.js"></script>
<script src="/Scripts/bootstrap.js"></script>
<script src="/Scripts/respond.js"></script>
<script type="text/javascript">
$.validator.methods.number = function (value, element) {
return this.optional(element) || /^-?(?:d+|d{1,3}(?:[s.,]d{3})+)(?:[.,]d+)?$/.test(value);
};
</script>
也许这个脚本没有被执行?对不起,我主要使用后端,如果问题与js有关,那对我来说就是黑暗的森林。
答案 0 :(得分:2)
正如Stephen Muecke所说,默认情况下jquery.validate.js
使用小数点作为数字输入的分隔符(这是符合JS数字格式的标准)。要在俄罗斯文化中包含小数点逗号,您需要覆盖jquery.validator.methods.number
和jquery.validator.methods.range
行为,如下所示:
// taken from Lenard Gunda (see reference section)
$.validator.methods.number = function (value, element) {
// notice additional backslashes to escape formats
return this.optional(element) || /^-?(?:\d+|\d{1,3}(?:[\s\.,]\d{3})+)(?:[\.,]\d+)?$/.test(value);
}
$.validator.methods.range = function (value, element, param) {
var globalizedValue = value.replace(",", ".");
return this.optional(element) || (globalizedValue >= param[0] && globalizedValue <= param[1]);
}
如果您使用的是Globalize插件,则可以使用该插件中的parseFloat
替换正则表达式:
Globalize.culture('ru-RU');
function parseNumber(value) {
return Globalize.parseFloat(value);
}
$.validator.methods.number = function (value, element) {
return this.optional(element) || $.isNumeric(parseNumber(value));
}
$.validator.methods.range = function (value, element, param) {
var globalizedValue = parseNumber(value);
return this.optional(element) || (globalizedValue >= param[0] && globalizedValue <= param[1]);
}
参考文献:
jQuery validate and the comma decimal separator
Issue with Decimals, Commas and Client-Side Validation
jQuery Validation Plugin: validate decimal number with comma as decimal separator