This is now a Visual Studio 2010 suggestion.  Please VOTE IT UP to get it included in the final realease:

https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=514045

Visual Studio 2010 introduced a myriad of new features.  One of them that I have found myself using a lot lately is the ability to define a Publish Profile.  This lets you define a profile of how and where to deploy a web application.  So I can create a deployment profile for Development and point that to the development web servers and another for testing and so on. 

image

The only thing I feel it is lacking is the ability to pick a different web.config file for the various profiles.  So that I can have a Dev, Test, and Prod web.config file.  It would be really cool if the Publish Profile tool would let me associate a .config file in my project as the web.config for that publish profile.

So the situation is this… I have a Silverlight LOB application that I need hosted in the Windows Azure cloud.  The Silverlight application hits a series of WCF Services that provide data from a SQL Database.  So for this project I needed to accomplish the following goals:

1) Deploy a SQL Server 2008 database to the SQL Azure cloud.

2) Deploy and configure my WCF Services to the Windows Azure cloud such that they hit the SQL Azure database.

3) Deploy and configure the Website application that hosts the Silverlight 3 LOB application such that it hits the WCF Services running on the Windows Azure Cloud.

Publish your SQL Server Database to SQL Azure

Follow the steps outlined here:
http://msdn.microsoft.com/en-us/library/ee621790.aspx

There are some great resources for working with SQL Azure here:
http://msdn.microsoft.com/en-us/library/ee621784.aspx

Once complete, you should be able to query your SQL Azure database from SQL Server Management Studio and retrieve your data from the cloud.  This does in fact work with the Nov. 2009 release of SQL Azure.  Note that SSMS can NOT currently show you any of the DB Meta info in the GUI, you can simply query your db with a new query window.

Also, be sure to add your public IP to the SQL Azure Database Firewall settings.

image

Converting the WCF Services to an Azure WCF Role

Since this is an existing application I did not want to mess around with my source controlled and working application code.  I decided to create an Azure version of my project and copy my source files in. 

I started by creating a new Windows Azure Cloud Service in Visual Studio 2010 b2.

image

I added a Web Role and a WCF Service Role.

image

Note that when you add these roles you can hover over the role and click the pencil link.  This will let you rename the Role.  This is important because it is a royal pain to rename everything after the fact.

Now that you have your new roles.  Copy your service code and resolve your references so that your WCF service compiles.

Decorate your WCF Service Class with the ServiceBehavior attribute and set the AddressFilterMode to Any.  This is needed to get your WCF Service to work in the cloud.  You can read up more about it online here.


 

Add your Silverlight Application To the Web Role

I am actually considering simplifying my deployment a bit by including the Silverlight application and the Default.aspx web page all in the same Role.  If I decide to do this I will update this posting.

So now you have your Database and WCF Service set up you need to Add your Silverlight application to the Web Role that will display the Silverlight application.  To do this make sure your Silverlight project is included in the new Azure solution.  Open the Default.aspx page in the new Azure Web Role project and insert the necessary HTML and Javascript to display your Silverlight application.  You can cut and past this from the Silverlight test page if you like.

Now, link the Azure Web Role project to the Silverlight project so that every time you build, your XAP file (the Silverlight bits) is updated in the Azure Web Role project. 

image

Right click on your Azure Web role project and choose Properties.  Click the Silverlight Applications tab.  Here you can link a Silverlight application to this web app so that it is updated when the Silverlight project is built.

Test the Web Role project and it should build and display your Silverlight application.  Once this is working we need to tie all of these applications together.

CSCFG Cloud Service Configuration

You need some way of telling the Silverlight application where the WCF Service is located.  Modifying a Web.config file is not a viable option.  With an application deployed to the Azure Cloud you need to be able to configure the Silverlight application outside of the Web Application and Outside of the ServiceReferences.ClientConfig file.

I will post another blog entry about dynamically configuring Silverlight for WCF.  Here I will give you the ingredients:

Add the initParams tag to the Silverlight ActiveX Control definition in the HTML page that hosts your Silverlight application.  In the initParams you must pass in the base URL for your WCF Service(s).  My init params looks like this:


This allows the HTML page to pass in configuration parameters to the Silverlight application.  The Silverlight application needs to read these values in the App.xaml.cs file like this:


I use a Proxy Factory to create the instance of my WCF Service Proxies so I have only one place to update the construction of my WCF Proxies like this:


Once you have done all this, your Silverlight application is now properly plumbed to allow you to pass in the WCF Service Url.  There is one more step here and that is to read the WCF Service url from the Cloud Service Configuration File.

First, You need to define a configuration setting in the ServiceDefinition.csdef file:


Next, actually define the value for the new Setting in the .cscfg file:


Now, you need to update your HTML/ASP.NET website so that it will read the config setting from the .cscfg file and pass that value to your silverlight application.  I did this by defining a public method on my Default.aspx.cs code behind file that retreives the value for me.

 


Now a quick update to my .ASPX page that displays the Silverlight application and we are set!

 


So now you are all wired up.  You can now deploy the application to the Azure Cloud.  After deployment use the configure button to configure the .cscfg file to point to the staging or production URL of your WCF Service.

 

I am wrapping up a Silverlight 3 LOB application and decided to change my WCF Bindings from basicHTTP to Custom/Binary because I was receiving network issues.  After doing this and changing my client bindings all hell broke loose. 

I started getting the error:

Cannot create a service reference with namespace X because the name is already in use by an existing service reference, folder or file

Followed the directions here and got close.  I even tried to create the service references again with a different name and got the following:

Custom tool warning: cannot import wsdl:portType

