KB Article T570966
Visible to All Users

How to migrate to the new Middle-Tier implementation after upgrading to XAF v17.2+

Version 17.2 has the updated Middle Tier Security implementation. Data is secured on the server, but permission information is passed to the client along with data, so that UI updates are done without extra requests and the client application works faster. When you create a new application with the Solution Wizard 17.2+, the wizard adds the new Middle Tier code automatically. However, if you want to get the benefits of the new approach for an existing project, you'll need to update the Middle Tier Security implementation in your code.

Follow the steps below to manually update the Middle Tier Security implementation in your existing project.

1. Server Application Modifications
In the Program.cs file, find this code:

C#
QueryRequestSecurityStrategyHandler securityProviderHandler = delegate () { SecurityStrategyComplex securityStrategyComplex = new SecurityStrategyComplex(typeof(PermissionPolicyUser), typeof(PermissionPolicyRole), new AuthenticationStandard()); securityStrategyComplex.SupportNavigationPermissionsForTypes = false; return securityStrategyComplex; }; SecuredDataServer dataServer = new SecuredDataServer(connectionString, XpoTypesInfoHelper.GetXpoTypeInfoSource().XPDictionary, securityProviderHandler); ServiceHost serviceHost = new ServiceHost(new WcfSecuredDataServer(dataServer)); serviceHost.AddServiceEndpoint(typeof(IWcfSecuredDataServer), WcfDataServerHelper.CreateNetTcpBinding(), "net.tcp://127.0.0.1:1451/DataServer");
Visual Basic
Dim securityProviderHandler As QueryRequestSecurityStrategyHandler = Function() Dim securityStrategyComplex As New SecurityStrategyComplex(GetType(PermissionPolicyUser), GetType(PermissionPolicyRole), New AuthenticationStandard()) securityStrategyComplex.SupportNavigationPermissionsForTypes = False Return securityStrategyComplex End Function Dim dataServer As New SecuredDataServer(connectionString, XpoTypesInfoHelper.GetXpoTypeInfoSource().XPDictionary, securityProviderHandler) Dim serviceHost As New ServiceHost(New WcfSecuredDataServer(dataServer)) serviceHost.AddServiceEndpoint(GetType(IWcfSecuredDataServer), WcfDataServerHelper.CreateNetTcpBinding(), "net.tcp://127.0.0.1:1451/DataServer")

…and replace it with the following:

C#
Func<IDataServerSecurity> securityProviderHandler = () => new SecurityStrategyComplex(typeof(PermissionPolicyUser), typeof(PermissionPolicyRole), new AuthenticationStandard()); string serviceEndPoint = @"net.tcp://127.0.0.1:1451/DataServer"; ServiceHost serviceHost = new WcfXafServiceHost(connectionString, securityProviderHandler); serviceHost.AddServiceEndpoint(typeof(IWcfXafDataServer), WcfDataServerHelper.CreateNetTcpBinding(), serviceEndPoint);
Visual Basic
Dim securityProviderHandler As Func(Of IDataServerSecurity) = _ Function() New SecurityStrategyComplex(GetType(PermissionPolicyUser), GetType(PermissionPolicyRole), New AuthenticationStandard()) Dim serviceEndPoint As String = "net.tcp://127.0.0.1:1451/DataServer" Dim serviceHost As ServiceHost = New WcfXafServiceHost(connectionString, securityProviderHandler) serviceHost.AddServiceEndpoint(GetType(IWcfXafDataServer), WcfDataServerHelper.CreateNetTcpBinding(), serviceEndPoint)

If your existing code uses the SecuredDataServer constructor with the committingDelegate parameter, replace it with the code provided in the How to use the custom CommittingDelegate with the new WcfXafServiceHost ticket.
If you use logging in an app server, you can switch the detail level of information written into an application's log file to the Verbose(4) level. With this level, all Security System loggers (Permission Processors, Middle Tier loggers, security rule loggers) are enabled automatically. For more information, see the Log Files article.
As an alternative, you can create a custom class derived from the WcfXafServiceHost class and override its GetInstanceCore method. In this method, return a WcfSecuredServerLogger instance with required parameters (e.g. you can pass your custom ILogger implementation in it). See the code below that illustrates it:

C#
public class CustomWcfXafServiceHost : WcfXafServiceHost { ... protected override object GetInstanceCore(InstanceContext instanceContext, Message message, IDataLayer dataLayer, IDataServerSecurity serverSecurity, bool allowICommandChannelDoWithSecurityContext, InstanceContextMode contextMode) { return new WcfSecuredServerLogger(dataLayer, serverSecurity, allowICommandChannelDoWithSecurityContext, contextMode, Logger.Instance); } }
Visual Basic
Public Class CustomWcfXafServiceHost Inherits WcfXafServiceHost ... Protected Overrides Function GetInstanceCore(instanceContext As InstanceContext, message As Message, dataLayer As IDataLayer, serverSecurity As IDataServerSecurity, allowICommandChannelDoWithSecurityContext As Boolean, contextMode As InstanceContextMode) As Object Return New WcfSecuredServerLogger(dataLayer, serverSecurity, allowICommandChannelDoWithSecurityContext, contextMode, Logger.Instance) End Function End Class

2. Client WinForms Application Modifications
In the Program.cs file, find this code:

