views:

2075

answers:

3

* Readers Beware: massive code dump, not for the faint of heart... *

Hello,

I'm trying to figure out how to deploy a Silverlight 3 app to IIS7 with a WCF Service. I think i've got most of it figured out however I still get a cross domain error for some reason. I'm leaning toward thinking that the service is not finding the client access policy but I'm not sure how to confirm this. I get a very useless exception (simply says CrossDomainError). Inner Exception is nonexistant. Here are the steps I've taken to deploy the app. If anyone sees anything that doesn't add up can they please advise? I can't think of anything else to poke at right now...

  • In IIS manager I built a new site. I named it Silverlight, accepted a pool of the same name, and accepted all the rest of the defaults. I disabled the default site. I set the web root to be C:\WebApps
  • I placed all of the files from the release build of my Visual Studio Silverlight client project into the web root.
  • I place the following config files from the Silverlight client project in the web root: ServiceReferences.ClientConfig, Silverlight.js.
  • I placed the /bin directory from the release build of the Silverlight.Web project into the web root
  • I place the following files from the Silverlight.Web release build in the web root: crossdomain.xml, clientaccesspolicy.xml, Service1.svc, Service1.svc.cs, Web.config.
  • I renamed the TestPage.html file to index.html.

I realize that many of these are superfluous but I was running out of things to try so I started adding anything that looked like it might contain any useful metadata.

Here is the code to my various config files:

clientaccesspolicy.xml:

<?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 include-subpaths="true" path="/"/>
      </grant-to>
    </policy>
  </cross-domain-access>
</access-policy>

crossdomain.xml:

<!DOCTYPE cross-domain-policy SYSTEM "http://www.macromedia.com/xml/dtds/cross-domain-policy.dtd"&gt;
<cross-domain-policy>
  <allow-http-request-headers-from domain="*" headers="*"/>
</cross-domain-policy>

system.serviceModel configuration, excerpted from Web.config:

<system.serviceModel>
     <behaviors>
      <serviceBehaviors>
       <behavior name="SilverlightApplication2.Web.Service1Behavior">
        <serviceMetadata httpGetEnabled="true"/>
        <serviceDebug includeExceptionDetailInFaults="false"/>
       </behavior>
      </serviceBehaviors>
     </behaviors>
     <bindings>
      <customBinding>
       <binding name="customBinding0">
        <binaryMessageEncoding/>
        <httpTransport/>
       </binding>
      </customBinding>
     </bindings>
     <serviceHostingEnvironment aspNetCompatibilityEnabled="true"/>
     <services>
      <service behaviorConfiguration="SilverlightApplication2.Web.Service1Behavior" name="SilverlightApplication2.Web.Service1">
       <endpoint address="http://win-xqawq222tag:2721/Service1.svc" binding="customBinding" bindingConfiguration="customBinding0" contract="SilverlightApplication2.Web.Service1"/>
       <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
      </service>
     </services>
    </system.serviceModel>

ServiceReferences.ClientConfig:

<configuration>
    <system.serviceModel>
        <bindings>
            <customBinding>
                <binding name="CustomBinding_Service1">
                    <binaryMessageEncoding />
                    <httpTransport maxReceivedMessageSize="2147483647" maxBufferSize="2147483647" />
                </binding>
            </customBinding>
        </bindings>
        <client>
            <endpoint address="http://win-xqawq222tag:2721/Service1.svc" binding="customBinding"
                bindingConfiguration="CustomBinding_Service1" contract="ServiceReference1.Service1"
                name="CustomBinding_Service1" />
        </client>
    </system.serviceModel>
</configuration>

Service1.svc:

<%@ ServiceHost Language="C#" Debug="true" Service="SilverlightApplication2.Web.Service1" CodeBehind="Service1.svc.cs" %>

Now for the implementation followed by the client code:

Service1.svc.cs:

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

namespace SilverlightApplication2.Web
{
    [ServiceContract(Namespace = "")]
    [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
    public class Service1
    {
        [OperationContract]
        public DoWorkResult DoWork()
        {
            // Add your operation implementation here
            int i = new Random().Next();
            string s = "test string";
            DoWorkResult r = new DoWorkResult() { String = s, Integer = i };
            return r;
        }

        // Add more operations here and mark them with [OperationContract]
    }

    [DataContract]
    public class DoWorkResult
    {
        [DataMember]
        public string String { get; set; }

        [DataMember]
        public int Integer { get; set; }
    }
}

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;

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

