Chris Fuller  

Silver Sample Architecture Improvements

Posted by Chris Fuller
Wednesday, April 29, 2009

Developing systems is a creative process. Sometimes we build things, recognize that there is a better way and then go back and fix or "refactor" our code.

After working with the same type of architecture as Silver Sample, on a production system, I realized that I had made a mistake in an earlier post. I have since found a better way to use the proxy that is setup when we create a service reference from the Silverlight client.


Originally, I created a static reference to the proxy in App.xaml.cs, (see Figure 1), and used App.Proxy in the application (see Figure 2).


Figure 1 - original App.Proxy property defined in App.xaml.cs





Figure 2 - original source that uses App.Proxy from Page.xaml.cs





Problem #1

This first problem that I noticed was the my CityListCompleted method was getting called multiple times.


After some work, I realized that every time getCityList() was invoked, I was adding a new event handler. So if I invoked this method twice, I'd get 2 event handlers.


This may seem obvious, but I have been working in ASP.NET with a stateless model for a long time and I'm still adjusting to this change of paradigm.


The short-term fix was to move the logic that hooks up the event handler to the constructor for the page - see Figure 3.


Figure 3 - short-term fix




Problem #2
After working in this manner, I realized that my problem was fixed - one "complete" per asynchronous request, but then I ran into another problem...By putting the proxy in App.xaml.cs as a property, I made it global in scope. If I had 2 different user controls or areas in my system that referenced the same method, I would hook up 2 "complete" event handlers and they would both be executed when I made my asynch call, no matter where I executed my asynch call from. This worked in my favor in certain situations, but I found this to be sloppy and difficult to control.



Solution
The solution was to create the endpoint address for the application and the binding for the application in App.xaml.cs, then create an instance of the proxy within the method that made the asynch request, using the application-level endpointaddress and binding.


Figure 4 shows the address and binding properties in App.xaml.cs and Figure 5 shows my new method which creates the proxy, keeping the scope of the proxy at the method level instead of the application level.


Figure 4 - Endpoint and Binding Properties in App.xaml.cs




Note: I still haven't addressed the issue with the hard-coded endpoint address, but I will eventually figure out how to read this value from a .config file, (any suggestions would be welcome).



Figure 5 - New method that uses App.Binding and App.EndpointAddress





The one thing that I was worried about was performance. Would performance suffer if I moved the scope of the proxy from the application level, where it was created once and only once for the entire life of the application, to the method level where it would be created and destroyed each and every time the method was called.


To prove out my new technique, I created Silver Sample #2.


When you click on "Test 1" button, the application-level proxy is used. When you click on the "Test 2", the new method-level proxy is used. When you click on "Test Both", both the old and new versions of the proxy are called.


My testing showed that there really was no difference, from a performance standpoint, between the 2 techniques. Click here. to see for yourself.

<
The new technique gives me centralized control of the endpoint and binding, which is what I wanted, with method-level scoping on the proxy which takes an extra line of code, but is a better technique from an organizational, style and stability perspective.

Rick Sternquist  

NAntBuilder

Posted by Rick Sternquist
Wednesday, April 22, 2009

When it comes to automating a .NET build process, NAnt and NAntContrib are my favorite tools. One major advantage of NAnt is the fact that the build scripts are completely written in XML and can be maintained with your favorite text editor. However, as a Microsoft .NET developer, I must admit I prefer to do my work in an integrated development environment (IDE). That's why I use NAntBuilder. NAntBuilder is a full-featured IDE for NAnt and it's designed to be a powerful script creator, editor, and debugger. If you're new to developing NAnt scripts, I highly recommend giving the product a try. The new version is much improved. You can download a free, trial version here.

Labels:

Rick Sternquist  

Building Silverlight Apps with NAnt

Posted by Rick Sternquist

A Daily Build is one of the true cornerstones of software development. As Steve McConnell wrote in one of my all-time favorite articles, Daily Build and Smoke Test, a Daily Build "minimizes integration risks, reduces the risks of low quality, provides easier defect diagnosis, and improves morale".

