HOWTO:如何分别把每个用户的自定义模型数据保存到数据库

HOWTO:如何分别把每个用户的自定义模型数据保存到数据库

英文原文地址:<http://www.devexpress.com/Support/Center/KB/p/K18137.aspx>

 

 

Description:
By default, an XAF Windows Forms application stores users' customizations in the Model.User.xafml file, located in the application's directory. If the application is localized into several languages, an additional file, named Model.User.xafm postfixed by the language identifier may exist for each language. In certain scenarios, this approach may be inappropriate in the following cases:

 在默认的情况,XAF在WINDOWS FORM 应用程序把每个用户的自定义模型文件(Model.User.xafml)保存在应用程序目录下面.如果应用程序有多种本地化语言,会在每种语言的模型文件后面加上语言ID,但在实际使用中会出现下列一些情况,使这个方法不是很适用:

1. If two or more users share the same copy of the application, their customizations (e.g. to the UI) get overwritten. For instance, user A logs on, reorders columns in a certain List View and logs off. Then, user B does the same. User A launches the application and finds that the customizations are gone.
Note: Using the configuration file, you can specify that the Model.User.xafml must be saved to the current Windows user's ApplicationData folder (C:\Documents and Settings\username\Application Data). But, if users launch the application using the same Windows logon, the above still applies.

1:如果有二个或多个用户共同使用一台电脑上的应用程序,他们的自定义文件会相互覆盖.如:用户A登录系统,在一个列表中定义了一个列并且退出,用户B是不一样的设置,用户A的应用程序设置就会被覆盖

备注:在配置文件中,你可以指定Model.User.xafml 必须保存在当前WINDOWS用户的ApplicationData 目录下面(C:\Documents and Settings\username\Application Data),但是,如果所有的用户都使用同一个WINDOWS用户登录,上面的情况依旧会发生.

2. Since the Model.User.xafml file is stored in the plain XML format, anyone who has access to it, can easily influence the work of the application. For instance, it is possible to affect a critical setting that will cause the application to stop functioning.

This article illustrates how to resolve these issues by storing each user's customizations separately in the database.

Note:
In XAF ASP.NET Web applications, users' customizations aren't stored anywhere by default. You can store the customizations made to List Views in the web browser cookies by setting the SaveListViewStateInCookies property of the Application | Options node or SaveStateInCookies property of the Application | Views | ListView nodes to true.

2:由于Model.User.xafml 文件保存的文件格式是XML格式,所以任何人都可以修改他,用户可以很容易的修改影响应用程序...如:用户可能去修改一个条件字符串,导致应用程序的一些权限判断失效.

这一举例说明了为何要把每一个客户的自定义文件保存到数据库的原因.

备注:

在XAF ASP.NET 的WEB应用程序中,用户的自定义文件是默认是不会被保存的.你可以把列表的自定义信息保存在浏览器的cookies中,设置Application | Options节点中的SaveListViewStateInCookies属性或是Application | Views | ListView 节点下的SaveStateInCookies 属性为TRUE.

 

To begin, create a new Windows Forms XAF application solution named "UserDiffsToDB". Using the Application Designer, set the authentication type to the standard authentication, the security strategy to the Security Simple and the Security System's user class type to SimpleUser.

新建一个WINFOWS FORM 的XAF的应用程序,名称为:UserDiffsToDB,使用应用程序设计器,把认证模式的标准认证模块,设置安全系统的用户类型为 SimpleUser

<注:打开应用程序设计器,把Security Complex 和Authention Standard二块模块新增到安全认证上面.点击:Security Complex,属性窗体.有 一个UserType 选择 SimpleUser,如果已经选择了其他的用户类型,如User,则只要把下列代码中的SimpleUser更改成对应的用户类型就可以了>

1. Define the Persistent Classes Used to Store User Model Differences

1:定义用于保存每个用户自定义模型的持久类.

To store users' Model differences in the database, we use two persistent classes - the XmlUser and XmlStore. An XmlStore object stores a user's Model differences for one language. An XmlUser object stores a user's identifier and a collection of XmlStore objects. To retrieve the identifier of the currently logged on user, we use the SecuritySystem.CurrentUser property. This property returns the user class instance that represents the currently logged on user. In this example, we have the SimpleUser class set as the Security System's user type. If you use another user class, change the User type as required.