            ServiceReference1.Service1Client proxy = new SilverlightApplication2.ServiceReference1.Service1Client();
            proxy.DoWorkCompleted += new EventHandler<SilverlightApplication2.ServiceReference1.DoWorkCompletedEventArgs>(proxy_DoWorkCompleted);
            proxy.OpenAsync();
            proxy.DoWorkAsync();
            proxy.CloseAsync();
        }

        void proxy_DoWorkCompleted(object sender, SilverlightApplication2.ServiceReference1.DoWorkCompletedEventArgs e)
        {
            if (e.Error == null)
            {
                String.Text = "Test String is: " + e.Result.String;
                Integer.Text = "Random Int is: " + e.Result.Integer;
            }
            else
            {
                String.Text = e.Error.Message + e.Error.InnerException.Message + e.Error.StackTrace;
                Integer.Text = e.Error.Message + e.Error.InnerException.Message + e.Error.StackTrace;
            }
        }
    }
}

All of this works fine in VS 2008 on XP Pro. On IIS7 on Server2008 I am able to hit the default page, index.html, at http://localhost or at http://%5BmyComputerName%5D.

I am also able to hit the service at http://localhost/Service1.svc. I am not able to hit the service using http://%5BcompNameHere%5D/Service1.svc. It complains with this error:

No protocol binding matches the given address 'http://win-xqawq222tag:2721/Service1.svc'. Protocol bindings are configured at the Site level in IIS or WAS configuration. Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: System.InvalidOperationException: No protocol binding matches the given address 'http://win-xqawq222tag:2721/Service1.svc'. Protocol bindings are configured at the Site level in IIS or WAS configuration.

Source Error:

An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.

Stack Trace:

[InvalidOperationException: No protocol binding matches the given address 'http://win-xqawq222tag:2721/Service1.svc'. Protocol bindings are configured at the Site level in IIS or WAS configuration.]
System.ServiceModel.Channels.TransportChannelListener.OnOpening() +11513378 System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout) +229
System.ServiceModel.Dispatcher.ChannelDispatcher.OnOpen(TimeSpan timeout) +72

[InvalidOperationException: The ChannelDispatcher at 'http://win-xqawq222tag:2721/Service1.svc' with contract(s) '"Service1"' is unable to open its IChannelListener.] System.ServiceModel.Dispatcher.ChannelDispatcher.OnOpen(TimeSpan timeout) +118
System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout) +261
System.ServiceModel.ServiceHostBase.OnOpen(TimeSpan timeout) +107
System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout) +261
System.ServiceModel.HostingManager.ActivateService(String normalizedVirtualPath) +121
System.ServiceModel.HostingManager.EnsureServiceAvailable(String normalizedVirtualPath) +479

[ServiceActivationException: The service '/Service1.svc' cannot be activated due to an exception during compilation. The exception message is: The ChannelDispatcher at 'http://win-xqawq222tag:2721/Service1.svc' with contract(s) '"Service1"' is unable to open its IChannelListener..] System.ServiceModel.AsyncResult.End(IAsyncResult result) +11531006
System.ServiceModel.Activation.HostedHttpRequestAsyncResult.End(IAsyncResult result) +194
System.ServiceModel.Activation.HostedHttpRequestAsyncResult.ExecuteSynchronous(HttpApplication context, Boolean flowContext) +176
System.ServiceModel.Activation.HttpHandler.ProcessRequest(HttpContext context) +23
System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +181 System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +75

No protocol binding matches the given address 'http://win-xqawq222tag:2721/Service1.svc'. Protocol bindings are configured at the Site level in IIS or WAS configuration.

Further, I am able to hit the policy file at http://localhost/clientaccesspolicy.xml and http://%5BcomputerNameHere%5D/clientaccesspolicy.xml.

Is there something else I need to look at?

+1  A: 

Hi :)

I freely admit I haven't exactely tried to reproduce you specific error, but I noticed something I too stubled over.

Colin Cole blogged that there was a subtle change in cap.xml format in regard to using SSL. I didn't use SSL, but only when I changed

<allow-from http-request-headers="*">
    <domain uri="*"/>
</allow-from>

to

<allow-from http-request-headers="*">
    <domain uri="http://*" />
    <domain uri="https://*" /> <!-- if needed -->
</allow-from>

accessing the service worked.

ClearsTheScreen
A: 

I had to make the following change to the ServiceReferences.ClientConfig file and then publish again:

<configuration>
    <system.serviceModel>
        <bindings>
            <customBinding>
                <binding name="CustomBinding_Service1">
                    <binaryMessageEncoding />
                    <httpTransport maxReceivedMessageSize="2147483647" maxBufferSize="2147483647" />
                </binding>
            </customBinding>
        </bindings>
        <client>
            <endpoint address="http://localhost/Service1.svc" binding="customBinding"
                bindingConfiguration="CustomBinding_Service1" contract="ServiceReference1.Service1"
                name="CustomBinding_Service1" />
          <!--<endpoint address="http://localhost:2721/Service1.svc" binding="customBinding"
                bindingConfiguration="CustomBinding_Service1" contract="ServiceReference1.Service1"
                name="CustomBinding_Service1" />-->
        </client>
    </system.serviceModel>
</configuration>
sweeney
A: 

@ClearsTheScreen

Thank you for your answer. It's working for me.

rgds,

Richard

related questions