Ticket T222317
Visible to All Users

How to connect SecuredObjectSpaceProvider to a cached WCF data store service and configure BasicHttpBinding in code

created 10 years ago (modified 9 years ago)

Please look into T214347 for reference.

So I have replaced the Application Server with a WCF Service. This is working well. However, I have a problem with the WCF Service and storing the model in the database. I have modify my code as per the documentation Client-Side Security - Integrated Mode as follows:
Stop using the ThreadSafeDataLayer by passing false to the Object Space Provider constructor's threadSafe parameter (not recommended in ASP.NET applications).
Do not specify the database storage for application-wide model differences in the XafApplication.CreateCustomModelDifferenceStore event handler (you can still store user-specific differences in the database using theXafApplication.CreateCustomUserModelDifferenceStore event).I tried these 2 recommendations separately and at the same time and still have the following error:

Unable to save customization information:
Cannot Save user settings to the database.
Contact your application administrator for a solution. You can also try to find the reason of this failure yourself by checking the log file.
Error in deserializing body of request message for operation ModifyDataCached.

What can I do? My code looks like this:

C#
// This is on the xxx.Module.Win project on WinModule.cs private void Application_CreateCustomModelDifferenceStore(Object sender, CreateCustomModelDifferenceStoreEventArgs e) { //e.Store = new ModelDifferenceDbStore((XafApplication)sender, typeof(ModelDifference), true); e.Handled = true; } private void Application_CreateCustomUserModelDifferenceStore(Object sender, CreateCustomModelDifferenceStoreEventArgs e) { e.Store = new ModelDifferenceDbStore((XafApplication)sender, typeof(ModelDifference), false); e.Handled = true; } // This is on the xxx.Win project on WinApplication.cs protected override void CreateDefaultObjectSpaceProvider(CreateCustomObjectSpaceProviderEventArgs args) { args.ObjectSpaceProvider = new SecuredObjectSpaceProvider((SecurityStrategyComplex)Security, args.ConnectionString, args.Connection, false); }

Regards,

Carlos

