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.

13 comments:

  1. You mentioned that "The best practice for a Web application is to use SQL server authentication", first of all shall I use sa or create a new one? If a new one is better, the which role is the most appropriate? Thanks.

    ReplyDelete
  2. You can use either sa account or to create a new User account. A new User account which only has access to this particular database instance might be better. The Account should have the right to do every operation your application requires.

    ReplyDelete
  3. thanks for your help
    i. when i buld my project without changemy connection string its ok.and then iright click on my database and click on 'include in project'
    change my connection to
    ""
    but when i run my project and want add new user or login by last user get an error
    "... , login Faled for 'NewID'"
    i think when i create DB in first time with out username and password after change Coneection string its not work.
    and it's beter that i set i user and password for my dataBase
    2. if i want add more option in register form , how can i do it.
    thanks
    hossein.aftabi@gmail.com

    ReplyDelete
  4. I've just finish editing my web config as your recommendations and It's working fine .....

    You are the best :)

    Thanks

    ReplyDelete
  5. The updated URL for the official troubleshooting document is

    http://msdn.microsoft.com/en-us/library/ff426913(v=VS.91).aspx

    Also, sa should never be used to login your application, that is a common cause of websites getting hacked.

    ReplyDelete
  6. very useful. thanks for sharing.

    ReplyDelete
  7. I had been struggling for one day till I came to this post. It saves my life :-). Appreciate.

    ReplyDelete
  8. I would not use SQL Authentication. Most places will require the use of integrated authentication. SQL Authentication is a large security risk generally speaking.

    ReplyDelete
  9. I would never suggest SQL Authentication. It is not the best but the worst practice. OTOH I accept that people choose the risky path when MS makes things complex.

    ReplyDelete
  10. I have done all the steps but I sill have errors on deploying to GoDaddy. Error: Load operation failed for query 'Get User'. The remote server returned and error: NotFound

    ReplyDelete
  11. Hi, if I run the .aspx file the browser gets redirected to login.aspx which don't exist. Do you have an idea?

    ReplyDelete
  12. Hi there, In the post you mentioned that the App_data folder supposed to have the aspnetdb.mdf, but I have checked but nothing is there. any idea what can I do to fix this?

    ReplyDelete
  13. Extraction condensing steam turbine- essels is a leading manufacturer of safe, proven and reliable Extraction condensing Steam Turbines and Double extraction condensing steam turbines built with high quality precision engineering, possessing heavy duty characteristics.

    ReplyDelete