On my current Silverlight project at Chicago Technologies, one of my first tasks was to develop an automated, Daily Build process for the team. Over the years, NAnt has become my favorite tool for automating .NET build processes. The following are a couple of considerations when working with NAnt and Silverlight:

  • NAnt - Use NAnt 0.86 Beta 1 Release. I have found this release to be stable and it supports both .NET Framework 3.5 and Silverlight 2.0 targets

  • NAntContrib - Use NAntContrib 0.85. NAntContrib provides tasks and tools that aren't available in NAnt. As far as I'm concerned, NAntContrib is a must for two reasons: the MSBuild task and the SCM-related tasks for SourceSafe, StarTeam, and Subversion.

  • MSBuild - Utililze the NAntContrib task, MSBuild, for the actual compilation of the application. More on this later.

An important note regarding the integration between Subversion and NAntContrib. On our project, we're using Subversion and the TortoiseSVN client. NAntContrib utilizes "svn.exe", the command line utility, for its SVN-related tasks. However, the installation of TortoiseSVN does not contain "svn.exe". I had to install an additional Subversion client that utilized "svn.exe" Without the command-line utility installed, your SVN-related NAntContrib tasks will not work. I used CollabNet Subversion Command-Line Client v1.6.1 (for Windows).

I hope this information helps you. My next post will contain a sample NAnt build script for building Silverlight applications.

Labels: , , ,

Chris Fuller  

Silverlight Deployment

Posted by Chris Fuller
Tuesday, April 21, 2009

The first item I wanted to address before I deployed was that I didn't like the SilverSampleTestPage.aspx that was generated for me.

I moved the XAML from SilverSampleTestPage.aspx to Default.aspx and deleted
SilverSampleTestPage.aspx and SilverSampleTestPage.html from my solution. I also made a few minor modifications to the XAML. Figure 1 shows the XAML for the Default.aspx page that hosts the SilverSample client application:

Figure 1 - Default.aspx


The second problem that I ran into was the fact that I was using the default binding and address for my service. In my getCityList() method, (see previous post), I had created an instance of my the proxy like this:

SilverServiceClient proxy = new SilverServiceClient();

The problem with this approach is that when I went to deploy, the address being used was the address of my local host from my service reference definition, (see Figure 2 - Service Reference Definition), and not the address of my QA server.

Figure 2 - Service Reference Definition


To rectify the situation, I added a using statement and static property to App.xaml.cs:

Figure 3 - Changes to App.xaml.cs
using System.ServiceModel;
using System.ServiceModel.Channels;
using SilverSample.SilverServiceProxy;
...


Ideally, I would be pulling the address from a .config file, but my understanding is that the Silverlight client doesn't have a .config file concept, (please correct me if I'm wrong and/or if there's a better way to do this). Until I figure out a better way, I'm switching back and forth between the server address and the local address depending on whether I'm working locally or deploying. Not ideal, but it works.

The local address is pulled directly from my local instance of Cassini - see Figure 4. This works because I'm hosting the WCF service within the web project.

Figure 4 - Cassini on client


NOTE: Sometimes over the course of working in Visual Studio, the port # on Cassini changes. When it does, I have to modify the local address for things to work.

OK, so I am ready to deploy. I comment out the local endpoint address and uncomment the address on the server I am deploying to. I then right-click on the SilverSample.Web project and choose "Publish". See Figure 5.



I copied the published files my solution up to my directory on the QA server.

Note: My QA Server is a Windows Server 2003 box running IIS 6.

Ready to go - right? Not so fast...the Silver Gods made me pay some dues first. My next post will explain the issues that I ran into and what I did to work through them.

Check it out - not fancy, but it works: http://www.silversample.com/sample1

Chris Fuller  

Silverlight Deployment Issues

Posted by Chris Fuller

My sample application is built in Silverlight and uses a WCF service, hosted in the web application for data access.

My first Silverlight deployment was not very smooth. I had several issues when I went to deploy. The good news is that I was able to work through all of them. Hopefully this post will save others some time.

The first problem I had was a 404 error when I went to http://www.silversample.com/silverservice.svc - see Figure 1.

Figure 1 - 404 Error SilverSample.svc


