OdeToCode IC Logo

Configuration Free JSON with WCF and AJAX in Visual Studio 2008 Beta 2

Tuesday, July 31, 2007 by scott

With all the out-of-band technology releases we've had (ASP.NET AJAX, .NET 3.0), it's nice to reach a point where we can bring them all together.

As an example...

Create a new web site in Visual Studio 2008. This will have to be a website under IIS, unfortunately, for reasons I'll point out later. Once the web site is up, add a new item – a WCF service. The service contract can look like the following:

[ServiceContract(Namespace="https://odetocode.com/ws",
                 Name=
"ServerProcessInfo")]
public interface IServerProcessInfo
{
   [
OperationContract]
    
IEnumerable<ProcessInfo> GetRunningProcesses();
}

The data contract can look like so:

[DataContract]
public class ProcessInfo
{
    [
DataMember]
    
public string Name { get; set; }

    [
DataMember]
    
public long WorkingSet { get; set; }
}

Finally, the LINQish implementation:

public class ServerProcessInfo : IServerProcessInfo
{
    
public IEnumerable<ProcessInfo> GetRunningProcesses()
    {
        
return
              (
                
from p in Process.GetProcesses()
                
orderby p.WorkingSet64 descending
                 select new ProcessInfo
                 {
                     Name = p.ProcessName,
                     WorkingSet = p.WorkingSet64
                 }
              ).Take(10);
    }
}

We can entirely remove any WCF <system.serviceModel> configuration from web.config. Instead of all the XML configuration goo, we just need a Factory attribute in our .svc file:

<%@ ServiceHost Language="C#" Debug="true" Service="ServerProcessInfo"
  
...
  Factory
="System.ServiceModel.Activation.WebScriptServiceHostFactory" %>