My solution was this:

(Under your Silverlight application project folder.)

  • Delete everything from obj and bin.
  • Remove the service references from ServiceReferences.ClientConfig
    (You should just have <configuration />.)
  • Delete the service references in your project.
  • Delete from your project folder/Properties/DataSources all the data sources created for your service references.  If you did not create any datasources manually then all of these can go.

This did fix my problem.  I hope this helps you also.

So in WPF you can use RelativeSource binding and Element binding to bind one visual element’s properties to another visual element’s properties.  You probably have discovered this is non-trivial in Silverlight.  If you are using an MVVM patter to develop your Silverlight application your life just got easier!

Why?  Take this example: 

image

You are building a user editor that lets you link roles to a user.  You want the Add Role and Remove Role buttons to only become enabled if the user has clicked a role. 

The solutions is simple.

In your ViewModel class create a boolean property called AvailableRolesSelectedIndex and a property called IsAddRoleEnabled.


(*Note I use a ViewModelBase class that defines a function called SafeNotify().  All this does is fire the PropertyChanged event for the INotifyPropertyChanged implementation on my ViewModel.)

Now, in the XAML, simply bind the AvailableRolesSelectedIndex property to the ListBox’s SelectedIndex property and bind the IsEnabled property of the Add Role button to the IsAddRoleEnabled property.

 


I also had to add to the constructor of my ViewModel class an initializer for my AvailableRolesSelectedIndex property.  You want it initialized to –1 or when the initial databinding occurs you will receive an error because the integer’s default value is 0, which does not exist in the listbox until the data is there.


Now I get a great little effect without having to interact directly with the controls on the View from my ViewModel.

Initial state:

image

Item clicked:

image

Error    1    The type or namespace name ‘log4net’ could not be found (are you missing a using directive or an assembly reference?)    c:\projects\DevSQL\…\Properties\AssemblyInfo.cs    4    7    SomeService

And warning:

Warning    8    The referenced assembly "c:\projects\DevSQL\…\AccountService\aaa.ServerCommon\bin\Debug\aaa.ServerCommon.dll" could not be resolved because it has a dependency on "System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" which is not in the currently targeted framework ".NETFramework,Version=v4.0,Profile=Client".    aaaService

 

image

So you are getting an error that typically points to an assembly reference not found.  Well just hang on a second before you go wild with debugging this.  First, check to make sure that there are no yellow exclamation marks on the assembly reference.  That would be a classic assembly not found problem.  If it is not there you may have another issue as discussed here.

Check to see if you have any warnings.

image

If you have warning messages like this you have a .NET 4.0 Profile settings error.  This is super easy to fix.  To give you some background on this, there are now more than one installation profile for .NET Runtime Libraries.  One is Full and one is Client.  The idea behind this is that if you are building a program that does not need to reference server side assemblies (System.Web.* as an example) then why install them?  You can now target a Full or Client profile.  The Client profiles will NOT have the server assemblies installed. 

To fix the problem, you need to target the full profile.  Simply Right click on your project and go to Properties.

image

Simply change the Target Framework drop down to .NET Framework 4 instead of .NET Framework 4 Client Profile and your code should compile.

This is really easy, hopefully this helps some newbies.

image

I have a button with the text Add User in the ‘Content’ property.  XAML is cool because you can make the content anything you want, including other controls or groups of controls.

I start by changing my XAML to break out the content property:

1) Remove the Content="Add User" from the Button tag.

2) Break out the content property like this:

<Button Margin="10,5,10,5">
    <Button.Content></Button.Content>
</Button>

3) Add a stack panel inside the Content property and add an image control and a textblock control:

                   <Button Margin="10,5,10,5">
                        <Button.Content>
                            <StackPanel Orientation="Horizontal">
                                <Image Height="16" />
                                <TextBlock>Add User</TextBlock>
                            </StackPanel>
                        </Button.Content>
                    </Button>

4) Now you need to add an image resource to your Silverlight application.

5) Reference the new image in the Source attribute of your Image control inside the Content property of your Button control and you now have an image and text inside your button.

                   <Button Margin="10,5,10,5">
                        <Button.Content>
                            <StackPanel Orientation="Horizontal">
                                <Image Height="16" Source="Images/user_add.png" />
                                <TextBlock Margin="5,0,0,0">Add User</TextBlock>
                            </StackPanel>
                        </Button.Content>
                    </Button>

image

That’s all there is to it.  You can add pretty much anything inside the Content property.

Back on a WPF project for a day and received this while wiring up a ViewModel to the main WPF form. 

image

As with most XAML errors the problem is related to something else deeper in the code.  The inner .. inner exception shows the problem.  An XML data file is being deserialized and the file does not exist. 

So if you get a wierd error like this you probably have some bad code in a constructor for the View’s class or your ViewModel.

Breakpoint the View’s class declaration right before initialize component or at the constructor of your ViewModel class.

image

Had a problem with the XamWebGrid column filters.  They are defaulting to Equals and Not Equals instead of all the other cool filters.  The solution is to explicitly define the filters.  This would require you to put a bunch of xaml in each of your grids.  Here I will show you how to do this using an Application level resource.

In your App.xaml file, define an Application.Resources section if one does not already exist.  Add the column filters XAML and name the filter.


Don’t forget to add the namespace declaration to the start of your App.xaml file:


In your XAML file that defines the XamWebGrid, add the static binding to this filter like this:


Now, in this example, the Quote column will have all the operands as defined in the App.XAML file.  Do the same for your other columns.  You might want to create a template for Strings and one for Integers so that you can have different default filter sets based on the data type.