We decorate both classes with the Browsable(false) attribute, so that they aren't displayed in the UI and the Model Editor.

Add a new XmlStorage.cs (XmlStorage.vb) file to the UserDiffsToDB.Module project using the Domain Object template. Copy the following code to the XmlStorage file.

为了保存每个用户不同的模型信息到数据库中,我们需要用到二个持久类:XmlUserXmlStore,XmlStore对象保存每个用户每种语言的自定义模型信息.XmlUser  对象保存每个用户的主键并且有一个XmlStore的对象集合.我们使用SecuritySystem.CurrentUser 属性取得当前登录用户的主键.这个属性返回当前登录用户类的实例.在这个实例中,我们设置了SimpleUser  类为Security System的用户类型,如果你使用了其他的用户类型,就需要更改相应的用户类型设置.

把二个类的Browsable(false) 属性加上,这样它们就不会显示在界面和模型设计器中.

新增一个Domain Object 类型的 XmlStorage.cs文件到 UserDiffsToDB.Module 工程.复制下列代码..

 

ExpandedBlockStart.gif 代码
using  System;
using  System.ComponentModel;

using  DevExpress.Xpo;
using  DevExpress.ExpressApp;
using  DevExpress.Persistent.Base;
using  DevExpress.Persistent.BaseImpl;
using  DevExpress.Persistent.Validation;

namespace  UserDiffsToDB.Module {
    [Browsable(
false )]
    
public   class  XmlUser : BaseObject {
        
public  XmlUser(Session session) :  base (session) { }

        
public  SimpleUser User {
            
get  {  return  GetPropertyValue < SimpleUser > ( " User " ); }
            
set  { SetPropertyValue( " User " , value); }
        }

        [Association(
" XmlUser-Aspects " ), Aggregated]
        
public  XPCollection < XmlStore >  Aspects {
            
get  {  return  GetCollection < XmlStore > ( " Aspects " ); }
        }
    }

    [Browsable(
false )]
    
public   class  XmlStore : BaseObject {
        
public  XmlStore(Session session) :  base (session) { }

        [Association(
" XmlUser-Aspects " )]
        
public  XmlUser User {
            
get  {  return  GetPropertyValue < XmlUser > ( " User " ); }
            
set  { SetPropertyValue( " User " , value); }
        }

        
public   string  Aspect {
            
get  {  return  GetPropertyValue < string > ( " Aspect " ); }
            
set  { SetPropertyValue( " Aspect " , value); }
        }

        [Size(SizeAttribute.Unlimited)]
        
public   string  XmlData {
            
get  {  return  GetPropertyValue < string > ( " XmlData " ); }
            
set  { SetPropertyValue( " XmlData " , value); }
        }
    }
}

 

 

2. Handle User Model Differences

In an XAF application, saving and loading of a user's Model differences is performed by a descendant of the abstract ModelDifferenceStore class. The two most important members of this class are the SaveDifference and Load methods. The Load method loads a user's Model differences. The SaveDifference method takes a user's Model differences as a parameter and saves them to a storage. By default, an XAF application uses an instance of the FileModelStore class. This class stores a user's Model differences in an XML file. Since we need to store the differences in the database, we implement a custom storage class that inherits from the ModelDifferenceStore class - the UserStore class.

在XAF应用程序中,保存和加载用户自定义模型文件是通过抽象类:ModelDifferenceStore 的子类来实现的.SaveDifferenceLoad 方法是二个最为重要的方法,Load 方法加载用户自定义模式,SaveDifference 方法提供一个用户自定义模型的参数并且自动保存.默认的,XAF应用程序使用FileModelStore 类的实例.这个类保存用户自定义模型到一个XML文件中,因为我们要保存自定义模型到数据库中.所以我们需要继承于ModelDifferenceStore 类 实现一个自定义保存的类:UserStore 类.