What magic does this factory give us? Well, we can add a ServiceReference via a ScriptManager (it's nice that AJAX extensions are in the toolbox by default), and write some script:

<asp:ScriptManager ID="ScriptManager1" runat="server">
  <Services>
    <asp:ServiceReference Path="~/ServerProcessInfo.svc" />
  </Services>
</
asp:ScriptManager>
        
<script type="text/javascript">

var
ws = new odetocode.com.ws.ServerProcessInfo();
ws.GetRunningProcesses(getRunningProcessesComplete);

function getRunningProcessesComplete(result)
{      
    
for(var i = 0; i < result.length; i++)
    {
         document.write(result[i].Name,
" ", result[i].WorkingSet);
         document.write(
"<br />");

    }    
}

Voila! Zero configuration and we have JSON on the wire!

HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
Server: Microsoft-IIS/7.0
X-Powered-By: ASP.NET
Date: Tue, 31 Jul 2007 03:08:10 GMT
Content-Length: 662

{"d":[{"__type":"ProcessInfo:#","Name":"devenv","WorkingSet":51011584},
{"__type":"ProcessInfo:#","Name":"w3wp","WorkingSet":44748800},
{"__type":"ProcessInfo:#","Name":"Fiddler","WorkingSet":34213888},
...
}

Note: there is a problem in Beta 2 that prevents this magic from working with WebDev.exe. The error you'll see with WebDev (aka Cassini) is:

"IIS specified authentication schemes 'Ntlm, 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."

Unfortunately, twiddling with the NTLM checkbox for WebDev doesn't help. Thus, the current need for IIS.

Some Cool Software You Might Not Know About

Thursday, July 26, 2007 by scott

Sahil's post on "Things I can't live without" got me thinking about some software I use that might not be so well known. XM Radio Studio

XaMp Studio plays XM Radio from a desktop application. Looks like Winamp and offers more features than the XM web interface. There is a toast notification to tell you when your favorite artist or tune is streaming. Note: don't download the "desktop" edition, as it seems incompatible with Vista and Windows Media Player 11.

DynDNS Updater coupled with the DynDNS service can give any computer a name – even if your ISP hands out dynamic IP addresses. The Updater can run as a Windows service to keep addresses in synch.

FoxIt Reader is a small, fast PDF reader. Scott Hanselman first mentioned Foxit a couple years ago, and the feature list has grown since that time. The only downside is that Foxit does not seem to decrypt password protected PDF files, so no e-book reading with Foxit.  

Robocopy now comes standard in Windows Vista. It's the tool I use for large file operations, particularly when moving bits over the network. Robocopy easily beats copying files using Windows Explorer, after all, the "robo" is short for robust.

There is only one weakness with robocopy. Try copying an Outlook PST file when Outlook is running:


PS> robocopy C:\Users\bitmask\appdata\Local\Microsoft\Outlook d:\temp outlook.pst

-------------------------------------------------------------------------------
   ROBOCOPY     ::     Robust File Copy for Windows
-------------------------------------------------------------------------------

  Started : Tue Jul 24 12:33:20 2007

   Source : C:\Users\bitmask\appdata\Local\Microsoft\Outlook\
     Dest : d:\temp\

    Files : outlook.pst

  Options : /COPY:DAT /R:1000000 /W:30

------------------------------------------------------------------------------

                           1    C:\Users\bitmask\appdata\Local\Microsoft\Outlook\
  0.0%      New File             856.3 m        Outlook.pst
2007/07/24 12:33:20 ERROR 33 (0x00000021) Copying File C:\Users\bitmask\appdata\Local\Microsoft\Outlook\Outlook.pst
The process cannot access the file because another process has locked a portion of the file.
Waiting 30 seconds...

Which brings me to my "last but not least" entry: Hobocopy.

PS> .\hobocopy C:\users\bitmask\appdata\local\microsoft\outlook\ d:\temp outlook.pst
HoboCopy (c) 2006 Wangdera Corporation. hobocopy @ wangdera.com

Starting a full copy from C:\users\bitmask\appdata\local\microsoft\outlook\ to d:\temp
Copied directory
Backup successfully completed.
Backup started at 2007-07-22 12:46:25, completed at 2007-07-22 12:47:48.
1 files (856.39 MB, 1 directories) copied, 7 files skipped

Hobocopy is Craig Andera's tool that uses the Volume Shadow Service to copy locked files. Pure goodness.

ASP.NET and Separating Concerns

Wednesday, July 25, 2007 by scott

Ayende had a recent post with the following quote from Nicholas Piasecki:

To me, this discussion all boils down to one thing: the foreach loop. Let's say you want to display a table of sales reports, but after every tenth row, you want to print out an extra row that displays a running total of sales to that point. And you want negative numbers to appear in red, positive numbers to appear in green, and zeros to appear in black. In MonoRail, this is easy; with WebForm's declarative syntax, just shoot yourself in the face right now. Most solutions I've seen end up doing lots of manipulation in the code-behind and then slamming it into a Literal or something, which to me defeats the purpose of the code separation.

Ayende says this is the essence of why he dislikes WebForms. In the comments, someone proposed a rails solution ...

#set ($i = 0)
#set ($running_total = 0)
#foreach ($report in $reports)
#each
    <tr>
        <td>$report.name</td>
        #if ($report.ammount > 0)
            
<div class="green">
        #elseif ($report.ammount < 0)
            
<div class="red">
        #else
            
<div class="black">
        #end
        $report.ammount
</td>
    </tr>

    #set ($running_total = $running_total + $report.ammount)
    #set ($i = $i + 1)
    #between
    #if (($i % 10 ) == 1)
    
<tr class="Running Total">
        <td>$running_total</td>
    </tr>
    #end
#end

... which received praise for elegance. I'm thinking if you really want to intermingle code and markup, than open up an .aspx page and have at it:

<%@ Page Language="C#" %>
<%  
    SalesReport report = new SomeApplicationService().GetSalesReport();
    int rowCount = 0;
    
int runningTotal = 0;
%>
<table>
  <% foreach (Salesperson p in report.SalesPeople) {
     rowCount++;
     runningTotal += p.TotalSales;
  %>
  
<tr>
    <td><%= p.Name %></td>
    
<td>
      <div class="<%= p.TotalSales < 0 ? "red" : p.TotalSales > 0 ? "green" : "black" %>">
        <%= p.TotalSales.ToString("c")  %>
      
</div>
    </td>        
  
</tr>
        
  <%
if(rowCount % 10 == 0) { %>
  
<tr>
    <td>SubTotal:</td>
    <td><%= runningTotal.ToString("c") %></td>
  </tr>
  <% } // end if %>  
<% }
// end foreach %>
</table>

Why throw out the baby with the bathwater?

Rockville User Group

Tuesday, July 24, 2007 by scott

RockNUG is the newest .NET user group in the vast suburbia of Washington D.C. Their next meeting is on August 8 at Montgomery College, and I'll be there to talk about ASP.NET AJAX. I have one WF book and one Pluralsight T-shirt to give away, too.

Come for the free pizza, and stay for the asynchronous fun!

Unit Testing with Visual Studio 2008

Monday, July 23, 2007 by scott

Unit testing features will now be available in the Professional version of Visual Studio 2008.

Unit testing has been to Visual Studio what Barry Bonds has been baseball – a center of controversy. First there was the Peter Provost petition to include unit testing features in all version of VS. Then there was the highly criticized TDD guidance accompanying the feature. Next came some performance issues and pain while using the shipping version, and most recently, the TestDriven.NET hullaballoo added an emotional charge to the air.

Putting all this behind us - what's new in 2008? I've been working with the latest bits, and I can say:

  1. Performance has improved dramatically.
  2. The context-menu command "Run Tests" is new (and context sensitive).
  3. Keyboard shortcuts take away the pain of the VS2005 test runner (Ctrl+R, A to run all tests in a solution, Ctrl+R, T to run tests in the current context).

Moving the unit-testing features into the Pro edition is a great move by Microsoft. I hope the feature gains traction and brings awareness of unit testing into the mainstream (although I think we are already close, aren't we?).

Related Links

Guidelines for Test-Driven Development by Jeff Palermo
Rules to Better Unit Tests by Adam Cogan.

Automatic Properties

Wednesday, July 18, 2007 by scott

I wrote my first class with automatic properties in Orcas today...

[DataContract(Name="FoodFact")]
public class FoodFactMessage
{
    [
DataMember]
    
public int ID { get; set; }
    
    [
DataMember]
    
public string Name { get; set; }

    [
DataMember]
    
public int Calories { get; set; }
}

... then I found myself staring at the screen.

It's an interface!
No,it's a class!
Wait, it is a class!

I'd say the syntax is still growing on me.

I'm sure some people will say – why use properties at all? If you don't need special code in the get and set methods – why not just use a public field?

The quick answer is: reflection. There are many forms of magic that will only occur if you expose state using public properties.

Related Links

ASP.NET and ASP.NET AJAX Double Feature

Tuesday, July 17, 2007 by scott

ASP.NET and AJAX Double Feature Class Come join Fritz Onion and myself at a Pluralsight double feature in southern California. Starting October on 22nd, we'll cover everything from JSON spitting web services to the Sharepointy magic of ASP.NET 2.0 web parts.

It's more than a class … it's an experience (and fun, too)!