views:

616

answers:

1
+1  Q: 

WCF / Csla Hell

I'm trying to build a proof of concept Csla 3.7/Silverlight 3 app and have been working my way through Rocky's tutorials. It's a really simple one form/one business object data editing app and everything is just peachy right up until the point where I try to get the Wcf configured so that the Silverlight app can talk to the Data Portal.

The error I'm getting is:

CommunicationException was unhandled by user code

An error occurred while trying to make a request to URI 'http://localhost:1406/WcfPortal.svc'. 
This could be due to attempting to access a service in a cross-domain way without a proper cross-domain policy in place, or a policy that is unsuitable for SOAP services. 
You may need to contact the owner of the service to publish a cross-domain policy file and to ensure it allows SOAP-related HTTP headers to be sent. 
This error may also be caused by using internal types in the web service proxy without using the InternalsVisibleToAttribute attribute. 
Please see the inner exception for more details.

I'm totally mystified by this as I'm a bit of a n00b to Silverlight & WCF. My setup is pretty straight forward for a Csla Silverlight app. I have 4 projects:

  • CslaSilverlight : Silverlight Project
  • CslaSilverlight.Client : Silverlight Class Library
  • CslaSilverlight.Server : .NET Class Library
  • CslaSilverlight.Web : ASPNET Project to host the SL app

Everything is running locally on my laptop under Cassini. I want the DataPortal to run outside of Silverlight so that I can access SQL Server. I think that the problem may be with my Wcf Config in the Silverlight application which is specified in a ServiceReferences.ClientConfig file:

<configuration>
    <system.serviceModel>
        <bindings>
            <basicHttpBinding>
                <binding name="BasicHttpBinding_IWcfPortal" maxBufferSize="65536"
                    maxReceivedMessageSize="65536" receiveTimeout="10" sendTimeout="10">
                </binding>
            </basicHttpBinding>
        </bindings>
        <client>
            <endpoint address="http://localhost:1406/WcfPortal.svc"
                binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IWcfPortal"
                contract="Csla.WcfPortal.IWcfPortal" name="BasicHttpBinding_IWcfPortal" />
        </client>
    </system.serviceModel>
</configuration>

I'm wondering if the port number important, when I change it I get a different error. I'm also wondering if the format of the endpoint address correct.

Not sure if it's important, but my serviceModel settings from the ASPNet web.config are:

  <system.serviceModel>
    <behaviors>
      <serviceBehaviors>
        <behavior name="WcfPortalBehavior">
          <serviceMetadata httpGetEnabled="true"/>
          <serviceDebug includeExceptionDetailInFaults="true"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <services>
      <service behaviorConfiguration="WcfPortalBehavior" name="Csla.Server.Hosts.Silverlight.WcfPortal">
        <endpoint address="" binding="basicHttpBinding" contract="Csla.Server.Hosts.Silverlight.IWcfPortal">
          <identity>
            <dns value="localhost"/>
          </identity>
        </endpoint>
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
      </service>
    </services>
  </system.serviceModel>
+3  A: 

If I am thinking it right, then the error may be telling you the entirely correct thing, you are missing a cross domain policy. The silverlight app is accessing the WCF service from a remote location and needs the authorisation to accept the request.

This occured for me in dev when the project was in three parts, the SL App, the WCF web service and the website. The web site and WCF service are run independantly, although they were a part of the same solution. As such Cassini is run twice and you are crossing a boundary.

I have a clientaccesspolicy.xml file along with the web service in development that has the following:

<?xml version="1.0" encoding="utf-8" ?>
<access-policy>
<cross-domain-access>
 <policy>
  <allow-from http-request-headers="*">
   <domain uri="*"/>
  </allow-from>
  <grant-to>
   <resource path="/" include-subpaths="true"/>
  </grant-to>
 </policy>
</cross-domain-access>
</access-policy>

The file is a allowing anyone and everything, you would refine it for production, but in dev it was the easiest way. Google wcf client access policy / wcf cross domain policy - it is a common issue.

Andrew
Sounds logical. I've googled as you suggest and I've added a clientaccesspolicy.xml file to my ASPNET web application in the root folder, but it doesn't have any effect!
Steve
I have mine directly in the same location as the .svc file for the web service. Did you locate it there?
Andrew
doh! it worked, just once... suddenly I now get "The remote server returned an error: NotFound"Cassini is up and running on port 3405. My endpoint address is http://localhost:3405/WcfPortal.svc
Steve
check your WCF project properties, on the web tab will be the cassini settings in terms of which port your WCF should run under. The default is auto-assign which means each time you run it can move to a different port. During dev I just choose a specific port and fix it on that, since the deployment will use something entirely different, I just want to know the service is always where I think it is.
Andrew
can I ask what you have in your .svc file? I have <%@ ServiceHost Language="C#" Debug="true" Service="Csla.Server.Hosts.Silverlight.WcfPortal" CodeBehind="WcfPortal.svc.cs" %>
Steve
Aside from different names of service etc identical.
Andrew
To check whether the WCF service is running access the file via http and it should bring up the default page and give youa link to access the WSDL definition. I'd first check that is accessible / running on the port you expect it on etc before then looking at how the SL is accessing it and where it thinks it is.
Andrew
awesome. Solved it, some kind of wield Visual Studio problem. My web project had a reference to Csla (net) but the bin folder had a copy of Csla (Light). When I reset the reference, CslaLight appeared in the bin folder again. So I removed the reference to Csla (net) in the web project and Csla (Net) ends up in the bin folder (probably because of other dependencies). Now all is well and it works perfectly!Thanks for all the tips...
Steve