Reputation: 727
I am trying to hit a self hosted WCF service from my Silverlight application but it is not working. The service is configured to use SSL and I can hit it using the WCFTestClient tool, a web browser, and I can reference the service and update it from within the silverlight project. The problem is when the silverlight application tries to make a call to the service, it bombs with the following error:
The server did not provide a meaningful reply; this might be caused by a contract mismatch, a premature session shutdown or an internal server error.
When I hit it using the WCF Test Client tool, it returns data without issues (as expected).
Any ideas?
Below is my app config:
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="basicHttp" closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard" maxBufferPoolSize="2147483647" maxReceivedMessageSize="2147483647" messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true" allowCookies="false">
<readerQuotas maxDepth="32" maxStringContentLength="2147483647" maxArrayLength="6553600" maxBytesPerRead="4096" maxNameTableCharCount="16384"/>
<security mode="Transport">
</security>
</binding>
</basicHttpBinding>
<webHttpBinding>
<binding name="webHttp" closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard" maxBufferPoolSize="2147483647" maxReceivedMessageSize="2147483647" useDefaultWebProxy="true" allowCookies="false">
<readerQuotas maxDepth="32" maxStringContentLength="2147483647" maxArrayLength="6553600" maxBytesPerRead="4096" maxNameTableCharCount="16384"/>
<security mode="Transport">
</security>
</binding>
</webHttpBinding>
</bindings>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true"/>
<services>
<service name="Application.ServiceModel.ApplicationService" behaviorConfiguration="serviceBehavior">
<host>
<baseAddresses>
<add baseAddress="https://192.168.1.171:8000/ApplicationServiceModel/service"/>
</baseAddresses>
</host>
<endpoint address=""
binding="basicHttpBinding"
bindingConfiguration="basicHttp"
contract="Application.ServiceModel.IApplicationService" />
<endpoint address="mex"
binding="mexHttpsBinding"
contract="IMetadataExchange"/>
<endpoint address="http://localhost:8000/"
binding="webHttpBinding"
contract="Application.ServiceModel.IApplicationService"
behaviorConfiguration="webHttpBehavior" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="serviceBehavior">
<serviceMetadata httpsGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="true"/>
<dataContractSerializer maxItemsInObjectGraph="2147483647"/>
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="webHttpBehavior">
<webHttp />
</behavior>
</endpointBehaviors>
</behaviors>
</system.serviceModel>
Upvotes: 0
Views: 1229
Reputation: 31
@carlos: Your code works great for http. However, I am not able to get it to work for https. I simply get "clientaccesspolicy.xml" is not found...
I have made these modifications to the main function:
public static void Main()
{
string baseAddress = "https://" + Environment.MachineName + ":8000";
ServiceHost host = new ServiceHost(typeof(Service), new Uri(baseAddress));
BasicHttpBinding basicHttpBinding = new BasicHttpBinding(BasicHttpSecurityMode.Transport);
host.AddServiceEndpoint(typeof(ITest), basicHttpBinding, "basic");
WebHttpBinding webHttpBinding = new WebHttpBinding(WebHttpSecurityMode.Transport);
HttpTransportSecurity httpTransportSecurity = webHttpBinding.Security.Transport;
httpTransportSecurity.ClientCredentialType = HttpClientCredentialType.None;
httpTransportSecurity.ProxyCredentialType = HttpProxyCredentialType.None;
WebHttpBehavior webHttpBehavior = new WebHttpBehavior();
host.AddServiceEndpoint(typeof(IPolicyRetriever), webHttpBinding, "").Behaviors.Add(webHttpBehavior);
ServiceMetadataBehavior smb = new ServiceMetadataBehavior();
smb.HttpsGetEnabled = true;
host.Description.Behaviors.Add(smb);
host.Open();
Console.WriteLine("Host opened");
}
Further, I have made these modifications to the GetSilverlightPolicy() function:
public Stream GetSilverlightPolicy()
{
string result =
@"<?xml version=""1.0"" encoding=""utf-8""?>
<access-policy>
<cross-domain-access>
<policy>
<allow-from http-request-headers=""SOAPAction"">
<domain uri=""https://""/>
<domain uri=""http://""/>
</allow-from>
<grant-to>
<resource path=""/"" include-subpaths=""true""/>
</grant-to>
</policy>
</cross-domain-access>
</access-policy>";
return StringToStream(result);
}
Upvotes: 3
Reputation: 87228
Silverlight clients cannot, by default, make networking requests to domains other than the one where the .XAP file was loaded (i.e., cross-domain requests). If you want to access a self-hosted WCF service (which means a X-domain request), the service must provide a policy file to the Silverlight runtime saying that it's OK for such requests to be made.
You can find an example of how to enable cross-domain calls for self-hosted services in the post at http://blogs.msdn.com/b/carlosfigueira/archive/2008/03/07/enabling-cross-domain-calls-for-silverlight-apps-on-self-hosted-web-services.aspx. Since your service uses HTTPS, you'll need to serve the policy using HTTPS as well, but otherwise the code in the post should work for you.
Upvotes: 1