Windows Azure数据库实体框架DbContext和MergeOptions。

时间:2021-02-02 09:37:12

I have a web role hosting a Unity3D application. In the application I have a connection screen. Like any other connection screen you can fill your login and password to access the core of the application (a game for example).

我有一个web角色托管Unity3D应用程序。在应用程序中,我有一个连接屏幕。与任何其他连接屏幕一样,您可以填写登录和密码以访问应用程序的核心(例如,一个游戏)。

All of those information are stored in a Windows Azure Database and I can create user using an admin panel. This panel is hosted in another Web Role and can access the database.

所有这些信息都存储在Windows Azure数据库中,我可以使用管理面板创建用户。这个面板托管在另一个Web角色中,可以访问数据库。

If I create a new user, I can connect with those information in my application. There is no problem. But now if I want to change the user password using the admin panel the value is well changed in the database but in my application I can't connect with the new password, the old one is always used.

如果我创建一个新用户,我可以在我的应用程序中连接这些信息。没有问题。但是现在如果我想使用管理面板来修改用户密码,这个值会在数据库中得到很好的改变,但是在我的应用程序中,我无法连接新密码,旧密码总是被使用。

The user creation and password change are done with the Razor Entity Framework.

用户创建和密码更改是使用Razor实体框架完成的。

I don't understand because in my Unity3D application I do a request to the web role and the user controller and the role returns the old password and not the new one. But in my db and my admin panel there is the new one... How can this be ? How can I solve this ?

我不明白,因为在我的Unity3D应用程序中,我对web角色和用户控制器做了一个请求,而角色返回的是旧密码,而不是新密码。但在我的数据库和管理面板中有一个新的…这怎么可能呢?我怎么解决这个问题呢?

Is it a Response caching problem ?

是响应缓存问题吗?

How I find and return User:

如何查找和返回用户:

DatabaseContext db = DatabaseContextProvider.WebDatabase;
string login = Request.Form["login"]; //The login typed by user
var users = from u in db.Users where u.Login == login select u;
User[] userArray = users.ToArray<User>();

Then I fill the Response to Unity3D with some Header like
Response.AddHeader("data", userArray[0].data.ToString());

然后我用一些像响应这样的标题填充Unity3D的响应。AddHeader(“数据”,userArray[0].data.ToString());

If you need any information that can help you solving my problem, just ask.

如果你需要任何可以帮助你解决我的问题的信息,只要问。

Thanks a lot for your help !

非常感谢您的帮助!

2 个解决方案

#1


1  

Found the problem, this was caused by Entity Framework :
Entity Framework and DbContext - Object Tracking
http://msmvps.com/blogs/kevinmcneish/archive/2010/02/16/setting-entity-framework-mergeoptions-what-works-what-doesn-t.aspx

发现了问题,这是由实体框架引起的:实体框架和DbContext -对象跟踪http://msmvps.com/blogs/kevinmcneish/archive/2010/02/16/settingentityframework - what-works-what-- what-work -what-do -what-do -what-do -what- did .aspx。

Before

之前

DatabaseContext db = DatabaseContextProvider.WebDatabase;
string login = Request.Form["login"];
var users = from u in db.Users where u.Login == login select u;
User[] userArray = users.ToArray<User>();

Now

现在

DatabaseContext db = DatabaseContextProvider.WebDatabase;
string login = Request.Form["login"];
ObjectContext objectContext = ((IObjectContextAdapter)db).ObjectContext;
ObjectSet<User> set = objectContext.CreateObjectSet<User>();
set.MergeOption = MergeOption.OverwriteChanges;
var users = from u in set where u.Login == login select u;
User[] userArray = users.ToArray<User>();

@Sandrino Di Mattia : Thanks for helping me finding the answer !

@Sandrino Di Mattia:谢谢你帮我找到答案!

#2


0  

If you can see the new password in the database but the controller returns the old password try to disable caching by creating the following ActionFilter and adding it to your Action returning the password (as described here):

