I have a WCF service (VS2008) project that seems to work ok. I have a console application that can connect to the WCF service (where VS hosts the WCF service so it can be debugged); and that console app can make calls to the service ok. (All of these projects
are in the same solution and execute on the local host.)
I have modified the endpoint in the app.config file of the WCF library to use basicHttpBinding (instead of wsHttpBinding) so that the service can be called from a Silverlight web application.
The problem I have is that the silverlight app is unable to call the WCF service (while debugging in VS). That is, the WCF service is hosted by VS and the silverlight app is contained in an ASP.Net web site also hosted by VS. The domain of the asp.net app
is "localhost:1592" while the WCF service is being hosted at "localhost:8731". Therefore, I have a cross-domain situation that needs to be overcome.
I have a clientaccesspolicy.xml file and a crossdomain.xml file in my "C:\Inetpub\wwwroot" folder.
Using the "Microsoft Service Trace Viewer", I can see that the WCF service does receive data from the console application (obviously - since this worked). However, the trace viewer indicates that the WCF service does not receive any data from the silverlight
app.
Using Fiddler, I can see that there seems to be a problem when the silverlight application (hosted by an ASP.Net app) attempts to make a call to the WCF service:
Client config file will not work in Beta 1. We shall explictly specify the Binding and EndpointAddress. Please check out our quickstart for more details:
The main difference between the instructions and what I had done, was that I created the WCF service project differently. I tried having a Windows Service with a WCF-service in it (where the WCF-service was in a class library).
This seems conceptually similar to the architecture of the link you provided - just that I was trying to use a windows service to host the WCF instead of an ASP aplication. Is what I was trying to do possible/reasonable? That is, have a web-based silverlight
application utilize a WCF service that's hosted by a windows service? The reason for this is that the WCF service is a "middle tier", so connecting to it directly from the silverlight application seems desirable.
using System;
using System.ComponentModel;
using System.Configuration;
using System.Configuration.Install; // in System.Configuration.Install.dll
using System.ServiceModel;
using System.ServiceProcess;
using System.ServiceModel.Web;
using System.IO;
using System.ServiceModel.Description;
using System.ServiceModel.Channels;
using System.Xml; // in System.ServiceProcess.dll
namespace Microsoft.ServiceModel.Samples
{
// Define a service contract.
[ServiceContract(Namespace = "http://Microsoft.ServiceModel.Samples")]
public interface ICalculator
{
}
// Windows Service class which inherits from ServiceBase
// and contains the application entry point.
public class CalculatorWindowsService : ServiceBase
{
public ServiceHost serviceHost = null;
public ServiceHost serviceHost2 = null;
public static void Main()
{
ServiceBase.Run(new CalculatorWindowsService());
}
public void CalculatorService()
{
ServiceName = "WCFWindowsServiceSample";
}
// Start the Windows service.
protected override void OnStart(string[] args)
{
try
{
if (serviceHost != null)
{
serviceHost.Close();
}
if (serviceHost2 != null)
{
serviceHost2.Close();
}
// Create a ServiceHost for the CalculatorService type and
// provide the base address.
serviceHost = new ServiceHost(typeof(CalculatorService));
serviceHost2 = new ServiceHost(typeof(CrossDomainService));
// Open the ServiceHostBase to create listeners and start
// listening for messages.
serviceHost.Open();
serviceHost2.Open();
}
catch(Exception ex){
//To log the error
System.IO.FileStream fs;
if (System.IO.File.Exists(@"C:\Log.txt"))
{
fs = new FileStream(@"C:\Log.txt", FileMode.Append);
}
else fs = new FileStream(@"C:\Log.txt", FileMode.OpenOrCreate);
Byte[] bContent = System.Text.Encoding.GetEncoding("gb2312").GetBytes(ex.Message + "\r\n");
fs.Write(bContent, 0, bContent.Length);
fs.Close();
}
}
// Stop the Windows service.
protected override void OnStop()
{
if (serviceHost != null)
{
serviceHost.Close();
serviceHost = null;
}
if (serviceHost2 != null)
{
serviceHost2.Close();
serviceHost2 = null;
}
}
}
// Provide the ProjectInstaller class which allows
// the service to be installed by the Installutil.exe tool
[RunInstaller(true)]
public class ProjectInstaller : Installer
{
private ServiceProcessInstaller process;
private ServiceInstaller service;
public ProjectInstaller()
{
process = new ServiceProcessInstaller();
process.Account = ServiceAccount.LocalSystem;
service = new ServiceInstaller();
service.ServiceName = "WCFWindowsServiceSample3";
Installers.Add(process);
Installers.Add(service);
}
}
}
public Page()
{
InitializeComponent();
BasicHttpBinding binding = new BasicHttpBinding();
EndpointAddress ed = new EndpointAddress("http://localhost:7999/ServiceModelSamples/service");
ServiceReference3.CalculatorClient proxy = new SilverlightApplication1.ServiceReference3.CalculatorClient(binding,ed);
proxy.AddCompleted += new EventHandler<SilverlightApplication1.ServiceReference3.AddCompletedEventArgs>(proxy_AddCompleted);
proxy.AddAsync(1, 2);
Thanks very much for the previous post - that got me 99% of the way there.
I just had to alter the OnStart( ) and OnStop( ) methods of CalculatorWindowsService so that the CrossDomainService was (also) started and stopped. Without this, I still received the 404 error.
I see the same on my end. I wrote a great WCF Rest compatible service using webHttpBinding and it worked great in Silverlight 2 Beta 1. Now that I've upgraded to Silverlight 2 Beta 2 it looks as though I can not use this Binding type anymore!??!
webHttpBinding was great because I could easily switch the encoding between XML or JSON. Has ANYONE found a way to use a webHttpBinding WCF service in Silverlight 2 Beta 2? Anyone???
But when I run my silverlight application, I get following error:
An error occurred while trying to make a request to URI 'http://localhost:7999/ServiceModelSamples/service'. 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. Please see the inner exception for more details.
But, I used Nikhil's Web Development Helper, I see that Silverlight app is getting 'clientaccesspolicy.xml' since it is giving 200.
I don't know what is the problem? Is it because even Silverlight 2 Doesn't support webhttpbinding? If so what is the workaround?
guylemar
Member
16 Points
4 Posts
Silverlight 2 and WCF - Protocol Error
May 29, 2008 06:33 AM | LINK
Hi there,
I have a WCF service (VS2008) project that seems to work ok. I have a console application that can connect to the WCF service (where VS hosts the WCF service so it can be debugged); and that console app can make calls to the service ok. (All of these projects are in the same solution and execute on the local host.)
I have modified the endpoint in the app.config file of the WCF library to use basicHttpBinding (instead of wsHttpBinding) so that the service can be called from a Silverlight web application.
The problem I have is that the silverlight app is unable to call the WCF service (while debugging in VS). That is, the WCF service is hosted by VS and the silverlight app is contained in an ASP.Net web site also hosted by VS. The domain of the asp.net app is "localhost:1592" while the WCF service is being hosted at "localhost:8731". Therefore, I have a cross-domain situation that needs to be overcome.
I have a clientaccesspolicy.xml file and a crossdomain.xml file in my "C:\Inetpub\wwwroot" folder.
clientaccesspolicy.xml contains:
<?xml version="1.0" encoding="utf-8"?>
<access-policy>
<cross-domain-access>
<policy>
<allow-from>
<domain uri="*"/>
</allow-from>
<grant-to>
<resource path="/" include-subpaths="true"/>
</grant-to>
</policy>
</cross-domain-access>
</access-policy>
crossdomain.xml contains:
<?xml version="1.0"?>
<!DOCTYPE cross-domain-policy SYSTEM "http://www.macromedia.com/xml/dtds/cross-domain-policy.dtd">
<cross-domain-policy>
<allow-access-from domain="*" />
</cross-domain-policy>
Using the "Microsoft Service Trace Viewer", I can see that the WCF service does receive data from the console application (obviously - since this worked). However, the trace viewer indicates that the WCF service does not receive any data from the silverlight app.
Using Fiddler, I can see that there seems to be a problem when the silverlight application (hosted by an ASP.Net app) attempts to make a call to the WCF service:
So, is the problem that something is having a problem obtaining the clientaccesspolicy.xml and crossdomain.xml files?
In which case, any suggestions would be appreciated as to how I can get this working.
Thanks.
Allen Chen –...
Star
14215 Points
1854 Posts
Microsoft
Re: Silverlight 2 and WCF - Protocol Error
Jun 02, 2008 02:48 AM | LINK
Hi:
Client config file will not work in Beta 1. We shall explictly specify the Binding and EndpointAddress. Please check out our quickstart for more details:
http://silverlight.net/Quickstarts/Remote/323aac2f-14cc-4dd8-bb40-fa2cb3c2e522.aspx
In addition, please check if you can get the response when you request http://localhost:8731/clientaccesspolicy.xml
I suggest you to create Asp.Net Web Application project to host Silverlight and set the port or use IIS Web Server via Properties->Web.
Regards
Allen Chen
Microsoft Online Community Support
Please remember to mark the replies as answers if they help and unmark them if they provide no help.
guylemar
Member
16 Points
4 Posts
Re: Silverlight 2 and WCF - Protocol Error
Jun 05, 2008 06:13 AM | LINK
Hi Allen, thanks for the reply.
Following those instructions worked ok for me.
The main difference between the instructions and what I had done, was that I created the WCF service project differently. I tried having a Windows Service with a WCF-service in it (where the WCF-service was in a class library).
This seems conceptually similar to the architecture of the link you provided - just that I was trying to use a windows service to host the WCF instead of an ASP aplication. Is what I was trying to do possible/reasonable? That is, have a web-based silverlight application utilize a WCF service that's hosted by a windows service? The reason for this is that the WCF service is a "middle tier", so connecting to it directly from the silverlight application seems desirable.
Thanks,
Guy
Allen Chen –...
Star
14215 Points
1854 Posts
Microsoft
Re: Silverlight 2 and WCF - Protocol Error
Jun 05, 2008 11:12 AM | LINK
Hi:
It's not that easy sine you have to provide the cross domain policy file. To solve this problem please try my sample here:
Create Windows Service project, add App.config into it:
App.config:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<services>
<service name="Microsoft.ServiceModel.Samples.CrossDomainService">
<host>
<baseAddresses>
<add baseAddress="http://localhost:7999/"/>
</baseAddresses>
</host>
<endpoint address=""
binding="webHttpBinding"
contract="Microsoft.ServiceModel.Samples.ICrossDomain" behaviorConfiguration="HttpEnableBehavior" />
</service>
<service name="Microsoft.ServiceModel.Samples.CalculatorService" behaviorConfiguration="CalculatorServiceBehavior" >
<host>
<baseAddresses>
<add baseAddress="http://localhost:7999/ServiceModelSamples/service"/>
</baseAddresses>
</host>
<!-- this endpoint is exposed at the base address provided by host: http://localhost:8000/ServiceModelSamples/service -->
<endpoint address=""
binding="basicHttpBinding"
contract="Microsoft.ServiceModel.Samples.ICalculator"/>
<!-- the mex endpoint is explosed at http://localhost:8000/ServiceModelSamples/service/mex -->
<endpoint address="mex"
binding="mexHttpBinding"
contract="IMetadataExchange" />
</service>
</services>
<behaviors>
<endpointBehaviors>
<behavior name="HttpEnableBehavior">
<webHttp/>
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior name="CalculatorServiceBehavior">
<serviceMetadata httpGetEnabled="True"/>
<serviceDebug includeExceptionDetailInFaults="False" />
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
</configuration>
Modify the code in Program.cs:
using System;
using System.ComponentModel;
using System.Configuration;
using System.Configuration.Install; // in System.Configuration.Install.dll
using System.ServiceModel;
using System.ServiceProcess;
using System.ServiceModel.Web;
using System.IO;
using System.ServiceModel.Description;
using System.ServiceModel.Channels;
using System.Xml; // in System.ServiceProcess.dll
namespace Microsoft.ServiceModel.Samples
{
// Define a service contract.
[ServiceContract(Namespace = "http://Microsoft.ServiceModel.Samples")]
public interface ICalculator
{
[OperationContract]
double Add(double n1, double n2);
[OperationContract]
double Subtract(double n1, double n2);
[OperationContract]
double Multiply(double n1, double n2);
[OperationContract]
double Divide(double n1, double n2);
}
[ServiceContract(Namespace = "http://Microsoft.ServiceModel.Samples")]
public interface ICrossDomain {
[OperationContract]
[WebGet(UriTemplate = "clientaccesspolicy.xml")]
Message ProvidePolicyFile();
}
// Implement the ICalculator service contract in a service class.
public class CalculatorService : ICalculator
{
// Implement the ICalculator methods.
public double Add(double n1, double n2)
{
double result = n1 + n2;
return result;
}
public double Subtract(double n1, double n2)
{
double result = n1 - n2;
return result;
}
public double Multiply(double n1, double n2)
{
double result = n1 * n2;
return result;
}
public double Divide(double n1, double n2)
{
double result = n1 / n2;
return result;
}
}
public class CrossDomainService : ICrossDomain {
private XmlReader MakeXml()
{
TextReader reader = new StringReader(@"<?xml version='1.0' encoding='utf-8'?>
<access-policy>
<cross-domain-access>
<policy>
<allow-from>
<domain uri='*'/>
</allow-from>
<grant-to>
<resource path='/' include-subpaths='true'/>
</grant-to>
</policy>
</cross-domain-access>
</access-policy>");
return XmlReader.Create(reader);
}
public Message ProvidePolicyFile()
{
XmlReader xmlReader = MakeXml();
return Message.CreateMessage(MessageVersion.None, "", xmlReader);
}
}
// Windows Service class which inherits from ServiceBase
// and contains the application entry point.
public class CalculatorWindowsService : ServiceBase
{
public ServiceHost serviceHost = null;
public ServiceHost serviceHost2 = null;
public static void Main()
{
ServiceBase.Run(new CalculatorWindowsService());
}
public void CalculatorService()
{
ServiceName = "WCFWindowsServiceSample";
}
// Start the Windows service.
protected override void OnStart(string[] args)
{
try
{
if (serviceHost != null)
{
serviceHost.Close();
}
if (serviceHost2 != null)
{
serviceHost2.Close();
}
// Create a ServiceHost for the CalculatorService type and
// provide the base address.
serviceHost = new ServiceHost(typeof(CalculatorService));
serviceHost2 = new ServiceHost(typeof(CrossDomainService));
// Open the ServiceHostBase to create listeners and start
// listening for messages.
serviceHost.Open();
serviceHost2.Open();
}
catch(Exception ex){
//To log the error
System.IO.FileStream fs;
if (System.IO.File.Exists(@"C:\Log.txt"))
{
fs = new FileStream(@"C:\Log.txt", FileMode.Append);
}
else fs = new FileStream(@"C:\Log.txt", FileMode.OpenOrCreate);
Byte[] bContent = System.Text.Encoding.GetEncoding("gb2312").GetBytes(ex.Message + "\r\n");
fs.Write(bContent, 0, bContent.Length);
fs.Close();
}
}
// Stop the Windows service.
protected override void OnStop()
{
if (serviceHost != null)
{
serviceHost.Close();
serviceHost = null;
}
if (serviceHost2 != null)
{
serviceHost2.Close();
serviceHost2 = null;
}
}
}
// Provide the ProjectInstaller class which allows
// the service to be installed by the Installutil.exe tool
[RunInstaller(true)]
public class ProjectInstaller : Installer
{
private ServiceProcessInstaller process;
private ServiceInstaller service;
public ProjectInstaller()
{
process = new ServiceProcessInstaller();
process.Account = ServiceAccount.LocalSystem;
service = new ServiceInstaller();
service.ServiceName = "WCFWindowsServiceSample3";
Installers.Add(process);
Installers.Add(service);
}
}
}
Install and start the Windows Service:
http://msdn.microsoft.com/en-us/library/ms733069.aspx
Add service reference in Silverlight project:
public Page()
{
InitializeComponent();
BasicHttpBinding binding = new BasicHttpBinding();
EndpointAddress ed = new EndpointAddress("http://localhost:7999/ServiceModelSamples/service");
ServiceReference3.CalculatorClient proxy = new SilverlightApplication1.ServiceReference3.CalculatorClient(binding,ed);
proxy.AddCompleted += new EventHandler<SilverlightApplication1.ServiceReference3.AddCompletedEventArgs>(proxy_AddCompleted);
proxy.AddAsync(1, 2);
}
void proxy_AddCompleted(object sender, SilverlightApplication1.ServiceReference3.AddCompletedEventArgs e)
{
//Breakpoint here. result should be 3.
}
Regards
Allen Chen
Microsoft Online Community Support
Please remember to mark the replies as answers if they help and unmark them if they provide no help.
guylemar
Member
16 Points
4 Posts
Re: Silverlight 2 and WCF - Protocol Error
Jun 05, 2008 11:08 PM | LINK
Thanks very much for that Allen.
I'll try that out and let you know how I get on.
guylemar
Member
16 Points
4 Posts
Re: Silverlight 2 and WCF - Protocol Error
Jun 06, 2008 06:10 AM | LINK
Hi Allen,
Thanks very much for the previous post - that got me 99% of the way there.
I just had to alter the OnStart( ) and OnStop( ) methods of CalculatorWindowsService so that the CrossDomainService was (also) started and stopped. Without this, I still received the 404 error.
Thanks again,
Guy
cncolder
Member
45 Points
29 Posts
Re: Re: Silverlight 2 and WCF - Protocol Error
Jun 30, 2008 03:53 AM | LINK
Silverlight 2 beta2 cannot reference webHttpBinding [:'(]
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
http://www.ViTarn.com/
SilverlightGeek
Member
20 Points
10 Posts
Re: Re: Silverlight 2 and WCF - Protocol Error
Jul 09, 2008 04:01 PM | LINK
I see the same on my end. I wrote a great WCF Rest compatible service using webHttpBinding and it worked great in Silverlight 2 Beta 1. Now that I've upgraded to Silverlight 2 Beta 2 it looks as though I can not use this Binding type anymore!??!
webHttpBinding was great because I could easily switch the encoding between XML or JSON. Has ANYONE found a way to use a webHttpBinding WCF service in Silverlight 2 Beta 2? Anyone???
harsha_hs
Member
44 Points
21 Posts
Re: Silverlight 2 and WCF - Protocol Error
Apr 08, 2009 09:19 AM | LINK
I am using Silverlight 2. I tried your sample, and services are running fine.
I get calculator service when I type this URL: http://localhost:7999/ServiceModelSamples/service
and I get clientaccesspolicy file when I type this URL: http://localhost:7999/clientaccesspolicy.xml
But when I run my silverlight application, I get following error:
An error occurred while trying to make a request to URI 'http://localhost:7999/ServiceModelSamples/service'. 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. Please see the inner exception for more details.
But, I used Nikhil's Web Development Helper, I see that Silverlight app is getting 'clientaccesspolicy.xml' since it is giving 200.
I don't know what is the problem? Is it because even Silverlight 2 Doesn't support webhttpbinding? If so what is the workaround?
HarshBardhan
Star
10118 Points
1749 Posts
Re: Silverlight 2 and WCF - Protocol Error
Apr 09, 2009 11:32 AM | LINK
specify binding as basichttp binding and check.
Harsh Bardhan