文章出處

主題描述了如何實現一個 WCF 中間應用程序服務器及如何配置 XAF客戶端連接到服務器



注意
主題演示可以解決方案向導自動生成代碼執行操作如果現有的 XAF 解決方案實現顯示功能如果創建一個的 XAF 解決方案使用向導
 
完整樣例項目在 http://www.devexpress.com/example=E4599 

 

 
1.打開現有的 XAF 解決方案啟用安全系統,創建幾個用戶帳戶如果沒有現有解決方案看這里如何創建一個基于客戶端的安全 (2 層架構) 教程
2.向 XAF 解決方案添加一個控制臺應用程序項目這個項目代表示例中的應用程序服務器
3.將引用添加的 XAF 解決方案 (例如,MySolution.Module MySolution.Module.Win  MySolution.Module.Web) 模塊項目右鍵項目,單擊創建新項目,然后在對話框中選擇“添加引用......” 切換項目選項卡選擇模塊項目單擊確定

4.打開創建項目 Program.cs (Program.vb) 文件以下代碼添加 Main 方法 (在示例假定的 XAF 解決方案稱為"MySolution")。

using System;
using System.Collections.Generic;
using System.ServiceModel;
using DevExpress.Persistent.Base;
using DevExpress.Xpo;
using DevExpress.Xpo.DB;
using DevExpress.ExpressApp;
using DevExpress.ExpressApp.MiddleTier;
using DevExpress.ExpressApp.Security;
using DevExpress.ExpressApp.Security.ClientServer;
using DevExpress.ExpressApp.Security.ClientServer.Wcf;
using DevExpress.ExpressApp.Security.Strategy;
using DevExpress.ExpressApp.Web.SystemModule;
using DevExpress.ExpressApp.Win.SystemModule;
using DevExpress.ExpressApp.Xpo;
// ... 
static void Main() {
    try {
        Console.WriteLine("Starting...");
        DataSet dataSet = new DataSet();
        string connectionString = 
            "Integrated Security=SSPI;Pooling=false;Data Source=(local);Initial Catalog=MySolution";
        ValueManager.ValueManagerType = typeof(MultiThreadValueManager<>).GetGenericTypeDefinition();

        ServerApplication serverApplication = new ServerApplication();
        serverApplication.ApplicationName = "MySolution";
        serverApplication.Modules.Add(new MySolution.Module.MySolutionModule());
        serverApplication.Modules.Add(new SystemWindowsFormsModule());
        serverApplication.Modules.Add(new SystemAspNetModule());
        serverApplication.CreateCustomObjectSpaceProvider += delegate(object sender, CreateCustomObjectSpaceProviderEventArgs e) {
            e.ObjectSpaceProvider = new XPObjectSpaceProvider(connectionString, null);
        };
        serverApplication.DatabaseVersionMismatch += delegate(object sender, DatabaseVersionMismatchEventArgs e) {
            e.Updater.Update();
            e.Handled = true;
        };

        Console.WriteLine("Setup...");
        serverApplication.Setup();
        Console.WriteLine("CheckCompatibility...");
        serverApplication.CheckCompatibility();
        serverApplication.Dispose();

        Console.WriteLine("Starting server...");
        QueryRequestSecurityStrategyHandler securityProviderHandler = delegate() {
            return new SecurityStrategyComplex(
                typeof(SecuritySystemUser), typeof(SecuritySystemRole), new AuthenticationStandard());
        };

        IDisposable[] disposable;
        IDataLayer dataLayer = new SimpleDataLayer(XpoTypesInfoHelper.GetXpoTypeInfoSource().XPDictionary, 
                                         DevExpress.Xpo.DB.MSSqlConnectionProvider.CreateProviderFromString(connectionString, 
                                         DevExpress.Xpo.DB.AutoCreateOption.None, out disposable));
        SecuredDataServer dataServer = new SecuredDataServer(dataLayer, securityProviderHandler);

        ServiceHost serviceHost = new ServiceHost(new WcfSecuredDataServer(dataServer));
        serviceHost.AddServiceEndpoint(typeof(IWcfSecuredDataServer), 
            WcfDataServerHelper.CreateDefaultBinding(), "http://localhost:1451/DataServer");
        serviceHost.Open();

        Console.WriteLine("Server is started. Press Enter to stop.");
        Console.ReadLine();
        Console.WriteLine("Stopping...");
        serviceHost.Close();
        Console.WriteLine("Server is stopped.");
    }
    catch(Exception e) {
        Console.WriteLine("Exception occurs: " + e.Message);
        Console.WriteLine("Press Enter to close.");
        Console.ReadLine();
    }
}

 

