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 无法将字符串转换为整数,有没有办法让它以这种方式工作?(并且还为其他类型的(例如日期)提供相同的错误消息)

更新:我想找到一种方法,以便在转换错误的情况下能够有很好的默认错误消息,这样就不必担心每个特定的属性(这个问题的标题也发生了变化)

Asp.Net 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;
        }
    }
相关文章: