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”会产生一般消息,而不是我为PropertyValueInvalid(以及InvalidPropertyValue以及良好度量)输入到Messages.resx中的消息。
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;
}
}
答案 0 :(得分:1)
我为解决类似问题所做的是清除模型状态,对ModelState["XXXX"].Value.AttemptedValue
进行验证,而不是针对因尝试将无效值放入模型属性而导致的错误值,填充错误消息和重置模型值。
这样我可以收到我想要的错误消息,如果需要,可以提供多个(“需要值”或“值必须为数字”)。
答案 1 :(得分:0)
我在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") } })
答案 2 :(得分:0)
这里我将联系人号码字段作为字符串,但是使用范围属性,因此可以提供数字验证,以便从资源文件中使用。
[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作为键。您也可以在多语言
中自定义和使用它