注意

  1. ServerApplication.ApplicationName 屬性客戶端應用程序名稱 (即 XafApplication.ApplicationName) 相同
  2. ServerApplication.Modules 集合包含客戶應用程序直接引用模塊查看哪些客戶端應用程序要求哪些模塊,可以在 WinApplication/WebApplication 的InitializeComponent方法中找到
  3. QueryRequestSecurityStrategyHandler 對象指定用戶類型 角色類型身份驗證
  4. 服務終結點通過 ServiceHost.AddServiceEndpoint 方法添加
  5. 如果使用自定義權限請求自定義登錄參數在用戶初始化數據服務器之前注冊通過靜態的 WcfDataServerHelper.AddKnownType 方法
  6. 如果使用一個自定義綁定對象不要使用 WcfDataServerHelper.CreateDefaultBinding 方法自己創建綁定對象傳遞ServiceHost.AddServiceEndpoint 方法
  7. 當使用 AuthenticationActiveDirectory 時, all the methods of the application server should be invoked in the caller's context (a Windows account under which the client application is running). Refer to the Delegation and Impersonation with WCF and Security in Remoting articles in MSDN for more details on how this can be done, depending on the transport technology used. For instance, in the case of WCF, you can modify the ServiceAuthorizationBehavior.ImpersonateCallerForAllOperations property in the code of your service.

  8. 打開 Windows 窗體應用程序項目 Program.cs (Program.vb) 文件修改 Main 方法如下所示
using System.ServiceModel;
using DevExpress.ExpressApp;
using DevExpress.ExpressApp.Security;
using DevExpress.ExpressApp.Security.ClientServer;
using DevExpress.ExpressApp.Security.ClientServer.Wcf;
// ... 
[STAThread]
static void Main() {
    Application.EnableVisualStyles();
    Application.SetCompatibleTextRenderingDefault(false);
    EditModelPermission.AlwaysGranted = System.Diagnostics.Debugger.IsAttached;
    MySolutionWindowsFormsApplication winApplication = new MySolutionWindowsFormsApplication();
    string connectionString = "http://localhost:1451/DataServer";
    try {
        WcfSecuredDataServerClient clientDataServer = new WcfSecuredDataServerClient(
            WcfDataServerHelper.CreateDefaultBinding(), new EndpointAddress(connectionString));
        ServerSecurityClient securityClient = new ServerSecurityClient(clientDataServer, new ClientInfoFactory());
        securityClient.IsSupportChangePassword = true;
        winApplication.ApplicationName = "MySolution";
        winApplication.Security = securityClient;
        winApplication.CreateCustomObjectSpaceProvider += delegate(
            object sender, CreateCustomObjectSpaceProviderEventArgs e) {
            e.ObjectSpaceProvider = new DataServerObjectSpaceProvider(clientDataServer, securityClient);
        };
        winApplication.Setup();
        winApplication.Start();
        clientDataServer.Close();
    }
    catch(Exception e) {
        winApplication.HandleException(e);
    }
}
  1. ServerSecurityClient.IsSupportChangePassword 屬性指示可以通過 ChangePasswordByUser  ResetPasswords 操作更改用戶密碼如果服務器使用AuthenticationStandard 身份驗證屬性設置 trueIfAuthenticationActiveDirectory 使用初始化 IsSupportChangePassword 屬性因為默認 false請注意設置影響 ChangePasswordByUser  ResetPasswords 操作可見性不要授予權限用戶的 StoredPassword 屬性創建相應成員級別權限允許非管理用戶更改他們密碼
    • 備注:

      調試服務器主機連接字符串"localhost"更改根據服務器端設置端口(因為默認應用程序項目完成)可以通過配置應用程序對象配置文件讀取連接字符串。為簡單起見在這里連接硬編碼的
      如果使用自定義權限請求自定義登錄參數在用戶客戶端應用程序初始化之前注冊通過靜態的 WcfDataServerHelper.AddKnownType 方法
       
  2. 應用程序服務器正在使用服務器執行兼容性檢查 XafApplication.DatabaseVersionMismatch 的事件發生無條件地引發異常編輯WinApplication.cs (WinApplication.vb) 文件以下方式修改 DatabaseVersionMismatchevent 處理程序
public partial class MySolutionWindowsFormsApplication : WinApplication {
    //... 
   private void MySolutionWindowsFormsApplication_DatabaseVersionMismatch(
        object sender, DevExpress.ExpressApp.DatabaseVersionMismatchEventArgs e) {
        throw new InvalidOperationException(
            "The application cannot connect to the specified database " +
            "because the latter does not exist or its version is older " +
            "than that of the application.");
        }
    }
}

 

 

  1. 編輯 Module.cs (Module.vb) 文件位于平臺無關模塊項目(即你的XXX.Module項目)注冊下列方式使用安全類型。(就是用戶和角色所使用的類型)

using DevExpress.ExpressApp.Security.Strategy;
// ... 
public sealed partial class MySolutionModule : ModuleBase {
    // ... 
    protected override IEnumerable<Type> GetDeclaredExportedTypes() {
        List<Type> result = new List<Type>(base.GetDeclaredExportedTypes());
        result.AddRange(new Type[] { typeof(SecuritySystemUser), typeof(SecuritySystemRole) });
        return result;
    }
}

 

上面代碼要引用 DevExpress.ExpressApp.Security.v15.2 程序集。

 

默認情況下,導航欄中不會顯示角色的列表,這個行為與2層架構不同,如果想要顯示角色列表,需要手動的在xafml中增加角色列表,列表的名稱是:"SecuritySystemRole_ListView"。

 

 
現在可以運行應用服務器客戶端應用程序。在解決方案資源管理器中應用程序服務器項目設置啟動項目,并且運行服務器運行客戶端應用程序右擊解決方案資源管理器應用程序項目然后選擇調試 |啟動實例顯示了服務器客戶端

 

 


文章列表


不含病毒。www.avast.com
arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()