Che*_*hev 7 c# validation asp.net-mvc entity-framework asp.net-mvc-3
好吧,这个问题真的在我的皮肤下.让我从一步一步的格式描述我的应用程序开始.
首先,我有我的Entity Framework生成的模型.在其中我有以下实体:
http://www.codetunnel.com/EFEntities.jpg
现在,为了在实体上实现验证,我使用了部分类并处理EF提供的OnChanging挂钩.以下是PostComment部分类的示例:
namespace CodeTunnel.Domain.Models
{
public partial class PostComment : IDataErrorInfo
{
private Dictionary<string, string> _errors = new Dictionary<string, string>();
partial void OnAuthorChanging(string value)
{
//Validating anything but required value works fine.
//Like this pseudo-validator.
if (value.ToLower() != "fred")
_errors.Add("Author", "Sorry, your name must be Fred.");
}
partial void OnBodyChanging(string value)
{
//Required value validation does not work, I will tell you why below.
if (string.IsNullOrEmpty(value))
_errors.Add("Body", "Body is required.");
}
#region -= IDataErrorInfo methods =-
public string Error
{
get { return string.Empty; }
}
public string this[string columnName]
{
get
{
if (_errors.ContainsKey(columnName))
return _errors[columnName];
return string.Empty;
}
}
#endregion
}
}
Run Code Online (Sandbox Code Playgroud)
请注意,我的类继承自IDataErrorInfo.默认情况下,MVC会检查此错误.如果它找到任何,则它使模型无效并使用存储的错误作为视图中验证助手的消息.我很确定当EF抛出一个异常时,这个字典甚至永远不会填充该属性的值.事实上,我甚至不确定MVC是否在EF生成异常后检测并使模型无效时查找值.
这是问题的屏幕截图,包括示例伪验证器,因此您可以看到它正在工作:
http://www.codetunnel.com/ValidationError.jpg
如您所见,错误消息未显示.但是,它确实将该字段验证为无效.如果我在那里放一个值,那么它验证就好了.我已经对这个问题进行了很多研究,这就是我所知道的:
您无法自定义为必填字段显示的错误消息的原因是因为model属性不可为空.因为它不可为空,所以尝试将null值绑定到它会引发异常.MVC吞下了这个例外,并使模型无效.在发生此异常的任何地方都会生成消息.我不知道消息是由EF还是MVC生成的(我猜MVC因为它首先负责吞下异常).我不知道如何自定义此消息.正如你所看到的,它总是说"价值''是无效的." 我认为这并不完全可怕,但它真的不是非常用户友好.
它到达我的名称验证器并检查你的名字是否"fred"就好了,因为没有抛出任何异常.就EF而言,传入的价值是可以的.直到它达到我的OnAuthorChanging方法它才意识到它不合适.这是正确的行为,并且工作得很好.
如果我在OnChanging事件中抛出异常而不是添加到我的IDataErrorInfo字典中,我可以生成相同的验证消息,只有它将输入的值放在单引号之间.例:
partial void OnAuthorChanging(string value)
{
if (value.ToLower() != "fred")
//_errors.Add("Author", "Sorry, your name must be Fred.");
throw new Exception("Sorry, your name must be Fred.");
}
Run Code Online (Sandbox Code Playgroud)
当输入"test"作为Author的值时,该代码显示此消息:"值'test'无效.".对于必填字段,它只是值为null,因此单引号之间没有任何内容.
有些人(比如这个人)建议你只需在你的模型中将属性设置为可空.这不是一个可接受的解决方案.其中一个原因是:
错误3031:从第313行开始映射片段的问题:不可为空的列PostComments.Body in Table PostComments映射到可空的实体属性.
另外,设置nullable对于非可空类型(例如int)不起作用,将int切换为可空int是一个令人讨厌的混乱,我甚至不会进入这里.
最重要的是,我想从EF自己处理这些例外,或者至少自定义它生成的消息,但我不知道如何.我完全迷失了.我想要做的就是根据我认为非常简单的模型验证定制一条消息!
任何帮助深表感谢.
小智 8
正如您所发现的,MVC正在基于不可归类型来验证您的模型.这是在自定义验证运行之前向ModelState添加错误.
我之前有过这个,并通过在动作开始时循环通过Modelstate并删除所有内容,然后进行自定义验证(坏!!)来解决它
然后发现即使您没有使用数据注释作为主要验证形式,您也可以通过添加[对buddy类中的非nullible类型是必需的,并指定消息来自定义抛出的消息.
它是这样的:
[MetadataType(typeof(YourClassMetadata))]
public partial class YourClass
{
//buddyclass to entity class
class YourClassMetadata
{
[Required(ErrorMessage="Your custom overriding error message")]
public int NonNullablePropertyThatIsGivingYouProblems {get;set;}
}
}
Run Code Online (Sandbox Code Playgroud)
我已经开始为mvc 查看流畅的验证(http://fluentvalidation.codeplex.com),他们似乎通过添加行来关闭global.asax中的问题,在application_start()上
DataAnnotationsModelValidatorProvider.AddImplicitRequiredAttributeForValueTypes = false;
Run Code Online (Sandbox Code Playgroud)
但我可能错了.
| 归档时间: |
|
| 查看次数: |
8986 次 |
| 最近记录: |