Comments (1)
Dennis Garavsky (DevExpress) 10 years ago

    Hello Carlos,

    As I see, you are using SecuredObjectSpaceProvider, but wrote that you used the WCF application server. Do you have other code files where you configured this, because these two settings contradict each other?
    Would you please post a small sample project illustrating this error so we can debug it locally and assist you further?

    Answers approved by DevExpress Support

    created 10 years ago (modified 10 years ago)

    Hello Carlos,

    I now understand what you mean. If you debug your app in Visual Studio as per https://msdn.microsoft.com/en-us/library/d14azbfh.aspx?f=255&MSPPError=-2147217396, then you will be able to catch the following exceptions:

    1. A first chance exception of type 'System.Xml.XmlException' occurred in System.Runtime.Serialization.dll

    Additional information: The maximum string content length quota (8192) has been exceeded while reading XML data. This quota may be increased by changing the MaxStringContentLength property on the XmlDictionaryReaderQuotas object used when creating the XML reader. Line 1, position 469.
    2. A first chance exception of type 'System.ServiceModel.CommunicationException' occurred in System.ServiceModel.dll

    Additional information: Error in deserializing body of request message for operation 'ModifyDataCached'.
    ===

    I modified your WinForms app as follows and it all worked fine in my tests:

    1. Uncommented out the Application_CreateCustomModelDifferenceStore method as per eXpressApp Framework > Task-Based Help > How to: Store the Application Model Differences in the Database.
    C#
    namespace Reports.Module.Win { [ToolboxItemFilter("Xaf.Platform.Win")] public sealed partial class ReportsWindowsFormsModule : ModuleBase { private void Application_CreateCustomModelDifferenceStore(Object sender, CreateCustomModelDifferenceStoreEventArgs e) { e.Store = new ModelDifferenceDbStore((XafApplication)sender, typeof(ModelDifference), true); e.Handled = true; }
    1. Modified the Reports.DataService\Web.config file (in the WCF service) as follows:
    XML
    <bindings> <basicHttpBinding> <binding name="ServicesBinding" maxBufferPoolSize="2147483647" maxReceivedMessageSize="2147483647" maxBufferSize="2147483647" transferMode="Streamed" > <readerQuotas maxDepth="2147483647" maxArrayLength="2147483647" maxStringContentLength="2147483647"/> </binding> </basicHttpBinding>
    1. Modified the Reports.Win\WinApplication.cs file (in the client app) as follows:
    C#
    using System; using System.ServiceModel; using DevExpress.ExpressApp; using DevExpress.ExpressApp.Security; using DevExpress.ExpressApp.Security.ClientServer; using DevExpress.ExpressApp.Win; using DevExpress.ExpressApp.Xpo; using DevExpress.Xpo.DB; using DevExpress.Xpo.DB.Helpers; namespace Reports.Win { public partial class ReportsWindowsFormsApplication : WinApplication { public ReportsWindowsFormsApplication() { InitializeComponent(); } protected override void CreateDefaultObjectSpaceProvider(CreateCustomObjectSpaceProviderEventArgs args) { args.ObjectSpaceProvider = new SecuredObjectSpaceProvider((SecurityStrategyComplex)Security, new CachedXpoDataStoreProvider(args.ConnectionString), false); } private void ReportsWindowsFormsApplication_CustomizeLanguagesList(object sender, CustomizeLanguagesListEventArgs e) { var userLanguageName = System.Threading.Thread.CurrentThread.CurrentUICulture.Name; if (userLanguageName != "en-US" && e.Languages.IndexOf(userLanguageName) == -1) { e.Languages.Add(userLanguageName); } } private void ReportsWindowsFormsApplication_DatabaseVersionMismatch(object sender, DevExpress.ExpressApp.DatabaseVersionMismatchEventArgs e) { if (System.Diagnostics.Debugger.IsAttached) { e.Updater.Update(); e.Handled = true; } } } public class CachedXpoDataStoreProvider : IXpoDataStoreProvider { private IDataStore _workingStore; private IDataStore _updatingStore; private string connectionString; public CachedXpoDataStoreProvider(string connectionUri) { this.connectionString = connectionUri; BasicHttpBinding binding = new BasicHttpBinding(); binding.MaxReceivedMessageSize = Int32.MaxValue; binding.MaxBufferSize = Int32.MaxValue; binding.MaxBufferPoolSize = Int32.MaxValue; binding.ReaderQuotas.MaxArrayLength = Int32.MaxValue; binding.ReaderQuotas.MaxDepth = Int32.MaxValue; binding.ReaderQuotas.MaxStringContentLength = Int32.MaxValue; binding.ReaderQuotas.MaxBytesPerRead = Int32.MaxValue; binding.ReaderQuotas.MaxNameTableCharCount = Int32.MaxValue; var client = new CachedDataStoreClient(binding, new EndpointAddress(connectionUri)); DataCacheNode node = new DataCacheNode(client); node.ProcessCookie(DataCacheCookie.Empty); this._workingStore = node; this._updatingStore = node; } public string ConnectionString { get { return connectionString; } } public IDataStore CreateUpdatingStore(out IDisposable[] disposableObjects) { disposableObjects = null; return _updatingStore; } public IDataStore CreateWorkingStore(out IDisposable[] disposableObjects) { disposableObjects = null; return _workingStore; } public DevExpress.Xpo.Metadata.XPDictionary XPDictionary { get { return null; } } } }

    Take special note of the new CachedXpoDataStoreProvider class and the following constructor:

    C#
    args.ObjectSpaceProvider = new SecuredObjectSpaceProvider((SecurityStrategyComplex)Security, new CachedXpoDataStoreProvider(args.ConnectionString), false);

    A reference to the System.Runtime.Serialization.dll assembly is required for this code to work.

    4.  Modified the Reports.Win\Program.cs file (in the client app) as follows:

    C#
    using (var winApplication = new ReportsWindowsFormsApplication()) { //winApplication.DatabaseUpdateMode = DatabaseUpdateMode.Never;

    I have also attached a modified version of your app in a private comment below.

      Comments (2)

        Works beautifully! Thank you!!!

        Dennis Garavsky (DevExpress) 10 years ago

          anytime, Carlos

          Other Answers

          created 10 years ago

          It's weird but I can't post any comments to this post. So I am answering it to see if it will allow me.

            Comments (1)

              Now I can see the comments. but I cannot mark as private. Can you look into this?

              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.