in

ASP.NET Weblogs

Tolga Koseoglu

Silverlight 2.0 and WCF

Having had some time to digest all the news from MIX08 I am working on converting a Silverlight 1.1 project to Silverlight 2.0. One of the major changes is to move from ASMX services to WCF services. Now, that cross-domain access is possible and with WCF inherently being more complex there are a lot of failure points.

So, having spend probably a total of 8 hours on updating the structure of the new project and deploying it to a production environment I thought I'd share this with you so you don't have to spend that much time. Since most of the time spent had to do with deployment and WCF configurations I will focus on that.

The 3 main challenges I needed to figure out were...

  1. Windows authentication versus Anonymous authentication. This is solely WCF and doesn't have to do with Silverlight directly.
  2. Cross-domain access. This is important when troubleshooting your service, which has been deployed to production, and referencing it within your local Visual Studio Silverlight project.
  3. Asp.net Compatibility. Again, WCF only configuration.

1. Windows vs. Anonymous authentication.

By default, WCF requires you to have your IIS virtual directly configured to be accessible anonymously. However, if you do some kind of domain related stuff you need your IIS virtual directly to be configured to be Windows Authentication. Here is the code to update your web.config file of the WCF web application.

<system.serviceModel>

        <bindings>

            <basicHttpBinding>

                <binding name="MyBinding">

                    <security mode="TransportCredentialOnly">

                        <transport clientCredentialType="Windows" />

                    </security>

                </binding>

            </basicHttpBinding>

        </bindings>

        <behaviors>

            <serviceBehaviors>

                <behavior name="DesignDBServiceBehavior">

                    <serviceMetadata httpGetEnabled="true"/>

                    <serviceDebug includeExceptionDetailInFaults="false"/>

                </behavior>

            </serviceBehaviors>

        </behaviors>

        <services>

            <service behaviorConfiguration="DesignDBServiceBehavior" name="DesignDBService">

                <endpoint

                    address=""

                    binding="basicHttpBinding"

                    contract="IDesignDBService"

                    bindingConfiguration="MyBinding">                   

                </endpoint>               

            </service>

        </services>

        <serviceHostingEnvironment aspNetCompatibilityEnabled="true"/>

    </system.serviceModel>

2. Cross-domain access.

I mainly just needed to get this working because I tried to debug my local SL project having referenced and external cross-domain WCF service. In order to get this working you need to put a "clienataccesspolicy.xml" in the root of your IIS server. This is usually at C:\inetpub\wwwroot. If the file is there and granted the file allows your local domain of your SL project access, Silverlight will automatically acknowledge the file and give access. So, there is nothing you need to do within Silverlight. HOWEVER, MAKE SURE TO RESTART IIS. THE FILE IS NOT RECOGNIZED RIGHT AWAY.

<?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>

3. Asp.net Compatibility

This involves two steps

1. Change to the web.config file of the WCF web application.

<serviceHostingEnvironment aspNetCompatibilityEnabled="true"/>

   add this line into the root of <system.serviceModel>.

2. Adding of a class property of the service class, not the service interface.

using System;
using System.ServiceModel;
using System.Configuration;
using System.Web;
using System.Web.Configuration;
using System.ServiceModel.Configuration;
using System.Text;
using System.Security.Principal;
using System.ServiceModel.Activation;
using System.Collections.Generic;


using System.Linq;

[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class DesignDBService : IDesignDBService
{

Comments

 

どっとねっとふぁんBlog said:

Silverlight 2.0 and WCF 今後きっと参考にするだろう情報なのでメモ。 WCFをきちんとやらないとな。。。

March 19, 2008 3:52 AM
 

Ryan said:

Thank you for this - I'll be checking this out soon and hoping that it solves my error as well!

March 19, 2008 2:22 PM
 

arigney said:

Dear Tolga,

                     I am still getting this security error trying to call my WCF web service from my silverlight 2 application.  Here is the error.

I made the change you said was required for WCF to use windows authentication, but I still get the same error. I have also setup a ICrossDomainPolicyResponder but that didn't work either. Can you help me please?

{System.ServiceModel.CommunicationException: An error occurred while trying to make a request to URI

'localhost/.../main'. This could be due to a cross domain configuration error.

Please see the inner exception for more details. ---> System.Security.SecurityException: Security error.

  at MS.Internal.InternalWebRequest.Send()

April 7, 2008 12:58 AM
 

Hemant said:

Hi

I made a simple wcf service hosted in iis. I am trying to call it in silverlight 2 application. I added crossdomain.xml, clientaccesspolicy.xml in the root of service folder.

The service is accessed anonymously i and also followed the third step.

Still i get an exception  of type 'System.ServiceModel.ProtocolException'.

Additional information: The remote server returned an unexpected response: (404) Not Found.

can you tell what i am missing ?

April 11, 2008 10:10 AM
 

Hemant said:

Solved it.

Silverlight app was not getting clientaccesspolicy.xml

followed the post here

timheuer.com/.../silverlight-cannot-access-web-service.aspx

Thanks.

April 11, 2008 10:51 AM
 

codism said:

How can I pass some information between client and server for all calls. Well, I may be asking a wrong question. I read many online articles about WCF security and Sliverlight. They sound like they are all talking about how to authenticate a client. In my case, it's ok to allow anonymous access to all end points. But if a record can be returned or an operation should be performed is determined in code, by the user name and password provided in a context object, which was input at the first time a user signed in and attached automatically (through a static member in the framework, I guess) to each call to the service.

Could you point me out the solution in Silverlight 2?

April 11, 2008 11:52 AM
 

codism said:

In my application, it is ok to allow anonymous access to all end points. But the logic determining if a certain operation can be preformed is in code, by user information provided in a context object. Could you point me out the solution to pass user information automatically for each service call?

April 11, 2008 11:58 AM
 

kemaltolga said:

Hello everyone:

I apologize for not getting back to you guys earlier. I feel you pain, since it has been mine for days as well. All I can tell you is that what I posed works.

for some of you it seems like the issues are within WCF.

I recommend isolating the issue...

1. Create a regular web app and try to consume the WCF services you created.

2. Create a silverlight project WITH an web application.  Build the same WCF service within the Silverlight host web site and run it. Cross domain erros should not appear here, since the Silverlight project and the hosting web project are part of the same solution.

3. Try to consuem the first WCF you created. It needs to be hosted in IIS with the crossdomain.xml file in the root. In my case...wwwroot.

Good luck

--tolga

April 19, 2008 12:51 AM
 

Vijay said:

We have to put the crossdomainpolicy.xml file in the folder C:/Inetpub/wwwroot and host the WCF Web application in IIS by going to properties window of WCF Web Application project, select the Web tab and select the option "Use IIS Web Server". This has to be done in case our WCF service is hosted on a remote machine other than the client app machine....It worked for me...

April 25, 2008 2:18 AM

Leave a Comment

(required)  
(optional)
(required)  
Add

About kemaltolga

Born in Ankara, Turkey. Raised in Germany. Recruited for the Track & Field Team at Texas A&M University in College Station, TX, in January 2000. NCAA champion in 2001 (Discus). Work for design firm in southern California. Married with one daughter (born 1/6/2006).