Asp.Net MVC:如何在无效转换的情况下使验证消息默认更美观
本文关键字:验证 情况下 消息 默认 美观 转换 MVC Net 无效 Asp | 更新日期: 2023-09-27 18:33:27
我有以下模型类:
public class Person{
public int Age { get; set; }
}
并具有以下控制器来编辑它:
public class HomeController : Controller
{
...
[HttpPost]
public ActionResult EditPerson(Person person)
{
//... bla bla bla
return View(person);
}
}
提交表单时将调用编辑人员。表单包含一个名为"年龄"的输入。如果用户输入非数字字符串 - 调用 EditPerson 时,ModelState["Info"] 包含文本错误,例如"值'0dfrg'对年龄无效"
我查看了 MS 源,发现如果任何类型转换失败,则会设置此类错误消息。但我想在所描述的情况下写一些类似"字段'年龄'必须包含一个数字"的东西。如果 MVC 无法将字符串转换为整数,有没有办法让它以这种方式工作?(并且还为其他类型的(例如日期)提供相同的错误消息)
更新:我想找到一种方法,以便在转换错误的情况下能够有很好的默认错误消息,这样就不必担心每个特定的属性(这个问题的标题也发生了变化)
您可以使用验证属性并将其用于模型字段,如下所示
public class Person{
[RegularExpression(@"[0-9]*$", ErrorMessage = "Field 'Age' must contain a number")]
public int Age { get; set; }
}
这比仅在操作中执行验证要好,在这种情况下,还将添加客户端验证。
请确保在视图中使用 html 帮助程序来显示验证。在这种情况下,类似于
@Html.TextBoxFor(model => model .Age)
@Html.ValidationMessageFor(model => model.Age)
https://dotnetfiddle.net/j3opUQ
看看这是否有帮助
[RegularExpression(@"'d+", ErrorMessage = "Field 'Age' must contain a number")]
public int Age { get; set; }
感谢您的解决方案,但我想要的是为模型可以包含的每个 int、datetime 等字段做出正确的行为。这样我就不需要为这些事情烦恼了。我找到了一个解决方案(感谢调试MS代码的可能性)。它很丑,但有效:
1) 在插入行Application_Start:
ModelBinders.Binders.DefaultBinder = new ExtendedModelBinder();
2) 定义扩展模型绑定器类:
public class ExtendedModelBinder : DefaultModelBinder
{
string GetErrorMessageForType(Type type)
{
if (type == typeof(int))
return "You must enter an integer numeric value";
if (type == typeof(double))
return "You must enter a numeric value";
return "The entered value is incorrect";
}
public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
object res = base.BindModel(controllerContext, bindingContext);
foreach (var entry in bindingContext.ModelState)
{
if (entry.Value.Errors != null)
{
var itemsToReplace = new List<ModelError>();
foreach (var err in entry.Value.Errors)
{
if (string.IsNullOrEmpty(err.ErrorMessage) && err.Exception != null)
{
var ex = err.Exception;
while (!(ex is FormatException) && ex != null)
ex = ex.InnerException;
if (ex != null)
{
itemsToReplace.Add(err);
}
}
}
foreach (var err in itemsToReplace)
{
var ex = err.Exception;
entry.Value.Errors.Remove(err);
entry.Value.Errors.Add(GetErrorMessageForType(bindingContext.ModelType));
}
}
}
return res;
}
}