- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
首先让我逐步描述我的应用程序。
首先,我有 Entity Framework 生成的模型。在其中我有以下实体:
http://www.codetunnel.com/EFEntities.jpg
现在,为了对实体实现验证,我使用分部类并处理 EF 提供的 OnChanging Hook 。以下是 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
}
}
请注意,我的类继承自 IDataErrorInfo
。 MVC 默认检查此验证错误。如果它找到任何错误,那么它会使模型无效并使用存储的错误作为 View 中验证助手的消息。我很确定当 EF 抛出异常时,这个字典甚至不会填充该属性的值。事实上,我什至不确定 MVC 是否会在检测到 EF 生成的异常并使模型无效后寻找值。
这是问题的屏幕截图,包括示例伪验证器,因此您可以看到它正在运行:
http://www.codetunnel.com/ValidationError.jpg
如您所见,错误消息并未显示。但是,它确实正确地将字段验证为无效。如果我在那里放一个值,那么它就可以正常验证。我对这个问题做了很多研究,以下是我所知道的:
无法自定义为必填字段显示的错误消息的原因是模型属性不可为空。因为它不可为空,所以尝试将空值绑定(bind)到它会引发异常。 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.");
}
当输入“test”作为 Author 的值时,该代码显示此消息:“The value 'test' is invalid.”。对于必填字段,它只是值为 null,因此单引号之间没有任何内容。
一些人 ( like this guy ) 建议您只需在模型中将属性设置为可为空即可。这不是一个可接受的解决方案。原因之一是:
Error 3031: Problem in mapping fragments starting at line 313:Non-nullable column PostComments.Body in table PostComments is mapped to a nullable entity property.
另外,简单地设置 nullable 将不适用于不可为 null 的类型,例如 int,将 int 切换为 nullable int 是一个令人讨厌的困惑,我什至不会在这里讨论。
底线是,我想自己处理这些来自 EF 的异常,或者至少自定义它生成的消息,但我不知道如何处理。我完全迷路了。我想做的就是自定义一条关于我认为非常简单的模型验证的消息!
最佳答案
正如您所发现的,MVC 正在根据不可为空的类型验证您的模型。这会在您的自定义验证运行之前向 ModelState 添加错误。
我以前遇到过这个问题,通过在 Action 开始时循环遍历 Modelstate 并删除所有内容,然后进行自定义验证来绕过它(糟糕!!)
然后发现即使你没有使用数据注解作为你的主要验证形式,你也可以自定义抛出的消息,方法是在伙伴类中的非空类型中添加[Required,并指定消息。
是这样的:
[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;}
}
}
我已经开始查看 mvc 的流畅验证 (http://fluentvalidation.codeplex.com),他们似乎通过添加行在 application_start() 中解决了 global.asax 中的问题
DataAnnotationsModelValidatorProvider.AddImplicitRequiredAttributeForValueTypes = false;
但我可能错了。
关于c# - 使用 Entity Framework 时处理 ASP.NET MVC 中的必填字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5357808/
SQLite、Content provider 和 Shared Preference 之间的所有已知区别。 但我想知道什么时候需要根据情况使用 SQLite 或 Content Provider 或
警告:我正在使用一个我无法完全控制的后端,所以我正在努力解决 Backbone 中的一些注意事项,这些注意事项可能在其他地方更好地解决......不幸的是,我别无选择,只能在这里处理它们! 所以,我的
我一整天都在挣扎。我的预输入搜索表达式与远程 json 数据完美配合。但是当我尝试使用相同的 json 数据作为预取数据时,建议为空。点击第一个标志后,我收到预定义消息“无法找到任何内容...”,结果
我正在制作一个模拟 NHL 选秀彩票的程序,其中屏幕右侧应该有一个 JTextField,并且在左侧绘制弹跳的选秀球。我创建了一个名为 Ball 的类,它实现了 Runnable,并在我的主 Draf
这个问题已经有答案了: How can I calculate a time span in Java and format the output? (18 个回答) 已关闭 9 年前。 这是我的代码
我有一个 ASP.NET Web API 应用程序在我的本地 IIS 实例上运行。 Web 应用程序配置有 CORS。我调用的 Web API 方法类似于: [POST("/API/{foo}/{ba
我将用户输入的时间和日期作为: DatePicker dp = (DatePicker) findViewById(R.id.datePicker); TimePicker tp = (TimePic
放宽“邻居”的标准是否足够,或者是否有其他标准行动可以采取? 最佳答案 如果所有相邻解决方案都是 Tabu,则听起来您的 Tabu 列表的大小太长或您的释放策略太严格。一个好的 Tabu 列表长度是
我正在阅读来自 cppreference 的代码示例: #include #include #include #include template void print_queue(T& q)
我快疯了,我试图理解工具提示的行为,但没有成功。 1. 第一个问题是当我尝试通过插件(按钮 1)在点击事件中使用它时 -> 如果您转到 Fiddle,您会在“内容”内看到该函数' 每次点击都会调用该属
我在功能组件中有以下代码: const [ folder, setFolder ] = useState([]); const folderData = useContext(FolderContex
我在使用预签名网址和 AFNetworking 3.0 从 S3 获取图像时遇到问题。我可以使用 NSMutableURLRequest 和 NSURLSession 获取图像,但是当我使用 AFHT
我正在使用 Oracle ojdbc 12 和 Java 8 处理 Oracle UCP 管理器的问题。当 UCP 池启动失败时,我希望关闭它创建的连接。 当池初始化期间遇到 ORA-02391:超过
关闭。此题需要details or clarity 。目前不接受答案。 想要改进这个问题吗?通过 editing this post 添加详细信息并澄清问题. 已关闭 9 年前。 Improve
引用这个plunker: https://plnkr.co/edit/GWsbdDWVvBYNMqyxzlLY?p=preview 我在 styles.css 文件和 src/app.ts 文件中指定
为什么我的条形这么细?我尝试将宽度设置为 1,它们变得非常厚。我不知道还能尝试什么。默认厚度为 0.8,这是应该的样子吗? import matplotlib.pyplot as plt import
当我编写时,查询按预期执行: SELECT id, day2.count - day1.count AS diff FROM day1 NATURAL JOIN day2; 但我真正想要的是右连接。当
我有以下时间数据: 0 08/01/16 13:07:46,335437 1 18/02/16 08:40:40,565575 2 14/01/16 22:2
一些背景知识 -我的 NodeJS 服务器在端口 3001 上运行,我的 React 应用程序在端口 3000 上运行。我在 React 应用程序 package.json 中设置了一个代理来代理对端
我面临着一个愚蠢的问题。我试图在我的 Angular 应用程序中延迟加载我的图像,我已经尝试过这个2: 但是他们都设置了 src attr 而不是 data-src,我在这里遗漏了什么吗?保留 d
我是一名优秀的程序员,十分优秀!