2012-05-25 25 views
2

我有一个Web应用程序:ExtJs前端 - EntityFramework + SQL Server作为后端。让我们来看看错误情况之一:实体框架。如何正常报告SQL约束错误

  • 我有数据库约束的用户名(名称必须是唯一的)
  • 我没有为任何客户端验证(我应该是有办法吗?使这种验证通用?)
  • 如果我尝试插入用户具有相同的名称服务器返回500错误。
  • 如果我在同一台机器上运行它IIS是 - 我得到完整的错误消息(与键冲突等基本SQL异常说明),如果我从其他机器运行它 - 我只是得到500错误和错误消息。

什么是处理这个最好的方法?我需要以某种人类可读的格式告诉用户有关错误的信息。我真的不想在IIS上打开错误消息,因为这不是一个好习惯。

回答

2

我认为你在这里没有错误,但违反了商业规则。

我喜欢来区分他们两个,是第一部分意外情况(如数据库连接如损失)以及后来的一些场景,你知道它可能发生。

对于错误,我认为合适的是以通用的方式通知用户(例如,“出现意外错误”),因为它的用户不能纠正或不需要详细信息。

在另一方面,业务规则是什么,用户可能了解并能采取措施纠正(在这里,用户名约束)。所以它应该被通知给用户。

在我工作的项目,我们有一个类型的异常,BusinessException的。我们用一条消息来说明它是什么问题,并以可读的格式呈现。我们不明确地尝试捕获这些异常,但使用处理程序来管理它们。如果您使用的是MVC,那么您可以在其中添加一个扩展挂钩。

对于其他类型的异常,它是一个记录栈跟踪(即EventViewer)的好习惯,但不会给用户提供详细信息。

在这种情况下,我会做到以下几点:

  • 有一个按钮检查名称允许用户预先确认的名称。
  • 验证名称的地方取决于您希望具有应用程序业务逻辑的位置。在数据库上,使用存储过程是一种方法,但如果您使用EF,这意味着您想从数据访问中进行抽象。相反,你可以自己写这个验证,使用LINQ(类似于Context.Users.SingleOrDefault(x => x.Name == name)),然后检查它是否返回null或者某个用户。你可能认为这个验证不是必须的,因为你已经有了DB约束,但是这样做,逻辑
  • 从EF中捕获异常可能很麻烦,因为您需要检查SQL错误代码以确定它是否违反约束条件或其他错误。即使您确定这一点,您也需要转换该消息到用户友好的一个。

我希望这可以帮助你在你的决定!

+0

谢谢你这样的完整答案。正如你所说,我将研究LINQ验证。我完全同意你的'企业对内部'的错误观点 – sha

1

首先,我建议你必须确认提交到服务器的客户端上,通过向用户提供即时反馈之前,是一个很好的经验。

其次,您可以考虑为实际的插入,我有使用几个几个选项:

  1. 使用存储过程,做了检查,插入并返回新纪录确认为成功插入,这是容易做到的事务和处理存储过程中的所有问题,但是现在你有功能坐着的已编译代码之外
  2. 在你插入过程裹先打电话验证的交易,并处理它适当地提供你使用编译代码和外部依赖关系的复杂性就像存储过程一样,但是你有一些限制类型从该层,但可行
  3. 尝试事务锁的第插入和捕获异常,并用它适当地处理,这是我最不喜欢

我没有看到你提到的更新UserName,如果您确实允许使用此功能,则在更新之前您必须进行验证,以及由于插入时出现的相同问题。

+0

我同意客户端验证。我真的不想拥有数百个存储过程,并且我想在EntityFramework中以某种方式使用通用方法来返回可接受的错误。你知道这样吗?我的意思是我没有事件可以访问CommitChanges函数(我用它来执行此操作) - EF将所有内容自动传输到InsertXXXX/UpdateXXX。 – sha

1

我没有任何客户端验证(我应该吗?有 方式来使这种验证通用?)

我会永远这样做。你可以使用jquery ajax来调用服务器页面并检查那里的数据。这让用户知道,即使点击提交按钮,用户名也不可用。这给了更好的用户体验。这种方法避免了另一台服务器往返(所有表单数据的正常形式发布,然后收到错误)

服务器,如果我尝试使用相同的名称插入用户返回500错误。

总是在您的代码中发现异常,并且将其记录为。向用户显示关于错误的友好信息。切勿向最终用户显示异常的Stacktrace。如果您使用的是ASP.NET,请使用自定义错误页面功能。