ASP.NET - 如何使用实体框架构建 MVC3 模型和视图?
我是 ASP.NET 的新手,所以我的问题可能很愚蠢,并且受到多年使用 Java/JSF 的影响。
我想使用 ASP.NET 以及 MVC3 和 Entity Framework 4.1 来实现一个 Web 应用程序。由于它是一个业务应用程序,因此应该通过防止数据操纵和并发来保证安全。
因此,我计划使用实体框架支持的乐观锁定。但是,当谈到使用 MVC 范例及其提供的选项时,我不确定如何实现上述安全方面的要求。
示例
我有一个实体类型为“customer”的域模型,其属性为
- ID(数据库 PK)、
- 名称、
- 生日、
- 版本(用于乐观锁定),
以便为视图准备编辑其数据,我还使用具有以下属性的视图模型“customerView”
- 名称
在控制器中,我从数据库加载特定记录,将值传输到视图模型并将其放入强类型视图中。这非常有效 - 值显示在网络表单中,我可以发回更改。由于视图模型不包含 ID 和版本(导致不属于回发的一部分),因此我无法将值映射回域模型,因为它在请求-响应-生命周期期间丢失了。
当然,我可以将 ID 和版本添加为隐藏输入字段,我希望避免这种情况,因为它启用了数据操作。有人可能会在发回数据之前更改 ID 或版本,这可能会导致意外的行为,因为我无法将发送回服务器的数据与传递到 Web 表单的数据(尤其是 ID 和版本)进行比较。
我认为一种方法是存储在会话中显示编辑视图之前获取的数据记录/域模型(或至少是记录的 ID),以避免来回发送不需要的字段,尽管我知道这不是最佳方式,可能会影响应用程序性能。使用默认会话状态之外的另一种会话状态(例如 SQL Server)怎么样?这将能够保存至少一个数据库操作,因为我不必再次从数据库加载记录以便从视图模型传输值。我可以从会话中获取域模型记录,甚至可以检查数据操作。
我希望这个例子能够说明我面临的问题。
也许有更好的方法来解决这些问题。也许我完全困惑了;)
I am new to ASP.NET, so my question may be silly and influenced by years of using Java/JSF.
I want to implement a web application using ASP.NET with MVC3 and the Entity Framework 4.1. As it is a business application it should be secure by means of preventing data manipulation and by means of concurrency.
Thus I planned using optimistic locking which the Entity Framework supports. But when it comes to using the MVC paradigm and the options that it offers, I am not sure how to fulfill the security aspects named above.
Example
I have a domain model with an entity type "customer" which has the attributes
- ID (Database PK)
- Name
- Birthday
- Version (used for optimistic locking)
In order to prepare it for a view to edit its data, I additionally use a view model "customerView" with the following attributes
- Name
In the controller I load a specific record from the database, transfer the values to the view model and put it into a strongly typed view. This works great - the value is shown in the web form and I am able to post back the changes. As the view model does not include the ID and the version (resulting in not being part of the postback), I am not able to map the values back to the domain model as it got lost during the request-response-lifecyle.
Surely, I can add the ID and the version as hidden input field which I'd like to avoid as it enabled for data manipulation. Someone could change the ID or version before posting the data back, which might result in unwanted behaviour as I am not able to compare the data send back to the server with the one delivered to the web form (especially ID and version).
I think one way would be to store the data record/domain model (or at least the record's ID) I fetched before displaying the edit view in the session in order to avoid sending unwanted fields back and forth, though I know that this is not the best way and might influence application performance. What about using another session state then the default one, e.g. SQL Server? This would enable for saving at least one database operation as I don't have to load the record from the database another time in order to transfer the values from the view model. I can get the domain model record from the session and even might check for data manipulation.
I hope the example illustrates the problems I am facing.
Maybe there is an even better way to approach these issues. Maybe I am totally confused ;)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
当谈到竞争条件时,首先要问的问题应该是:并发活动实际上导致无效记录的概率是多少?
在您的情况下:如果您有一个 ID、姓名的客户和生日 我无法想到两个并发用户同时编辑客户并输入不同数据的常见场景。为什么一个用户输入一个姓名或生日,而其他人同时输入不同的姓名或生日?
我想说的是:在大多数情况下,与锁定和类似保护手段带来的可用性和性能方面的努力和损失相比,问题的可能性可以忽略不计。
关于该主题的一篇非常好的文章:竞争条件不存在乌迪·达汉 (Udi Dahan)
When it comes to race conditions the first question to ask should be: What is the probability of a concurrent activity that actually leads to an invalid record?
In your case: If you have a Customer with ID, Name, and Birthday I can't think of a common scenario where two concurrent users would edit the customer at the very same time AND enter different data. Why would one user enter one name or birthday and somebody else enter a different name or birthday at the same time?
What I want to say: In most cases the probability of the issue is negligible compared to the effort and loss of usability as well as performance that comes with locking and similar means of protection.
A very good article on the topic: Race Conditions Don't Exist by Udi Dahan
您必须在视图中包含您的 ID,没有其他方法。至于数据操作 - 您必须检查(在每次保存时)是否允许用户使用此 ID 修改对象。
版本时间戳也是如此,但在这种情况下,您不必担心数据操作,因为数据库中几乎没有手动生成匹配的时间戳,如果它们不匹配,则不会进行编辑,因此您很安全。 或者,当您传递正在编辑的每个字段的原始值时,您可以切换执行其他并发检查方案。
You'll have to include your ID in your view, there's no other way. As for data manipulation - you'll have to check (on every save) that user is allowed to modify object with this ID.
The same goes for version stamp, but in this case you don't have to worry about data manipulation, because there's practically no manually generate timestamp matching one in database, and if they don't match there'll be no edit, so you're safe. Or you can switch do other concurrency checking scenario, when you pass original values of every field being edited.