【问题标题】:ASP.NET MVC: DataAnnotations - Show an error message indicating that a field must be numericASP.NET MVC:DataAnnotations - 显示指示字段必须是数字的错误消息
【发布时间】:2011-01-04 00:57:34
【问题描述】:

DataAnnotations 的工作方式似乎存在一些漏洞,因为用户将一些文本输入到将进入 int 的字段中将永远无法到达 DataAnnotations 代码。它启动模型绑定错误并向用户显示错误“值 'a' 对于 XXXX 字段无效。”

无论如何,它自动处理这种情况非常好,但我实际上想显示一条指示问题的错误消息,例如。 "值 'a' 不是数字。请在 XXXX 字段中输入数字值"。

我已经尝试了How to replace the default ModelState error message in Asp.net MVC 2?ASP.NET MVC - Custom validation message for value types 列出的解决方案,但我无法让它们发挥作用。

看来我的资源文件根本没有被读取,因为这里 (http://msdn.microsoft.com/en-us/library/system.web.mvc.defaultmodelbinder.resourceclasskey.aspx) 声明“如果属性设置为无效的类键(例如不存在的资源文件),MVC 会抛出一个例外。”即使我将行更改为 DefaultModelBinder.ResourceClassKey = "asdfasdhfk" 也不例外。

有人有什么想法吗?

编辑:这是一些代码。减去我的 Messages.resx 文件的消息没有被使用,所有这些都在工作。 Messages.resx 的代码是自动生成的,所以我不会包含它。

因此,在 ProcessOrder 中输入“a”会生成一条通用消息,而不是我在 Messages.resx 中输入的 PropertyValueInvalid(以及 InvalidPropertyValue 以获得良好的衡量标准)。

Application_Start 方法

protected void Application_Start()
{            
    RegisterRoutes(RouteTable.Routes);
    ModelBinders.Binders.DefaultBinder = new Microsoft.Web.Mvc.DataAnnotations.DataAnnotationsModelBinder(); //set dataanooations to be used
    DefaultModelBinder.ResourceClassKey = "Messages"; //set data annotations to look in messages.resx for the default messages
    ValidationExtensions.ResourceClassKey = "Messages";
}

实体类

[MetadataType(typeof(GLMetaData))]
public partial class GL
{

}



public class GLMetaData
{
    public int TransRefId { get; set; }

    [DisplayName("Process Order")]
    public int? ProcessOrder { get; set; }

    [DisplayName("Trans Type")]
    [StringLength(50)]
    public string TransType { get; set; }

    [StringLength(100)]
    public string Description { get; set; }

    [DisplayName("GL Code")]
    [StringLength(20)]
    public string GLCode { get; set; }

    [DisplayName("Agents Credit No")]
    [StringLength(50)]
    public string AgentsCreditNo { get; set; }

    [Required]
    public bool Active { get; set; }
}

控制器动作:

    [AcceptVerbs(HttpVerbs.Post)]
    public ActionResult Edit(GL glToBeUpdated)
    {
        try
        {
            if (!ModelState.IsValid)
                return View(glToBeUpdated);

            //set auto properties
            glToBeUpdated.UpdateDate = DateTime.Now;
            glToBeUpdated.UpdateUser = this.CurrentUser;

            glDataLayer.update(glToBeUpdated);

            glDataLayer.submitChanges();

            return RedirectToAction("Index");
        }
        catch
        {
            glDataLayer.abortChanges();

            throw;
        }
    }

【问题讨论】:

  • 你让它工作了吗?同样的问题...
  • 没有。我主要切换到客户端验证(主要通过 jquery 字母数字插件),在后端使用服务器端验证,而没有完全描述性的错误消息作为后备。该系统的用户都是我公司的内部用户,我可以确保他们始终启用 javascript,因此后端验证只是一种安全措施,因此不需要漂亮的错误消息。

标签: asp.net-mvc data-annotations modelstate


【解决方案1】:

我为解决类似问题所做的是清除模型状态,验证 ModelState["XXXX"].Value.AttemptedValue 而不是尝试将无效值放入模型属性中导致的空值,填充错误消息并重置模型值。

这样我可以得到我想要的错误消息,并且如果需要提供多个错误消息(“需要一个值”或“该值必须是数字”)。

【讨论】:

  • 有趣,但是根本没有达到 DataAnnotations 验证,所以我不能使用这种方法。我决定只使用 jquery 字母数字插件来阻止输入非数字数据。在某些情况下,您仍然可以通过此验证,但总体而言,该解决方案已经足够好了。
【解决方案2】:

我在 MVC4 RC 上的大部分时间都在与这个作斗争。不管我设置什么

DefaultModelBinder.ResourceClassKey

它似乎从来没有工作过。当我分配垃圾时,它也从未抛出异常。

这是我用来分配值的(无济于事):

 DefaultModelBinder.ResourceClassKey = typeof(App_GlobalResources.ValidationMessages).Name;

最后我决定在客户端处理这个错误消息并覆盖 jQuery 用来显示消息的数据属性。

@Html.TextBoxFor(m => m.Amount, new Dictionary<string,object>(){{"data-val-number","Invalid Number"}})

这是我需要的工作方式。

具有讽刺意味的是,这也有效:

@Html.TextBoxFor(m => m.Amount, new Dictionary<string, object>() {{ "data-val-number", HttpContext.GetGlobalResourceObject("ValidationMessages", "PropertyValueInvalid") } })

【讨论】:

    【解决方案3】:

    在这里,我将联系号码字段作为字符串,但具有范围属性,因此可以提供数字验证以在您的资源文件中使用。

        [Required(ErrorMessageResourceType = typeof(Global), ErrorMessageResourceName = "ContactNumberRequired")]
        [Range(0, int.MaxValue, ErrorMessageResourceType = typeof(Global), ErrorMessageResourceName = "ValidContactNumber")]
        [Display(Name = "Contact Number")]
        public string ContactNumber { get; set; }
    

    所以现在这里提供了 ErrorMessageResourceName 作为 key 。您也可以在多语言中自定义和使用它

    【讨论】:

      猜你喜欢
      • 2011-10-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-01-16
      相关资源
      最近更新 更多