WCF 数据服务/实体框架:记录客户端的用户名、身份验证、授权
我正在使用带有 WCF 数据服务的实体框架,并且我的数据库中有下表:
表 Contract
- Id (int)
- Name (varchar)
- byUser (varchar)
- isDeleted (bit)
Entity Framework class
- Id (int)
- Name(string)
- byUser( string)
- isDeleted(boolean)
每当用户插入/更新/删除合同(通过客户端应用程序)时,我需要记录谁执行了该操作。
因此,我创建了用于插入/更新/删除的存储过程,当执行插入/删除/更新时,它将从客户端接收用户名。
问题是删除操作不会发送谁正在执行该操作:
var ctx = Context;
var contractToDelete = ctx.Contracts.Where(c => c.ContractId == 1).First();
contractToDelete.ByUser = username;
ctx.DeleteObject(contractToDelete);
ctx.SaveChanges();
在服务器端,byUser 始终为空。
问题:
1)如何将 byUser 参数发送到服务器?
2)有没有更好的方法来处理这种情况?使用实体框架(日志记录/身份验证/授权)
I am using Entity Framework with WCF Data Services and I have the following table in my database :
Table Contract
- Id (int)
- Name (varchar)
- byUser (varchar)
- isDeleted (bit)
Entity Framework class
- Id (int)
- Name(string)
- byUser(string)
- isDeleted(boolean)
whenever the user is inserting/updating/deleting a contract(through a client app), I need to log who did the action.
so, I created Stored procedures for insert/update/delete that will receive the username from the client when an insertion/deletion/update is performed.
the issue is that the delete operation does not send over who is performing the operation :
var ctx = Context;
var contractToDelete = ctx.Contracts.Where(c => c.ContractId == 1).First();
contractToDelete.ByUser = username;
ctx.DeleteObject(contractToDelete);
ctx.SaveChanges();
at the server side, the byUser is always null.
Questions :
1) How do I make it so that the byUser parameter is sent to the server ?
2) Is there a better way to handle this kind of scenario ? (logging/authentication/authorization) with Entity Framework
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我管理此问题的方法是,当我的用户登录时,我将有关他们的基本信息存储在会话中。然后,我有一门课程,它位于我对上下文的操作之上。
每当我提交更改时,我都会执行相同的例程来检查更改的内容。我开发了根据正在处理的实体触发操作的能力(这样我就可以关注合同等内容)。然后我就可以登录用户了。
[编辑]
这比我意识到的更难澄清,但我会尝试。
我正在创建一个网络应用程序。大量使用 Ninject。
当用户登录时,我将他们的信息存储在 IUserSession 对象中(这实际上保存在 Session 中,但自定义 Ninject 作用域使这对我来说很方便,并防止我必须将数据层暴露给 Web Session)。该用户会话对象包含用户名、用户 ID 等。
我创建了一个包含上下文的类,并包装了所有 SELECT、CREATE、DELETE 和 COMMIT 调用。即选择;
该类还有一个 Commit 方法,这是对 SaveChanges 的调用。
在调用 SaveChanges 之前,您可以通过 Context.ChangeTracker.Entities 的形式访问更改
。对于每个发生更改的实体,您可以测试它是否被添加、删除或修改。以获取被修改元素的类型;
我确实计划很快根据我的个人经验编写一个教程(现在对您没有帮助)。
The way I managed this is, when my user logs in, I store basic information about them in the session. I then have a class that sits on top of my actions to context.
Whenever I commit back changes, I go through the same routine which checks what changed. I developed the ability to trigger actions based upon the entity being worked with (so I can keep an eye on something such as contracts). Then I have the user able to be logged.
[Edit]
This is tougher to clarify than I realised, but I'll try.
I'm creating a web application. Heavily using Ninject.
When the user logs in, I store their information in an IUserSession object (this is really held in Session, but a custom Ninject scope makes this neat for me and prevents me from having to expose my data layer to Web Session). This user session object contains username, user id etc.
I created a class that contains the context,and wraps all the SELECT,CREATE,DELETE and COMMIT calls. i.e. SELECT;
This class also has a Commit method, this is the call to SaveChanges.
Before calling SaveChanges, you have access to the changes in the form of Context.ChangeTracker.Entities
For each entity that has changed, you can test to see if it was added, deleted or modified.To get the type of the element being modified;
I do plan on writing up a tutorial soon, based upon my personal experience with doing this (not that that helps you right now).
它不会“总是”发送 null。它始终发送旧值。这是实体框架中的一些内部逻辑。对于每个跟踪对象,EF 都会保留原始值和当前值。当您删除对象时 EF 不使用当前值 - 它使用原始值(不要问我为什么,这就是它的工作原理)。
因此,您需要欺骗 EF:
调用
ApplyOriginalValues
将强制 EF 使用参数中传递的值覆盖原始值 = 您将使用当前值覆盖原始值。在我看来,更好的方法是将已删除的记录存储在单独的表中,因为它将避免将 isDeleted=false 传递给每个查询时出现的许多问题,其中急切加载和延迟加载都会加载已删除的记录。避免
isDeleted
问题的唯一方法是使用条件映射,但在这种情况下,即使您愿意,也无法加载已删除的记录,除非您使用存储过程或直接 SQL 查询。It doesn't send null "always". It sends the old value always. That is some internal logic in entity framework. For each tracked object EF keeps both original and current values. When you are deleting object EF doesn't use current values - it uses original values (don't ask me why, simply this is how it works).
So you need to cheat EF:
Calling
ApplyOriginalValues
will force EF to override original values with values passed in parameter = you will override original values with current values.In my opinion the better way is storing deleted records in separate table because it will avoid a lot of problems with passing
isDeleted=false
to every query where both eager and lazy loading will load deleted records as well. The only way to avoid problems withisDeleted
is using conditional mapping but in such case you will not be able to load deleted records even if you want to unless you use stored procedures or direct SQL queries.