To make the application use our custom class, we handle the WinApplication.CreateCustomUserModelDifferenceStore event. This event is raised after a user has been authenticated. It allows us to specify an instance of the ModelDifferenceStore class descendant that will be used for saving and loading of a user's Model differences. We set the handler's Handled parameter to true, to cancel the creation of the default storage class instance.

为了使应用程序使用自定义保存类,我们需要调用WinApplication.CreateCustomUserModelDifferenceStore 事件.这个事件在用户认证完成后产生,此事件允许指定一个ModelDifferenceStore 类子类的实例来进行自定义模型的加载和保存.我们可以设置事件的Handled 参数=TRUE 来禁止默认存储类的实例的生成.

Copy the following code to the Program.cs (Program.vb) file of the UserDiffsToDB.Win project.

复制下列代码到工程:UserDiffsToDB.Win中的Program.cs 文件中.


 

ExpandedBlockStart.gif 代码
using  System;
using  System.Configuration;
using  System.Windows.Forms;

using  DevExpress.Xpo;
using  DevExpress.Data.Filtering;
using  DevExpress.ExpressApp;
using  DevExpress.ExpressApp.Security;
using  DevExpress.ExpressApp.Win;
using  DevExpress.Persistent.Base;
using  DevExpress.Persistent.BaseImpl;

using  UserDiffsToDB.Module;
using  DevExpress.ExpressApp.Model.Core;
using  DevExpress.ExpressApp.Model;


namespace  UserDiffsToDB.Win {
    
static   class  Program {
        
///   <summary>
        
///  The main entry point for the application.
        
///   </summary>
        [STAThread]
        
static   void  Main() {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(
false );
            EditModelPermission.AlwaysGranted 
=  System.Diagnostics.Debugger.IsAttached;
            UserDiffsToDBWindowsFormsApplication winApplication 
=   new
UserDiffsToDBWindowsFormsApplication();
            winApplication.CreateCustomUserModelDifferenceStore 
+=   new
EventHandler
< CreateCustomModelDifferenceStoreEventArgs > (winApplication_CreateCustomUserModelDifferenceStore);
            
if  (ConfigurationManager.ConnectionStrings[ " ConnectionString " !=   null ) {
                winApplication.ConnectionString 
=
ConfigurationManager.ConnectionStrings[
" ConnectionString " ].ConnectionString;
            }
            
try  {
                winApplication.Setup();
                winApplication.Start();
            }
            
catch  (Exception e) {
                winApplication.HandleException(e);
            }
        }

        
static   void  winApplication_CreateCustomUserModelDifferenceStore( object  sender,
CreateCustomModelDifferenceStoreEventArgs e) {
            UserStore userDiffs 
=   new  UserStore((WinApplication)sender);
            e.Store 
=  userDiffs;
            e.Handled 
=   true ;
        }

        
public   class  UserStore : ModelDifferenceStore {
            
private   static   readonly   string  xmlHeader  =
                
" <?xml version=\ " 1.0 \ "  encoding=\ " utf - 8 \ " ?> "   +  System.Environment.NewLine;
            
private  WinApplication application;

            
public   override   string  Name {
                
get  {
                    
return   " UserStore " ;
                }
            }

            
public  UserStore(WinApplication winApplication) {
                application 
=  winApplication;
            }

            
private  XmlStore FindStoreByAspect(XPCollection < XmlStore >  stores,  string  aspect) {
                
foreach  (XmlStore store  in  stores) {
                    
if  (store.Aspect  ==  aspect)  return  store;
                }
                
return   null ;
            }

            
private  XmlUser FindXmlUserByCurrentUser() {
                ObjectSpace objectSpace 
=  application.CreateObjectSpace();
                SimpleUser currentUser 
=  objectSpace.GetObject((SimpleUser)SecuritySystem.CurrentUser);
                XmlUser user 
=  objectSpace.FindObject < XmlUser > (
                    
new  BinaryOperator( " User " , currentUser, BinaryOperatorType.Equal));
                
return  user;
            }

          
public   override   void  Load(ModelApplicationBase model) {
                ModelXmlReader xmlReader 
=   new  ModelXmlReader();
                XmlUser user 
=  FindXmlUserByCurrentUser();
                
if (user  !=   null ) {
                    
foreach (XmlStore store  in  user.Aspects) {
                        xmlReader.ReadFromString(model, store.Aspect, store.XmlData);
                    }
                }
            }

            
public   override   void  SaveDifference(ModelApplicationBase model) {
                ObjectSpace objectSpace 
=  application.CreateObjectSpace();
                XmlUser user 
=  objectSpace.GetObject(FindXmlUserByCurrentUser());
                
if (user  ==   null ) {
                    user 
=   new  XmlUser(objectSpace.Session);
                    user.User 
=  objectSpace.GetObject((SimpleUser)SecuritySystem.CurrentUser);
                }
                
for ( int  i  =   0 ; i  <  model.AspectCount;  ++ i) {
                    ModelXmlWriter xmlWriter 
=   new  ModelXmlWriter();
                    
string  aspect  =  model.GetAspect(i);
                    
string  xmlContent  =  xmlWriter.WriteToString(model, i);
                    
if ( ! string .IsNullOrEmpty(xmlContent)) {
                        XmlStore store 
=  FindStoreByAspect(user.Aspects, aspect);
                        
if (store  ==   null )
                            store 
=   new  XmlStore(objectSpace.Session);
                        store.User 
=  user;
                        store.Aspect 
=  aspect;
                        store.XmlData 
=  xmlHeader  +  xmlContent;
                    }
                }
                objectSpace.CommitChanges();
            }
        }
    }
}

 

 

3. Populate the Database with Sample Data

3:在数据库中新增实例数据...

To be able to log on to the application, a user must be created. To do so, copy the following code to the Updater.cs (Updater.vb) file of the UserDiffsToDB.Module project. This code snippet creates two users, named "John" and "Sam" with empty passwords. "Sam" has the administrative rights, "John" doesn't.

