CSLA and WCF

CSLA and WCF

Old forum URL: forums.lhotka.net/forums/t/12190.aspx


redone posted on Friday, October 18, 2013

Hi everyone,

I don't have any experience in csla, a bit surfed forums, saw some similar questions and probably know the answer, but still would like to clarify with more experienced person:

Is it bad practice to use CSLA business object as WCF service input/output or is this even possible? I mean either return object or input parameter. Is this a bad practice? Should  DTO be used instead?

Also other one more philosophic one: Is it a good practice that wcf will call csla object or csla object itself should call wcf?

 

Thanks,

--O

 

skagen00 replied on Friday, October 18, 2013

WCF in CSLA is usually considered one of the mechanisms to get to the DataPortal.

With any traditional sort of CSLA usage, you'll be getting a hydrated object using the DataPortal.  Once you traverse the "logical" boundary from client to server, it's not in any way prohibited that you might call a WCF service to hydrate your business object on the server due to the DataPortal request.

You shouldn't really think of your CSLA objects as "calling WCF".  You basically say, "DataPortal, fetch Organizatoin 55", and your dataportal request will probably involve a "SingleCriteria<int>" of 55, and whatever means the DataPortal gets to the server (very well may be WCF) is not necessarily important to the object.

I'd definitely recommend the Expert Business Objects book or the CSLA videos - for example, your question of DTOs OR WCF is really not an either or - we use WCF for our DataPortal and we use DTOs to enable a data access layer that provides for mocking (and unit testing with mocking).

 

redone replied on Friday, October 18, 2013

Hi skagen00,

Thanks for reply,

You've mentioned that you only use DTO just for unit testing, am I understood well? Is there some performance degradation of doing so vs DTO? Is it okay to return BO from WCF method, because I looked into FAQ and saw that BO can't be serialized via WCF? Also if that is possible, the BO is completely serialized, even event handlers/delegates/etc.?

As for the second question regarding where it is correct to implement BO request, the "correct" way of doing so, is to implement BO access in the client portal and there to do bo access work(or other name CRUD operations) am I correct?

--O

 

skagen00 replied on Friday, October 18, 2013

We don't just use DTOs for unit testing.

DTOs contain data that backs a business object for us.  When we fetch, the BO wants a DTO in exchange for criteria (usually the ID).  When we insert/update, the BO populates a DTO and sends it to the data access layer for insert or update.  In the case of testing, about 70% of our 12K+ tests use "mock" DTOs.

Initially when my colleague added the extra layer, where properties were copied with every fetch, insert, update of a business object, I was concerned about performance.  I ran a test and just due to the unpredictable lack of controls, his data access layer (with the extra copy to/fro DTOs) was actually very marginally faster than using our business layer *without* a data access layer and DTOs.  Obviously the extra copy can't speed up performance but it entirely knocked out the concept for me that adding this extra layer with DTOs was going to be that meaningful to performance.