C#
string connectionString = "net.tcp://127.0.0.1:1451/DataServer"; WcfSecuredDataServerClient clientDataServer = new WcfSecuredDataServerClient(WcfDataServerHelper.CreateNetTcpBinding(), new EndpointAddress(connectionString)); ServerSecurityClient securityClient = new ServerSecurityClient(clientDataServer, new ClientInfoFactory()); securityClient.SupportNavigationPermissionsForTypes = false; securityClient.IsSupportChangePassword = true; winApplication.Security = securityClient; winApplication.CreateCustomObjectSpaceProvider += delegate(object sender, CreateCustomObjectSpaceProviderEventArgs e) { e.ObjectSpaceProvider = new DataServerObjectSpaceProvider(clientDataServer, securityClient); };
Visual Basic
Dim connectionString As String = "net.tcp://127.0.0.1:1451/DataServer" Dim clientDataServer As New WcfSecuredDataServerClient(WcfDataServerHelper.CreateNetTcpBinding(), New EndpointAddress(connectionString)) Dim securityClient As New ServerSecurityClient(clientDataServer, New ClientInfoFactory()) securityClient.SupportNavigationPermissionsForTypes = False securityClient.IsSupportChangePassword = True winApplication.Security = securityClient AddHandler winApplication.CreateCustomObjectSpaceProvider, Sub(sender As Object, e As CreateCustomObjectSpaceProviderEventArgs) e.ObjectSpaceProvider = _ New DataServerObjectSpaceProvider(clientDataServer, securityClient)

…and replace it with the following:

C#
string connectionString = @"net.tcp://127.0.0.1:1451/DataServer"; WcfSecuredClient client = new WcfSecuredClient(WcfDataServerHelper.CreateNetTcpBinding(), new EndpointAddress(connectionString)); winApplication.Security = new MiddleTierClientSecurity(client) { IsSupportChangePassword = true }; winApplication.DatabaseUpdateMode = DatabaseUpdateMode.Never; winApplication.CreateCustomObjectSpaceProvider += delegate (object sender, CreateCustomObjectSpaceProviderEventArgs e) { e.ObjectSpaceProviders.Add(new MiddleTierServerObjectSpaceProvider(client)); };
Visual Basic
Dim connectionString As String = "net.tcp://127.0.0.1:1451/DataServer" Dim client As New WcfSecuredClient(WcfDataServerHelper.CreateNetTcpBinding(), New EndpointAddress(connectionString)) winApplication.Security = New MiddleTierClientSecurity(client) With {.IsSupportChangePassword = True} winApplication.DatabaseUpdateMode = DatabaseUpdateMode.Never AddHandler winApplication.CreateCustomObjectSpaceProvider, Sub(sender As Object, e As CreateCustomObjectSpaceProviderEventArgs) _ e.ObjectSpaceProviders.Add(New MiddleTierServerObjectSpaceProvider(client))

Additionally, replace this line:

C#
clientDataServer.Close();
Visual Basic
clientDataServer.Close()

…with the following:

C#
client.Dispose();
Visual Basic
client.Dispose()

3. ASP.NET and  Mobile Applications:
If you previously configured your ASP.NET or Mobile application to use the Middle Tier, this configuration will be incompatible with the server modifications described above. It is recommended to use the Integrated Mode instead of the Middle Tier in these applications. The Middle Tier does not make sense for an ASP.NET or Mobile application from the logical, maintenance and performance point of view. These applications are client-server by default.

See Also:
Security permissions processing mechanism optimization and other important changes in XAF v17.2+

Show previous comments (1)
Dennis Garavsky (DevExpress) 7 years ago

    @Maxime MERIAUX: I've created a separate ticket on your behalf (T579483: Cache node usage with the new middle-tier implementation in v17.2). It has been placed in our processing queue and will be answered shortly.

    C C
    Christoph Weinzierl-Heigl [msg] 7 years ago

      Hello,

      I'm trying to move my application to the new WcfXafServiceHost, however I noticed there seems to be no apparent replacement for the EventHandler<DataServiceOperationEventArgs> comittingDelegate that was available in the SecuredDataServer constructor.

      This was my previous call:

      C#
      var securedDataServer = new SecuredDataServer(dataLayer, securityProviderHandler, DevExpress.ExpressApp.MiddleTier.Logger.Instance, myCommittingDelegate, false);

      This is the constructors signature:

      C#
      public SecuredDataServer(IDataLayer dataLayer, QueryRequestSecurityStrategyHandler querySecurityEnvironmentHandler, ILogger logger, EventHandler<DataServiceOperationEventArgs> committingDelegate, bool allowICommandChannelDoWithSecurityContext) {...}

      Is there any way to include the myCommittingDelegate with the new WcfXafServiceHost?

      DevExpress Support Team 7 years ago

        Hello,

        I've created a separate ticket on your behalf (T594017: How to use the custom CommittingDelegate with the new WcfXafServiceHost). It has been placed in our processing queue and will be answered shortly.

        Disclaimer: The information provided on DevExpress.com and affiliated web properties (including the DevExpress Support Center) is provided "as is" without warranty of any kind. Developer Express Inc disclaims all warranties, either express or implied, including the warranties of merchantability and fitness for a particular purpose. Please refer to the DevExpress.com Website Terms of Use for more information in this regard.

        Confidential Information: Developer Express Inc does not wish to receive, will not act to procure, nor will it solicit, confidential or proprietary materials and information from you through the DevExpress Support Center or its web properties. Any and all materials or information divulged during chats, email communications, online discussions, Support Center tickets, or made available to Developer Express Inc in any manner will be deemed NOT to be confidential by Developer Express Inc. Please refer to the DevExpress.com Website Terms of Use for more information in this regard.