 为了能够登录进程序,必须先要建立用户.为了实现这个功能,复制下列代码到工程:UserDiffsToDB.Module的Updater.cs文件中.

这些代码会创建二个密码为空的用户:John和 Sam.  SAM有管理员的权限,JOHN不是...

 

ExpandedBlockStart.gif 代码
using  System;

using  DevExpress.ExpressApp.Updating;
using  DevExpress.Xpo;
using  DevExpress.Data.Filtering;
using  DevExpress.Persistent.BaseImpl;

namespace  UserDiffsToDB.Module {
    
public   class  Updater : ModuleUpdater {
        
public  Updater(Session session, Version currentDBVersion) :  base (session, currentDBVersion) { }
        
public   override   void  UpdateDatabaseAfterUpdateSchema() {
            
base .UpdateDatabaseAfterUpdateSchema();

            SimpleUser adminUser 
=  Session.FindObject < SimpleUser > ( new  BinaryOperator( " UserName " " Sam " ));
            
if  (adminUser  ==   null ) {
                adminUser 
=   new  SimpleUser(Session);
                adminUser.UserName 
=   " Sam " ;
                adminUser.FullName 
=   " Sam " ;
            }
            adminUser.IsAdministrator 
=   true ;
            adminUser.SetPassword(
"" );
            adminUser.Save();

            SimpleUser user 
=  Session.FindObject < SimpleUser > ( new  BinaryOperator( " UserName " " John " ));
            
if  (user  ==   null ) {
                user 
=   new  SimpleUser(Session);
                user.UserName 
=   " John " ;
                user.FullName 
=   " John " ;
            }
            user.IsAdministrator 
=   false ;
            user.SetPassword(
"" );
            user.Save();
        }
    }
}

 

 

After creating the sample users you can logon using different credentials and customize the application. For instance, you can change the active skin for each user. Different users will have different active skins. Since users' Model differences are stored in the database, the Model.User.xafml file won't be created.

 

建立完成示例用户后,可以使用不同的用户进行登录并且进行自定义应用程序.如:你可以为每一个用户更改当前的外观 ,不同的用户有不同的外观,因为用户自定义模型被保存到数据库中,所以Model.User.xafml 是不会被建立的.....


 

 

转载于:https://www.cnblogs.com/flxa/archive/2010/11/06/1870660.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值