UPDATE: Please read the updated information on RIA Services deployment and troubleshooting on MSDN..
So you’ve been playing around with Silverlight and WCF RIA Services (the artist formerly known as .NET RIA Services) and you are ready to deploy. You’ve been living in your happy Visual Studio environment, perhaps even relying on the built-in web server (a.k.a. Cassini) to serve up your pages/XAP to test. All has been well, you’ve done your testing and you are ready to publish to your server. You compile one last time and then right-click in Visual Studio on the web project and click Publish. You push to your IIS endpoint or via FTP and the files deploy. Sweet! Now you go visit your site. And it doesn’t work. WTF?
I’ve been getting some emails on RIA Services deployment gotchas and thought I’d take a stab at explaining some of the deployment nuances.
First it should be said that there is no greater supplement than having your dev environment match as close as possible to your ending target production environment. If you are using IIS6 to host your final application, then it would be ideal that it is also your development/test environment. I know this isn’t always possible for everyone, but if it is, make the effort and save yourself some time in the long run.
What is described below are some things you might run into. Not everyone will…some will not hit any of these. But hopefully if you do, this will be some insight.
Deploying the RIA libraries – to bin or not to bin
Your first error you may run into is assembly loading errors in your ASP.NET application. Perhaps it says that it cannot locate or load System.Web.Ria assembly? And here you thought the Publish command was going to deploy those for you, didn’t you (note: so did I). Well, they aren’t. You can do two things here.
First, you can “bin deploy” if you want. That term means that you would deploy any non-core framework assemblies in your web applications /bin directory, making them locally available to the web application. If you want to go this route, you can. You have to manually go into your references in your web application and change the Copy Local property on some assemblies:
The assemblies you would want to do this on (depending on what you have referenced) would be:
- System.Web.DomainServices.* (there 4 of them depending on what you are using)
- Microsoft.RiaServices.Tools UPDATE: this assembly only required for design-time experiences
Once you do that, on your next compile, these assemblies would be copied to your bin directory and then the subsequent Publish action would also push those to your server.
The second option you have is to install the RIA Services server libraries on the server in the Global Assembly Cache (GAC). You may have tried this already and run the RiaServices.msi installer on your server and received the warning that you are missing Visual Studio and all sorts of tools.
And then you walked away and went the bin-deploy route. Well open up a command prompt and run this instead:
1: msiexec /i RiaServices.msi SERVER=TRUE
And the server assemblies for RIA Services will be installed into the GAC for all to enjoy. The advantage this has is that it becomes easier to service if you have one set of assemblies to update versus a few /bin deployed applications scurried all over the place.
HTTP Scheme violation and IIS host-headers
Now you run your application and you get this exception:
This collection already contains an address with scheme http. There can be at most one address per scheme in this collection.
Parameter name: item
Now you’re starting to wish your development environment mirrored your deployment environment aren’t you? :-) This lovely error message will leave you wondering what is going on for a while if you didn’t know what it meant. I mean, it’s completely descriptive isn’t it? Of course not.
If you are getting this, you are likely running Windows 2003 server (IIS6) and are using host-headers in IIS.
NOTE: Host headers in IIS allow you to leverage a single IP address, but have separate web sites that respond to different hostname requests. This information is usually provided in the IIS management console and is stored in the IIS metabase.
If this isn’t you, or you aren’t controlling your server, I’m guessing you are in a shared hosting environment.
NOTE: Full trust is required for RIA Services. UPDATE: Partial trust is supported for .NET4/VS2010, full trust requirement is only for .NET 3.5/VS2008.
Either way, what you are seeing is a limitation of Windows Communication Foundation (WCF) under .NET 3.x. There are a few things you can do here.
If you are running .NET 3.0 (well, you likely aren’t running RIA Services then are you) – but here’s some information on creating your own ServiceHostFactory…which isn’t really an option here.
If you are running .NET 3.5 (more likely), and can get to your web.config setting, you can add this setting:
2: <serviceHostingEnvironment aspNetCompatibilityEnabled="true">
4: <add prefix="http://some.url.here.that.matches.a.host.header"/>
Note that the prefix you are using must match the base URI of where your DomainService will be at as well as it must exist as a mapped host-header for the site. More information available here.
if you are running .NET 4, you may not run into this issue, but there may be an optional opt-in configuration you will have to do when .NET 4 releases.
UPDATE: HttpModule for DomainService
Perhaps one thing that I assumed was that you’d be pushing the web app completely. But what if you already have a web.config and you aren’t pushing that over there. Well, pay attention to the web.config of a RIA Services created project. You’ll see an HttpModule set up (this one is from VS2010, but will be similar, just version numbers different):
2: <add name="DomainServiceModule" type="System.Web.Ria.Services.DomainServiceHttpModule,
3: System.Web.Ria, Version=188.8.131.52, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
If you don’t have this, then you might see some weirdness. You see, for the default deployment, the service is handled through this module. You may have noticed that there are no physical .SVC files in your web app. If you look with Fiddler at your Silverlight/RIA Services application in action you’ll see something like /ClientBin/Your-Namespace-Here-Method.svc/binary. This is actually interpreted by the module to map the request.
If you wanted to generate a physical file yourself, you can do that and the request would be processed there versus through the virtual SVC file generated. You can read about this in Saurabh’s post.
Multiple Authentication Schemes
Okay, now you run it again and you get a message about it not supporting multiple authentication schemes and that you may have. The message may look like this:
IIS specified authentication schemes 'IntegratedWindowsAuthentication, Anonymous', but the binding only supports specification of exactly one authentication scheme. Valid authentication schemes are Digest, Negotiate, NTLM, Basic, or Anonymous. Change the IIS settings so that only a single authentication scheme is used.
This can be a result of your <authentication> node in your ASPNET application being set to Windows, but your site being set to Anonymous in IIS. For most, simply changing <authentication> node to mode=”Forms” will remove this error and allow you to continue. For others, if your IIS configuration is set to use both Integrated Auth as well as Anonymous, you’ll want to uncheck one of them in the Directory Security setting for the site in IIS management console.
Install the Hotfix (XP, Vista, Windows 2003)
As noted on the RIA Services information page, if you are not running Windows 7 or Windows 2008 R2, you need to install a Hotfix. Some people haven’t seen this note, so be sure if you fall in that category that you grab the appropriate hotfix for your architecture and run it. UPDATE: This hotfix is only needed if you are using VS2008.
So how can you troubleshoot all these things? Some wondered where I was able to get the error messages, when their response errors in Silverlight were just showing NotFound. I’ve said this again with regard to debugging services, especially cross-domain stuff, that if you aren’t using an HTTP diagnostic tool you are hurting your productivity in debugging. I use Fiddler. I used to use Web Development Helper a lot more, but have run into some problems with it registering in IE and Fiddler has finally got rid of all nuances that bothered me with it. Some others have used Charles proxy which I’ve heard is really great, but requires Java if you don’t have it. Any one of these tools can provide invaluable debugging information to help triage your issue. Sometimes the HTTP response code isn’t the full story and the response body will help tremendously.
NOTE: If you are using Fiddler for http://localhost debugging, you may have seen some challenges. In the URL, change to http://127.0.0.1./site – noting the trailing “.” after the IP address. Example: http://127.0.0.1.:12345/MyApp – this will trigger Fiddler to monitor those requests as well.
For WCF binary encoding messages, be sure to download WCF Binary-encoded message inspector if you are using Fiddler…it’s awesome (hat tip to Dan Wahlin for the tip).
I suspect anyone running into these issues above is likely using Silverlight 3/VS2008 and deploying to an IIS6 instance. Truly this is where the issues might manifest themselves. When WCF RIA Services comes out of beta/ctp status and releases next year, the development story will be that of Silverlight 4 and .NET 4 on the server. As noted above, these WCF issues (with host-headers) are solved with .NET 4 on the server, so this post will be useless when the bits release.
I hoped by posting this though, that some in the interim might find some better troubleshooting tips with regard to the shared hosting scenario mostly. I personally ran into a few of these myself on my own dedicated server that uses host-headers (but is still full trust), so I thought others might benefit from the steps that I went through to get my RIA Services application deployed on a server.
Hope this helps.