After some digging, I found that our server is running IIS 6.0 and the .svc extension was not registered. I registered .svc with the following steps:
1. Right-click on the SilverSample site in IIS and choose "Properties"
2. Go to the "Home Directory" tab
3. Click the "Configuration" button
4. Click "Add"
5. In the Executable box, enter: c:\windows\microsoft.net\framework\v2.0.50727\aspnet_isapi.dll - see Figure 2.

Figure 6 - Application Configuration in IIS 6


This fixed my issue. I could now browse to http://www.silversample.com/silverservice.svc - see Figure 3.

Figure 3 - SilverService.svc


To test the service, I went back to Visual Studio on my local machine, deleted my local service reference and added a service reference that pointed to silverservice.svc on my QA server. See Figure 4.

Figure 4 - SilverServiceProxy Pointing to QA Server


My application ran, but when I clicked the "Test" button which executes the service, I got a strange error: "CommunicationException was unhandled by user code".
See Figure 5.

Figure 5 - CommunicationException error


After some digging, I found
Mark's Blog
which pointed me in the correct direction.

I created a new file called clientaccesspolicy.xml and put it in the root of SilverSample site. The clientaccesspolicy.xml file looks like this:















This fixed my issue and I was able to run locally hitting the service.

Note: If you are using a virtual directory under a web site in IIS, the clientaccesspolicy.xml file needs to be put at the root of the site. This is where IIS looks for it. I found this by running Fiddler when working on another project that was using a virtual directory.

Note: This is probably not the configuration you want for a production environment. Below is the configuration I settled on. It allows my application to use the service while preventing public access to the service.















Ok one step closer, one more issue to go. Here is the next error I ran into when I tried to run the SilverSample application from the web server:



This was my 2nd IIS 6 issues. This time I had to add the .xap extension as a Mime Type to my web site in IIS. I right-clicked on the SilverSample site in IIS, went to Properties, then to the HTTP Headers tab and clicked the "MIME Types" button.
Figure 7 shows the MIME Type settings for the .xap file:

Figure 7 - MIME Type Settings for .xap File


That was it! Now everything is worky, worky and I am through my first deployment. Granted this is a simple, make-believe application, but I've worked through a lot of issues that I will know how to deal with when I go to deploy my production application.

Rick Sternquist  

Silverlight Error Message - AG_E_PARSER_BAD_PROPERTY_VALUE

Posted by Rick Sternquist
Thursday, April 16, 2009

When I was getting started with Silverlight 2 development, I ran into the following exception several times:


System.Windows.Markup.XamlParseException occurred
Message="AG_E_PARSER_BAD_PROPERTY_VALUE [Line: 29 Position: 27]"


This exception is typically raised when an event is defined in your XAML, but not in your code-behind. If you're experiencing this exception, review your XAML and the associated events in your code-behind. Make sure they match up.

Labels: ,

Rick Sternquist  

SQL Server Business Intelligence Development Studio - Missing DEVENV.EXE

Posted by Rick Sternquist
Wednesday, April 15, 2009

As part of a recent project, I've been working with Microsoft SQL Server 2005's Business Intelligence tools such as SSAS (SQL Server Analysis Services), SSIS (SQL Server Integration Services), and SQL Server Business Intelligence Development Studio.

Just a few days before the project started, I had uninstalled Visual Studio 2005 to make a little room on my harddrive for Visual Studio 2008 SP1 and Silverlight 2. Forgetting that I had uninstalled Visual Studio 2005, I launched SQL Server Business Intelligence Development Studio and received the following message: "devenv.exe is missing". Of course it is! I just uninstalled it! I spent some time googling the problem and here's what worked for me:

  1. Using the SQL Server 2005 installation disc, run the following command: \Tools\Setup\vs_setup.exe. This will reinstall the Visual Studio 2005 IDE.
  2. Run the following command from \Tools directory: start /wait setup.exe /qb REINSTALL=SQL_WarehouseDevWorkbench REINSTALLMODE=OMUS.

This combination worked perfectly. My SQL Server 2005 Business Intelligence Development Studio was back up and running.

Labels: ,

Chris Fuller  

Silverlight Sample Architecture Using WCF Service

Posted by Chris Fuller
Sunday, April 12, 2009