Again, I'd really point you to minimally the CSLA videos.  All the answers you seem to need aren't going to fit into a concise post.  The CSLA book (Expert C# business objects) itself was the most meaningful development book I have ever read.  From your questions I am guessing you haven't read the book and haven't seen the videos.  I would recommend, if you haven't - give them the time and expense as they are worth it even if you aren't doing CSLA in the future.

Best,

Chris

 

SMILEMan replied on Thursday, October 31, 2013

You indicated that you use WCF to communicate to your DataPortal.  I'm having trouble getting it working (hosting in IIS).   I've posted this problem on the forum earlier but didn't get a resolution.

I had a CSLA 4.3 WCF Dataportal running for testing last year, but switched servers since then and have been not been able to get the CSLA 4.5.40  WCF Dataportal to run.   The new server is running IIS 7.5 vs. 7.0 on the old server and I had to configure more “security” settings to get my production CSLA 3.0 Remoting Dataportal to work, but eventually did. 

I'm getting a SecurityNegotiationException when I access the WCF DataPortal from a WPF application (currently only WPF applications needs access to this DataPortal).  I get this message on the first call to the Dataportal (Fetch of BusinessIdentity).

·        All of my business objects reference Csla.Web.dll and the DLL is in the bin folder of the DataPortal as Rocky indicated in earlier discussions on this forum.

·        I am able to ?wsdl the DataPortal service and get the xml displayed in the browser.   I have setup by config files like the Project Tracker as much as possible - see below for Web and Client config files.

·        Server is Windows Server 2008 R2 with IIS 7.5 with .NET Framework 4.5 loaded.

·        Anonymous Authentication is Enabled as the only  authentication method.

 

Fiddler just logged the first call to the Dataportal .   The following are the inner exceptions from the SecurityNegotiationException (let me know if you would like to see the full message with call stacks):

 

System.Windows.Markup.XamlParseException was unhandled

  HResult=-2146233087

  Message=The invocation of the constructor on type 'SMILE4.AppBootstrapper' that matches the specified binding constraints threw an exception.

 

InnerException: System.ServiceModel.Security.SecurityNegotiationException

       HResult=-2146233087

       Message=Secure channel cannot be opened because security negotiation with the remote endpoint has failed. This may be due to absent or incorrectly specified EndpointIdentity in the EndpointAddress used to create the channel. Please verify the EndpointIdentity specified or implied by the EndpointAddress correctly identifies the remote endpoint.

 

InnerException: System.ServiceModel.FaultException

            HResult=-2146233087

            Message=The message with Action 'http://schemas.xmlsoap.org/ws/2005/02/trust/RST/Issue' cannot be processed at the receiver, due to a ContractFilter mismatch at the EndpointDispatcher. This may be because of either a contract mismatch (mismatched Actions between sender and receiver) or a binding/security mismatch between the sender and the receiver.  Check that sender and receiver have the same contract and the same binding (including security requirements, e.g. Message, Transport, None).

 

 

 

Config files:

Web.Config

<?xml version="1.0"?>

<configuration>

  <system.codedom>

    <compilers>

      <compiler language="c#;cs;csharp" extension=".cs" compilerOptions="/warnaserror-" warningLevel="4" type="Microsoft.CSharp.CSharpCodeProvider, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">

        <providerOption name="CompilerVersion" value="v4.5" />

      </compiler>

      <compiler language="vb;vbs;visualbasic;vbscript" extension=".vb" compilerOptions="/optioninfer+" type="Microsoft.VisualBasic.VBCodeProvider, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">

        <providerOption name="CompilerVersion" value="v4.5" />

      </compiler>

    </compilers>

  </system.codedom>

 

  <appSettings>

    <add key="CslaAuthentication" value="Csla" />

    <add key="DalManagerType" value="SMILE4.DataAccess.SqlServer.DalManager,SMILE4.DataAccess.SqlServer" />

    <add key="CslaWriter" value="Csla.Serialization.Mobile.CslaBinaryWriter, Csla" />

    <add key="CslaReader" value="Csla.Serialization.Mobile.CslaBinaryReader, Csla" />

    <add key="AppType" value="DataPortal"/>

  </appSettings>

 

  <connectionStrings>

      <add name="Security"

                 connectionString="data source=Stiles-SMILE3;initial catalog=SMILESec;user=xxxx;password=xxxx;MultipleActiveResultSets=True"

                 providerName="System.Data.SqlClient" />

      <add name="TEST"

                 connectionString="data source=Stiles-SMILE3;initial catalog=TEST;user=xxxx;password=xxxx;MultipleActiveResultSets=True"

                 providerName="System.Data.SqlClient" />

      <add name="TRAIN"

                 connectionString="data source=Stiles-SMILE3;initial catalog=TRAIN;user=xxxx;password=xxxx;MultipleActiveResultSets=True"

                 providerName="System.Data.SqlClient" />

      <add name="STILES"

                 connectionString="data source=Stiles-SMILE3;initial catalog=STILES2;user=xxxx;password=xxxx;MultipleActiveResultSets=True"

                 providerName="System.Data.SqlClient" />

    </connectionStrings>

 

  <system.web>

    <compilation debug="false" targetFramework="4.5"/>

    <authentication mode="Windows"/>

    <!--

            The <customErrors> section enables configuration

            of what to do if/when an unhandled error occurs

            during the execution of a request. Specifically,

            it enables developers to configure html error pages

            to be displayed in place of a error stack trace.

        -->

 

        <customErrors mode="Off" defaultRedirect="GenericErrorPage.htm">

            <error statusCode="403" redirect="NoAccess.htm" />

            <error statusCode="404" redirect="FileNotFound.htm" />

        </customErrors>

        <!--<pages controlRenderingCompatibilityVersion="4.0" clientIDMode="AutoID"/>-->

        <trace enabled="false" requestLimit="10" pageOutput="false" traceMode="SortByTime" localOnly="true" />

 

        <sessionState

          mode="Off"

          stateConnectionString="tcpip=127.0.0.1:42424"

          sqlConnectionString="data source=127.0.0.1;user id=sa;password="

          cookieless="false"

          timeout="20"

        />

  </system.web>

  <!--

        The system.webServer section is required for running ASP.NET AJAX under Internet

        Information Services 7.0.  It is not necessary for previous version of IIS.

    -->

  <system.serviceModel>

    <serviceHostingEnvironment multipleSiteBindingsEnabled="true"/>

    <services>

      <service name="Csla.Server.Hosts.WcfPortal" behaviorConfiguration="WcfPortalBehavior">

        <endpoint contract="Csla.Server.Hosts.IWcfPortal" binding="wsHttpBinding"

                              bindingConfiguration="wsHttpBinding_IWcfPortal"

                              />

        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>

      </service>

      <service behaviorConfiguration="WcfPortalBehavior" name="Csla.Server.Hosts.Mobile.WcfPortal">

        <endpoint address="" binding="basicHttpBinding" contract="Csla.Server.Hosts.Mobile.IWcfPortal"

                              bindingConfiguration="basicHttpBinding_IWcfPortal">

          <identity>

            <dns value="localhost"/>

          </identity>

        </endpoint>

        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>

      </service>

    </services>

    <bindings>

      <wsHttpBinding>

        <binding name="wsHttpBinding_IWcfPortal" maxReceivedMessageSize="2147483647">

                              <security mode = "None"/>

          <readerQuotas maxBytesPerRead="2147483647"

                        maxArrayLength="2147483647"

                        maxStringContentLength="2147483647"

                        maxNameTableCharCount="2147483647"

                        maxDepth="2147483647"/>

        </binding>

      </wsHttpBinding>

      <basicHttpBinding>

        <binding name="basicHttpBinding_IWcfPortal" maxReceivedMessageSize="2147483647">

          <readerQuotas maxBytesPerRead="2147483647" maxArrayLength="2147483647" maxStringContentLength="2147483647" maxDepth="1024"/>

        </binding>

      </basicHttpBinding>

    </bindings>

    <behaviors>

      <serviceBehaviors>

        <behavior name="returnFaults">

          <serviceDebug includeExceptionDetailInFaults="true"/>

        </behavior>

        <behavior name="">

          <serviceMetadata httpGetEnabled="true"/>

          <serviceDebug includeExceptionDetailInFaults="false"/>

        </behavior>

        <behavior name="WcfPortalBehavior">

          <serviceMetadata httpGetEnabled="true"/>

          <serviceDebug includeExceptionDetailInFaults="true"/>

        </behavior>

      </serviceBehaviors>

    </behaviors>

  </system.serviceModel>

</configuration>

 

Client Config:

<?xml version="1.0" encoding="utf-8"?>

 

<configuration>

  <appSettings>

    <add key="CslaAuthentication" value="Csla" />

    <add key="ServerName" value="Stiles-SMILE3"/>

    <add key="TestMode" value = "true"/>

    <add key="SuppressWhatsNew" value = "false" />

    <add key="CslaDataPortalProxy" value="Csla.DataPortalClient.WcfProxy, Csla"/>

    <add key="CslaDataPortalUrl" value="http://Stiles-SMILE3/DataPortalHostWCF/WcfPortal.svc"/>

    <add key="AppType" value="SmartClient"/>

  </appSettings>

 

  <connectionStrings>

    <add name="SalesForce"

         connectionString="data source=localhost;initial catalog=SalesForce;integrated security=SSPI"

         providerName="System.Data.SqlClient" />

    <add name="LocalMaster"

         connectionString="data source=localhost;initial catalog=Master;integrated security=SSPI"

         providerName="System.Data.SqlClient" />

  </connectionStrings>

   

  <startup>

        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />

  </startup>

  <runtime>

    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">

      <dependentAssembly>

        <assemblyIdentity name="Caliburn.Micro" publicKeyToken="8e5891231f2ed21f" culture="neutral" />

        <bindingRedirect oldVersion="0.0.0.0-1.5.2.0" newVersion="1.5.2.0" />

      </dependentAssembly>

    </assemblyBinding>

  </runtime>

</configuration>

 

P.S. Production DataPortal is CSLA 3.0 using Remoting which is running just fine on the same server.   If it would be easier to set up CSLA 4.5 to use Remoting that would be fine with me as all my use is on an internal network of Windows PCs.

 

Any help would be appreciated.

Copyright (c) Marimer LLC