Saturday, February 26, 2011

Steps to Deploy Silverlight Business Application

Many people have trouble deploying Silverlight Business Applications to IIS. They tested everything under Visual Studio. But once they deploy the app to IIS, the app stops working. Either Silverlight can't connect to the service any more, or there are database connection related errors.

If you have trouble deploying your Silverlight Business Applications, check this general RIA deployment guide first:
http://blogs.msdn.com/b/bradsevertson/archive/2011/02/17/a-guide-to-deploying-ria-services-solutions.aspx 

If you are still having trouble, let's do this step by step to deploy a Silverlight application created by using the Silverlight Business Application Template:

1) Create a Silverlight Business Application in Visual Studio (VS).

Run your app by hitting F5 under VS. The application's main page is loaded in your default browser. Click the Login button. First you need to Register a user: Click "Register Now" button on the Login window; enter your user information to register. After you are done the login window is closed and you should already be logged in. Click Logout button to Logout. Click Login Button to login again. If everything works at this point, we can consider we already tested every feature of this application and ready to deploy it.  

You may wonder how everything just works by itself and you haven't even written any code yet. Where is the user data stored at? Those things are done by the code generated by VS.

When VS create this project, there is a SQL server database file ASPNETDB.mdf created under the App_Data folder in the Web Project.  This DB file holds application user membership data used by the authentication service. The connection to this DB is defined under the Web.Config <connectionstrings/> section.  It looks something like this:

<connectionStrings>
            <add name="ApplicationServices" connectionString="data source=.\SQLEXPRESS;Integrated Security=SSPI;AttachDBFilename=|DataDirectory|aspnetdb.mdf;User Instance=true" providerName="System.Data.SqlClient"/>
</connectionStrings>

If you are using earlier version of the RIA service (earlier than RIA service SP1 beta), you may not see the connection string under the Web.Config.  If this is the case,  the default connection string used by ASP.NET authentication service is defined in the machine.config. You can check your machine.config under x:\<windows>\Microsoft.NET\Framework\<version>\config\machine.config.

You should see the following connection string defined in machine.config:

<connectionStrings>
            <add name="LocalSqlServer" connectionString="data source=.\SQLEXPRESS;Integrated Security=SSPI;AttachDBFilename=|DataDirectory|aspnetdb.mdf;User Instance=true" providerName="System.Data.SqlClient"/>
</connectionStrings>

If you are on earlier version of RIA and do not see connection string in your Web.Config,  first thing you should do is to add one to override the connection string set in machine.config.

Add the following to your Web.config file:
<connectionStrings>
    <clear/> <!-- This is important, make sure you have this line-->
    <add name="LocalSqlServer" connectionString="data source=.\SQLEXPRESS;Integrated Security=SSPI;AttachDBFilename=|DataDirectory|aspnetdb.mdf;User Instance=true" providerName="System.Data.SqlClient"/>
</connectionStrings>

When you are under development, the project is using SQL Express to access the DB file. Remember SQL Express is for development only. When you finally deploy your app, you should use a full version SQL server in your production.  But for testing purposes, you can still use SQL Express to test your deployment.

2) Change the connection string to use SQL server authentication in the Web.Config:

The default connection string uses Windows authentication. It works under the DEV server when you are running the app under VS because the thread is running under the current windows user account. But when you are running the app under IIS, the thread is running under "NT AUTHORITY\NETWORK SERVICE" user account.  This user account does not have the right to access the SQL server unless you give it that right.  The best practice for a Web application is to use SQL server authentication.

If this is your original connection string:
<add name="ApplicationServices" connectionString="data source=.\SQLEXPRESS;Integrated Security=SSPI;AttachDBFilename=|DataDirectory|aspnetdb.mdf;User Instance=true" providerName="System.Data.SqlClient"/>

Change it to the following:
<add name="ApplicationServices"
         connectionString="data source=.\SQLEXPRESS;Integrated Security=False;User ID=YOURUSERID; Password=YOURPASSWORD;AttachDBFilename=|DataDirectory|aspnetdb.mdf;User Instance=False" providerName="System.Data.SqlClient" />

If this is your original connection string:
<add name="LocalSqlServer" connectionString="data source=.\SQLEXPRESS;Integrated Security=SSPI;AttachDBFilename=|DataDirectory|aspnetdb.mdf;User Instance=true" providerName="System.Data.SqlClient"/>

Change it to the following:
<add name="LocalSqlServer"
         connectionString="data source=.\SQLEXPRESS;Integrated Security=False;User ID=YOURUSERID; Password=YOURPASSWORD;AttachDBFilename=|DataDirectory|aspnetdb.mdf;User Instance=False" providerName="System.Data.SqlClient" />

3) Include ASPNETDB file in the deployment package.

If you want to deploy the ASPNETDB.mdf file with your solution, you need to include this file into your Web Project.

Click Project Menu on the VS Top Menu bar, select "Show All files". You should now see the ASPNETDB.mdf file under the App_Data folder under the Web project. It is not included in the Project by default.  Right click the file and select "Include in Project".

Any files you want to include in the deployment package, you need to include them into the project. Otherwise, the folder or files won't be published.

4) Build your solution. Do a final test of your app under VS.

4) Publish your app to a local file folder

If everything works at this point, you can publish the solution using the publish feature under VS. Right click your Web project to select "Publish ...". Select File System as your publish target. Select a local file folder to publish the package.

5) Test your deployment on your local IIS.

This is a important step. Before you finally publish the application to the hosting server, test it on your local IIS first, so you still have a chance to debug the problems if you find any. 

Open the IIS Admin tool (under Computer\Manage\Service and Applications) on your local computer. Add an Application under Default Web Site to point to the published folder you just created. Make sure that you select ASP.NET v4.0 as the application pool.

Under IIS Admin, right click the web application, go to Authentication Details, make sure only the Anonymous authentication and Forms authentication are enabled.

6) Test your App by enter "http://localhost/YourApplication/YourTestPage.html" in a browser.

If you find problem running under local IIS, you can use "Attach to process ..." VS feature under the Debug menu to debug your code. For server side code debugging, attach to "w3wp.exe". For Silverlight code debugging, attach to the browser process that you are currently running at.

7) If everything works, you can deploy your app to the final hosting server by copying the whole folder over.

8) For the final deployment, switch to use full version SQL server. 

You can attach the ASPNETDB.mdf file to your SQL server, then change your connection string to point to that SQL server instance.
         connectionString="data source=YOURSQLSERVER; Initial Catalog=YourDBInstanceName;Integrated Security=False;User ID=YOURUSERID; Password=YOURPASSWORD; User Instance=False"

You should also consider to encrypt the connection string for security.  Read the instruction on how to do this:
http://msdn.microsoft.com/en-us/library/ms178372.aspx

Hope this step by step guide can help you understand the problems you are having and make your application deployment process a smoother one.