For better or worse, I'm the first in my company to start using Silverlight. I've been working with Silverlight for a little over a month now and I love it. It has it's drawbacks and shortcomings, but overall, it's a great tool for building web–based applications that run through a browser without an install.


I've learned a lot since I started using the tool, and I plant write a series of articles to share some of the lessons. Before I get into that, I want to share the architecture that I am using, for 3 reasons:


  • 1. I hope this helps somebody else get going


  • 2. If there are improvements, suggestions, etc. that can be made to this architecture, I'd like to hear them


  • 3. My future articles will reference back to this one – some of the things I've overcome only make sense if you know how things are setup


My Silverlight application has a very simple architecture. I use a single WCF service, hosted in the "ASP.NET Web Application Project" that Visual Studio 2008 created for me when I setup my new application. Figure 1 shows the option I chose to setup my application when I first created my, "Silver Sample" Silverlight application.


Figure 1 – Silverlight Application Setup





After creating the SilverSample project using Visual Studio 2008, I went to Page.xaml and added a TextBlock within the default Grid that was provided. See Figure 2 for what my initial application architecture looks like and the "Hello World" XAML I added.


Figure 2 – Silver Sample Initial Architecture with "Hello World" Textblock





That was enough to get me started, so I compiled and ran the application. Visual Studio was kind enough to ask me if I wanted to debug this application if I ever run into problems. This is a nice feature, so I chose to "Modify the Web.config file to enable debugging" and clicked "Ok" – see Figure 3.


Figure 3 – Debugging Question from Visual Studio




My first Silverlight application came up successfully in IE – see Figure 4.


Figure 4 – Hello World




Hello World was working. Next I wanted to test getting data to the client application, (SilverSample) from the web server application, (SilverSample.Web).




I stopped the SilverSample application and right–clicked on the SilverSample.Web project in the Solution Explorer, choosing "Add New Item". In the "Add New Item" window, I chose, "WCF Service", named my service "SilverService.svc" and clicked the "Add" button – see Figure 5.



Figure 5 – Setting up my WCF Service within the ASP.NET Web Application Project





Visual Studio setup 3 files for me; ISilverService.cs, SilverService.svc.cs and SilverService.svc. See Figure 6.



Notice that SilverlightService inherits from its interface, ISilverService.


Figure 6 – Silver Sample with WCF Service added to the Web Application





I like to work with lists, so to test my new SilverSample application and its interaction with the WCF service, I created a list of strings and setup a method in SilverService.cs to return those strings. I also deleted the default, "DoWork()" method because I didn't need it. See Figure 7.




Figure 7 – CityList WCF Service




After creating my list I had to modify the ISilverService interface to get rid of the "DoWork()" method and include an interface for "CityList" – see Figure 8.
Figure 8 – City List Class Interface and Contract for WCF Service




The default binding entries which Visual Studio automatically configures for you when you add the WCF service to the web application are wsHttpBinding. Currently, Silverlight only supports basicHttpBinding. Figure 9 shows the generated values that will need to be changed.


Figure 9 – Generated Web.Config




Because Silverlight only supports basicHttpBinding, you will need to change the binding setting that was automatically generated for you when you added the service from wsHttpBinding to basicHttpBinding. See Figure 10.


Figure 10 – Change to Web.Config




I successfully built my application, with my new service by hitting F6 and noting that it said "Build Successful" in the lower–left–hand corner of the Visual Studio window.


Note: It's important to build the web project before attempting to use the web service from the Silverlight client application. More on this in a future post.




With my first service built, I went back to the client project, SilverSample, and add a Service Reference by right–clicking on the SilverSample project and choosing "Add Service Reference".


I clicked the "Discover" button and SilverSample found SilverService.svc for me. Next I verified the service by clicking the (+) next to "SilverService.cs" in the "Services" box. This showed the Interface definition. I also named my reference to the service, "SilverServiceProxy". See Figure 11.



Figure 11 – Add Service Reference




My service returns a Generic List, so before I clicked OK, I clicked "Advanced" which brought me to the "Service Reference Settings" screen where I changed the "Collection Type" in the "Data Type" section from "System.Collections.ObjectModel.ObservableCollection" to "System.Collections.Generic.List". See Figure 13.