如果您可以在数据库中看到新密码,但是控制器返回旧密码,尝试通过创建以下ActionFilter来禁用缓存,并将其添加到操作返回密码(如此处所述):

public class NoCacheAttribute : ActionFilterAttribute
{  
    public override void OnResultExecuting(ResultExecutingContext filterContext)
    {
        filterContext.HttpContext.Response.Cache.SetExpires(DateTime.UtcNow.AddDays(-1));
        filterContext.HttpContext.Response.Cache.SetValidUntilExpires(false);
        filterContext.HttpContext.Response.Cache.SetRevalidation(HttpCacheRevalidation.AllCaches);
        filterContext.HttpContext.Response.Cache.SetCacheability(HttpCacheability.NoCache);
        filterContext.HttpContext.Response.Cache.SetNoStore();

        base.OnResultExecuting(filterContext);
    }
}

And just on the side, why are you returning the password? The username/password validation should happen server side and should simply return true/false or a token after authentication succeeds. Returning passwords (even if hashed) is not a good idea from a security point of view.

另外,为什么要返回密码呢?用户名/密码验证应该发生在服务器端,在验证成功后,应该返回true/false或令牌。从安全的角度来看,返回的密码(即使是散列的)并不是一个好主意。

#1


1  

Found the problem, this was caused by Entity Framework :
Entity Framework and DbContext - Object Tracking
http://msmvps.com/blogs/kevinmcneish/archive/2010/02/16/setting-entity-framework-mergeoptions-what-works-what-doesn-t.aspx

发现了问题,这是由实体框架引起的:实体框架和DbContext -对象跟踪http://msmvps.com/blogs/kevinmcneish/archive/2010/02/16/settingentityframework - what-works-what-- what-work -what-do -what-do -what-do -what- did .aspx。

Before

之前

DatabaseContext db = DatabaseContextProvider.WebDatabase;
string login = Request.Form["login"];
var users = from u in db.Users where u.Login == login select u;
User[] userArray = users.ToArray<User>();

Now

现在

DatabaseContext db = DatabaseContextProvider.WebDatabase;
string login = Request.Form["login"];
ObjectContext objectContext = ((IObjectContextAdapter)db).ObjectContext;
ObjectSet<User> set = objectContext.CreateObjectSet<User>();
set.MergeOption = MergeOption.OverwriteChanges;
var users = from u in set where u.Login == login select u;
User[] userArray = users.ToArray<User>();

@Sandrino Di Mattia : Thanks for helping me finding the answer !

@Sandrino Di Mattia:谢谢你帮我找到答案!

#2


0  

If you can see the new password in the database but the controller returns the old password try to disable caching by creating the following ActionFilter and adding it to your Action returning the password (as described here):

如果您可以在数据库中看到新密码,但是控制器返回旧密码,尝试通过创建以下ActionFilter来禁用缓存,并将其添加到操作返回密码(如此处所述):

public class NoCacheAttribute : ActionFilterAttribute
{  
    public override void OnResultExecuting(ResultExecutingContext filterContext)
    {
        filterContext.HttpContext.Response.Cache.SetExpires(DateTime.UtcNow.AddDays(-1));
        filterContext.HttpContext.Response.Cache.SetValidUntilExpires(false);
        filterContext.HttpContext.Response.Cache.SetRevalidation(HttpCacheRevalidation.AllCaches);
        filterContext.HttpContext.Response.Cache.SetCacheability(HttpCacheability.NoCache);
        filterContext.HttpContext.Response.Cache.SetNoStore();

        base.OnResultExecuting(filterContext);
    }
}

And just on the side, why are you returning the password? The username/password validation should happen server side and should simply return true/false or a token after authentication succeeds. Returning passwords (even if hashed) is not a good idea from a security point of view.

另外,为什么要返回密码呢?用户名/密码验证应该发生在服务器端,在验证成功后,应该返回true/false或令牌。从安全的角度来看,返回的密码(即使是散列的)并不是一个好主意。