0
votes

I tried creating a WCF service in Visual Studio 2010 and it seems to work because when I debug is VS using WCF Test Client, I can connect to the service and run the commands. But, when I try to run the commands from my Silverlight app i get an error saying my cross domain doesn't work. I have included my code from my silverlight app and wcf client.

SERVICE

clientaccesspolicy.xml

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

app.config

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

  <system.web>
    <compilation debug="true" />
  </system.web>
  <!-- When deploying the service library project, the content of the config file must be added to the host's 
  app.config file. System.Configuration does not support config files for libraries. -->
  <system.serviceModel>
    <bindings>
      <basicHttpBinding>
        <binding name="SqlServerServiceBinding" maxBufferPoolSize="2147483647"
                 maxBufferSize="2147483647" maxReceivedMessageSize="2147483647">
          <readerQuotas  maxDepth="2147483647" maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" />
        </binding>
      </basicHttpBinding>
    </bindings>

    <!--<behaviors>
      <serviceBehaviors>
        <behavior name="SqlServerServiceBehavior">
          <serviceMetadata httpGetEnabled="true" />
          <serviceDebug includeExceptionDetailInFaults="false" />
        </behavior>
      </serviceBehaviors>
    </behaviors>-->

    <services>
      <service name="SqlServerService.Service1">
        <host>
          <baseAddresses>
            <add baseAddress = "http://localhost:8085/" />
          </baseAddresses>
        </host>
        <!-- Service Endpoints -->
        <!-- Unless fully qualified, address is relative to base address supplied above -->
        <endpoint address ="" binding="basicHttpBinding" contract="SqlServerService.IService1">
          <!-- 
              Upon deployment, the following identity element should be removed or replaced to reflect the 
              identity under which the deployed service runs.  If removed, WCF will infer an appropriate identity 
              automatically.
          -->
          <!--<identity>
            <dns value="localhost"/>
          </identity>-->
        </endpoint>
        <!-- Metadata Endpoints -->
        <!-- The Metadata Exchange endpoint is used by the service to describe itself to clients. --> 
        <!-- This endpoint does not use a secure binding and should be secured or removed before deployment -->
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior>
          <!-- To avoid disclosing metadata information, 
          set the value below to false and remove the metadata endpoint above before deployment -->
          <serviceMetadata httpGetEnabled="True"/>
          <!-- To receive exception details in faults for debugging purposes, 
          set the value below to true.  Set to false before deployment 
          to avoid disclosing exception information -->
          <serviceDebug includeExceptionDetailInFaults="False" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>

</configuration>

service1.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;

namespace SqlServerService
{
    // NOTE: You can use the "Rename" command on the "Refactor" menu to change the class name "Service1" in both code and config file together.
    public class Service1 : IService1
    {
        public CompositeType executeScriptWithReturn(String command_string)
        { 
            CompositeType cs = new CompositeType();
            Userful_Commands.sql_server_commands sql = new Userful_Commands.sql_server_commands("Server=localhost;Database=kenticoTest;Integrated Security=SSPI;");

            cs.DtValue = command_string;//sql.executeScriptWithReturn("SELECT * FROM tblBugs");
            return cs;
        }
    }
}

IService1.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;

namespace SqlServerService
{
    // NOTE: You can use the "Rename" command on the "Refactor" menu to change the interface name "IService1" in both code and config file together.
    [ServiceContract]
    public interface IService1
    {
        [OperationContract]
        CompositeType executeScriptWithReturn(String command_string);

        // TODO: Add your service operations here
    }

    // Use a data contract as illustrated in the sample below to add composite types to service operations
    [DataContract]
    public class CompositeType
    {
        public String dt;

        [DataMember]
        public String DtValue
        {
            get { return dt; }
            set { dt = value; }
        }
    }
}

SILVERLIGHT

ServicesReferences.ClientConfig

<configuration>
  <system.serviceModel>
    <bindings>
      <basicHttpBinding>
        <binding name="BasicHttpBinding_IService1" maxBufferSize="2147483647"
          maxReceivedMessageSize="2147483647">
          <security mode="None" />
        </binding>
      </basicHttpBinding>
    </bindings>
    <client>
      <endpoint address="http://localhost:8085/" binding="basicHttpBinding"
        bindingConfiguration="BasicHttpBinding_IService1" contract="ServiceReference1.IService1"
        name="BasicHttpBinding_IService1" />
    </client>
  </system.serviceModel>
</configuration>

MainPage.xaml.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Silverlight;
using SilverlightSQLServer;

namespace SilverlightApplication1
{
    public partial class MainPage : UserControl
    {
        public MainPage()
        {
            InitializeComponent();
        }

        private void loaded_up(object sender, RoutedEventArgs e)
        {
            //SilverlightApplication1.ServiceReference1.Service1Client sc = new ServiceReference1.Service1Client();
            //sc.executeScriptWithReturnCompleted += completed;
            //sc.executeScriptWithReturnAsync("TEST COMMAND");
            ServiceReference1.Service1Client ws = new ServiceReference1.Service1Client();

            ws.executeScriptWithReturnCompleted += completed;
            ws.executeScriptWithReturnAsync("TESTCOMMAND");
        }

        private void completed(object sender, SilverlightApplication1.ServiceReference1.executeScriptWithReturnCompletedEventArgs e)
        {
            SilverlightApplication1.ServiceReference1.CompositeType serviceResp = e.Result;
            e = e;

        }
    }
}

Thank you in advance.

1
What is the actual error you get? Is your client access policy in the root of where your service is hosted? Also, what about making 'allow-from http-request-headers = "*"' instead of SOAPActionThelonias

1 Answers

0
votes

I have wrestled with this myself. The simplest solution I have found is to put the WCF service in the Solution that hosts your silverlight application. Right click on that project (The .Web one that has the ClientBin folder) select add item and select WCF service. Put your code in that service and your cross domain issues go away. Of course if you want to host the service somewhere else then this wont help you.