I then clicked "OK" to exit out of the "Service Reference Settings" and "OK" to exit out of "Add Service Reference".


Figure 12 – Service Reference Settings




With my service configured on the client and the server, I wrote a little XAML in Page.xaml to help organize my output. See Figure 13.


Figure 13 – Page.xaml




I then went back to Page.xaml.cs and wrote code to consume the service asynchronously.



Next, I added a using statement at the top which referenced the service reference I just added; SilverSample.SilverServiceProxy. This makes the WCF service call a little less verbose.


Next I wrote a method called "getCityList" which makes the call into the WCF service asynchronously and a method called "getCityListCompleted" which is called when the list of cities comes back from the service. This method adds some rows and text blocks to the grid on the page to display the results.


See Figure 14 for these methods.


Figure 14 – Page.xaml.cs Source




Last, I ran the application and clicked the "Test" button. See Figure 15.


Figure 15 – Silver Sample Application




Summary
The Silver Sample application is simple, but it sets up a basic architecture that we can build from and proves out how to do the following:

  • 1. How to create a WCF service, hosted within the web project generated by Visual Studio when we created the Silverlight application.


  • 2. How to consume the WCF service, and the need to change the configuration setting in web.config to basicHttpBinding.


  • 3. How to use a Generic List in the WCF service.


  • 4. How to dynamically add controls to a Grid on the front–end.

Chris Fuller  

The Ugly And Dangerous Prejudice Against Stupidity

Posted by Chris Fuller
Tuesday, April 7, 2009

Bob Evans discussed a prejudice against outsourcing in the March 25th issue of Information Week.

Click here to read article

Here is my response:

Mr. Evans:

I think you named your March 25th article, "The Ugly And Dangerous Prejudice Against Outsourcing", incorrectly. You should have called it, "The Ugly And Dangerous Prejudice Against Stupidity". You made some good points, but I don't think there really is unfounded prejudice against outsourcing.

American corporations have made some really poor outsourcing decisions and are just now starting to realize the real cost to their organizations. I've had horrific customer service experiences with Dell and American Express lately, both of which have outsourced at least part of their customer service. I've spent hours and hours on the phone with both of these companies trying to straighten out what should be relatively simple customer service issues. What saves them money costs the consumer time and that is not good business.

We should outsource if it makes sense, but we should also be very careful about outsourcing areas of our business, especially if they are customer-facing. What good is saving a few bucks if it costs you the loyalty of your customers? We as Americans don't need to be protectionists, we just need to make better decisions.

-Chris Fuller
Chicago Technologies
www.chitech.net

Chris Fuller  

Getting Started with Silverlight 2

Posted by Chris Fuller
Thursday, April 2, 2009

I have been working with Microsoft tools most of my career with Chicago Technologies, from VB4 to VB6 to Classic ASP to ASP.NET, but I just recently started working with Silverlight 2. So far I love it. Specifically:

1. I love XAML ‒ it is the markup language I always wanted.
  • It is relatively easy to arrange controls on a page.

  • When I layout controls in XAML, things work like I expect without worrying about what browser (or version of the browser) I‘m running in.

  • I‘m tired of working with HTML and CSS and spending more time trying to get layouts right than developing my application.



2. Silverlight is easy to work with.

  • Install Tools for Visual Studio 2008

  • Silverlight client can maintain state. Wow is this nice for us developers!. And no more post‒backs ‒ wow this is nice for users!

  • Silverlight is .NET, so a lot of the good things I‘ve learned with ASP.NET still apply and it integrates very nicely with WCF.


I‘m on my first Silverlight project, so I do not claim to be an expert, (yet), but I love what I‘ve done so far and I‘m planning on being an expert by the time this project goes to production. In the meantime, here are a couple links I found extremely helpful in getting me going:

Scott Gu‘s End to End Tutorial
By Scott Gu

This is a great place to start learning Silverlight. Scott does a great job explaining practical uses for Silverlight and you will feel confident enough in your understanding after completing this tutorial to start programming in Silverlight.


Navigating and passing values between XAML Pages in Silverlight 2
By Nipun Tomar‘s

This article shows a nice technique for navigating between .xaml pages. I found this to be helpful when I started building a real application with more than one page.