Hanselminutes Podcast 264 - This is not your father's WCF - All about the WebAPI with Glenn Block

imageGlenn Block is with Scott in The Netherlands and tries to get Scott up to speed on what's new in the WCF Web Api. Scott thinks WCF is scary and heavyweight. How does WCF fit into a world of Web 2.0 lightweight APIs? What's the WCF WebAPI and how does compare to services in ASP.NET MVC?

Download: MP3 Full Show

Links from the Show

NOTE: If you want to download our complete archives as a feed - that's all 264 shows, subscribe to the Complete MP3 Feed here.

Also, please do take a moment and review the show on iTunes.

Subscribe: Subscribe to Hanselminutes or Subscribe to my Podcast in iTunes or Zune

Do also remember the complete archives are always up and they have PDF Transcripts, a little known feature that show up a few weeks after each show.

Telerik is our sponsor for this show.

Building quality software is never easy. It requires skills and imagination. We cannot promise to improve your skills, but when it comes to User Interface and developer tools, we can provide the building blocks to take your application a step closer to your imagination. Explore the leading UI suites for ASP.NETAJAX,MVC,Silverlight, Windows Forms and WPF. Enjoy developer tools like .NET Reporting,ORM,Automated Testing Tools, Agile Project Management Tools, and Content Management Solution. And now you can increase your productivity with JustCode, Telerik’s new productivity tool for code analysis and refactoring. Visitwww.telerik.com.

As I've said before this show comes to you with the audio expertise and stewardship of Carl Franklin. The name comes from Travis Illig, but the goal of the show is simple. Avoid wasting the listener's time. (and make the commute less boring)

Enjoy. Who knows what'll happen in the next show?

Hanselminutes Podcast 236 - Misunderstanding REST with Mike Amundsen

imageWeb Services with SOAP are a pretty well understood thing, but what's all this appeal about REST? Is REST just CRUD (Create Read Update Delete) for the Web? Is it a pattern, a style or dogma? Recognized REST expert Mike Amundsen sets Scott straight.

NOTE: If you want to download our complete archives as a feed - that's all 236 shows, subscribe to the Complete MP3 Feed here.

Also, please do take a moment and review the show on iTunes.

Subscribe: Subscribe to Hanselminutes Subscribe to my Podcast in iTunes

Download: MP3 Full Show

Do also remember the complete archives are always up and they have PDF Transcripts, a little known feature that show up a few weeks after each show.

Telerik is our sponsor for this show.

Building quality software is never easy. It requires skills and imagination. We cannot promise to improve your skills, but when it comes to User Interface and developer tools, we can provide the building blocks to take your application a step closer to your imagination. Explore the leading UI suites for ASP.NET AJAX,MVC,Silverlight,Windows Forms and WPF. Enjoy developer tools like .NET Reporting, ORM, Automated Testing Tools, Agile Project Management Tools, and Content Management Solution. And now you can increase your productivity with JustCode, Telerik’s new productivity tool for code analysis and refactoring. Visit www.telerik.com.

As I've said before this show comes to you with the audio expertise and stewardship of Carl Franklin. The name comes from Travis Illig, but the goal of the show is simple. Avoid wasting the listener's time. (and make the commute less boring)

Enjoy. Who knows what'll happen in the next show?

The Weekly Source Code 56 - Visual Studio 2010 and .NET Framework 4 Training Kit - Code Contracts, Parallel Framework and COM Interop

Do you like a big pile of source code? Well, there is an imperial buttload of source in the Visual Studio 2010 and .NET Framework 4 Training Kit. It's actually a 178 meg download, which is insane. Perhaps start your download now and get it in the morning when you get up. It's extremely well put together and I say Kudos to the folks that did it. They are better people than I.

I like to explore it while watching TV myself and found myself looking through tonight. I checked my blog and while I thought I'd shared this with you before, Dear Reader, I hadn't. My bad, because it's pure gold. With C# and VB, natch.

Here's an outline of what's inside. I've heard of folks setting up lunch-time study groups and going through each section.

C# 4 Visual Basic 10 
F# Parallel Extensions
Windows Communication Foundation Windows Workflow
Windows Presentation Foundation ASP.NET 4
Windows 7 Entity Framework
ADO.NET Data Services (OData) Managed Extensibility Framework
Visual Studio Team System RIA Services
Office Development  

I love using this kit in my talks, and used it a lot in my Lap Around .NET 4 talk.

There's Labs, Presentations, Demos, Labs and links to online Videos. It'll walk you step by step through loads of content and is a great starter if you're getting into what's new in .NET 4.

Here's a few of my favorite bits, and they aren't the parts you hear the marketing folks gabbing about.

Code Contracts

Remember the old coding adage to "Assert Your Expectations?" Well, sometimes Debug.Assert is either inappropriate or cumbersome and what you really need is a method contract. Methods have names and parameters, and those are contracts. Now they can have conditions like "don't even bother calling this method unless userId is greater than or equal to 0 and make sure the result isn't null!

Code Contracts continues to be revised, with a new version out just last month for both 2008 and 2010. The core types that you need are included in mscorlib with .NET 4.0, but you do need to download the tools to see them inside Visual Studio. If you have VS Pro, you'll get runtime checking and VS Ultimate gets that plus static checking. If I have static checking and the tools I'll see a nice new tab in Project Properties:

Code Contracts Properties Tab in Visual Studio

I can even get Blue Squigglies for Contract Violations as seen below.

A blue squigglie showing that a contract isn't satisfied

As a nice coincidence, you can go and download Chapter 15 of Jon Skeet's C# in Depth for free which happens to be on Code Contracts.

Here's a basic idea of what it looks like. If you have static analysis, you'll get squiggles on the lines I've highlighted as they are points where the Contract isn't being fulfilled. Otherwise you'll get a runtime ContractException. Code Contracts are a great tool when used in conjunction with Test Driven Development.

using System;
using System.Collections.Generic;
using System.Text;
using System.Diagnostics.Contracts;

namespace ContractsDemo
{
[ContractVerification(true)]
class Program
{
static void Main(string[] args)
{
var password = GetPassword(-1);
Console.WriteLine(password.Length);
Console.ReadKey();
}

#region Header
/// <param name="userId">Should be greater than 0</param>
/// <returns>non-null string</returns>
#endregion
static string GetPassword(int userId)
{
Contract.Requires(userId >= 0, "UserId must be");
Contract.Ensures(Contract.Result<string>() != null);

if (userId == 0)
{
// Made some code to log behavior

// User doesn't exist
return null;
}
else if (userId > 0)
{
return "Password";
}

return null;
}
}
}

COM Interop sucks WAY less in .NET 4

I did a lot of COM Interop back in the day and it sucked. It wasn't fun and you always felt when you were leaving managed code and entering COM. You'd have to use Primary Interop Assemblies or PIAs and they were, well, PIAs. I talked about this a little bit last year in Beta 1, but it changed and got simpler in .NET 4 release.

Here's a nice little sample I use from the kit that gets the Processes on your system and then makes a list with LINQ of the big ones, makes a chart in Excel, then pastes the chart into Word.

If you've used Office Automation from managed code before, notice that you can say Range[] now, and not get_range(). You can call COM methods like ChartWizard with named parameters, and without including Type.Missing fifteen times. As an aside, notice also the default parameter value on the method.

static void GenerateChart(bool copyToWord = false)
{
var excel = new Excel.Application();
excel.Visible = true;
excel.Workbooks.Add();

excel.Range["A1"].Value2 = "Process Name";
excel.Range["B1"].Value2 = "Memory Usage";

var processes = Process.GetProcesses()
.OrderByDescending(p => p.WorkingSet64)
.Take(10);
int i = 2;
foreach (var p in processes)
{
excel.Range["A" + i].Value2 = p.ProcessName;
excel.Range["B" + i].Value2 = p.WorkingSet64;
i++;
}

Excel.Range range = excel.Range["A1"];
Excel.Chart chart = (Excel.Chart)excel.ActiveWorkbook.Charts.Add(
After: excel.ActiveSheet);

chart.ChartWizard(Source: range.CurrentRegion,
Title: "Memory Usage in " + Environment.MachineName);

chart.ChartStyle = 45;
chart.CopyPicture(Excel.XlPictureAppearance.xlScreen,
Excel.XlCopyPictureFormat.xlBitmap,
Excel.XlPictureAppearance.xlScreen);

if (copyToWord)
{
var word = new Word.Application();
word.Visible = true;
word.Documents.Add();

word.Selection.Paste();
}
}

You can also embed your PIAs in your assemblies rather than carrying them around and the runtime will use Type Equivalence to figure out that your embedded types are the same types it needs and it'll just work. One less thing to deploy.

Parallel Extensions

The #1 reason, IMHO, to look at .NET 4 is the parallelism. I say this not as a Microsoft Shill, but rather as a dude who owns a 6-core (12 with hyper-threading) processor. My most favorite app in the Training Kit is ContosoAutomotive. It's a little WPF app that loads a few hundred thousand cars into a grid. There's an interface, ICarQuery, that a bunch of plugins implement, and the app foreach's over the CarQueries.

This snippet here uses the new System.Threading.Task stuff and makes a background task. That's all one line there, from StartNew() all the way to the bottom. It says, "do this chunk in the background." and it's a wonderfully natural and fluent interface. It also keeps your UI thread painting so your app doesn't freeze up with that "curtain of not responding" that one sees all the time.

private void RunQueries()
{
this.DisableSearch();
Task.Factory.StartNew(() =>
{
this.BeginTiming();
foreach (var query in this.CarQueries)
{
if (this.searchOperation.Token.IsCancellationRequested)
{
return;
}

query.Run(this.cars, true);
};
this.EndSequentialTiming();
}, this.searchOperation.Token).ContinueWith(_ => this.EnableSearch());
}

StartNew() also has a cancellation token that we check, in case someone clicked Cancel midway through, and there's a ContinueWith at the end that re-enables or disabled Search button.

Here's my system with the queries running. This is all in memory, generating and querying random cars.12% CPU across 12 processors single threaded

And the app says it took 2.3 seconds. OK, what if I do this in parallel, using all the processors?

2.389 seconds serially

Here's the changed code. Now we have a Parallel.ForEach instead. Mostly looks the same.

private void RunQueriesInParallel()
{
this.DisableSearch();
Task.Factory.StartNew(() =>
{
try
{
this.BeginTiming();
var options = new ParallelOptions() { CancellationToken = this.searchOperation.Token };
Parallel.ForEach(this.CarQueries, options, (query) =>
{
query.Run(this.cars, true);
});
this.EndParallelTiming();
}
catch (OperationCanceledException) { /* Do nothing as we cancelled it */ }
}, this.searchOperation.Token).ContinueWith(_ => this.EnableSearch());
}

This code says "go do this in a background thread, and while you're there, parallelize this as you like." This loop is "embarrassingly parallel." It's a big for loop over 2 million cars in memory. No reason it can't be broken apart and made faster.

Here's the deal, though. It was SO fast, that Task Manager didn't update fast enough to show the work. The work was too easy. You can see it used more CPU and that there was a spike of load across 10 of the 12, but the work wasn't enough to peg the processors.

19% load across 12 processors 

Did it even make a difference? Seems it was 5x faster and went from 2.389s to 0.4699 seconds. That's embarrassingly parallel. The team likes to call that "delightfully parallel" but I prefer "you're-an-idiot-for-not-doing-this-in-parallel parallel," but that was rejected.

0.4699 seconds when run in parallel. A 5x speedup.

Let's try something harder. How about a large analysis of Baby Names. How many Roberts born in the state of Washington over a 40 year period from a 500MB database?

Here's the normal single-threaded foreach version in Task Manager:

One processor chilling.

Here's the parallel version using 96% CPU.

6 processes working hard!

And here's the timing. Looks like the difference between 20 seconds and under 4 seconds.

PLINQ Demo

You can try this yourself. Notice the processor slider bar there at the bottom.

ProcessorsToUse.Minimum = 1;
ProcessorsToUse.Maximum = Environment.ProcessorCount;
ProcessorsToUse.Value = Environment.ProcessorCount; // Use all processors.

This sample uses "Parallel LINQ" and here's the two queries. Notice the "WithDegreeofParallelism."

seqQuery = from n in names
where n.Name.Equals(queryInfo.Name, StringComparison.InvariantCultureIgnoreCase) &&
n.State == queryInfo.State &&
n.Year >= yearStart && n.Year <= yearEnd
orderby n.Year ascending
select n;

parQuery = from n in names.AsParallel().WithDegreeOfParallelism(ProcessorsToUse.Value)
where n.Name.Equals(queryInfo.Name, StringComparison.InvariantCultureIgnoreCase) &&
n.State == queryInfo.State &&
n.Year >= yearStart && n.Year <= yearEnd
orderby n.Year ascending
select n;

The .NET 4 Training Kit has Extensibility demos, and Office Demos and SharePoint Demos and Data Access Demos and on and on. It's great fun and it's a classroom in a box. I encourage you to go download it and use it as a teaching tool at your company or school. You could do brown bags, study groups, presentations (there's lots of PPTs), labs and more.

Hope you enjoy it as much as I do.

2010 Survey Results: What .NET Framework features do you use?

In October of 2008 I took an informal survey on Twitter. I wanted to get an idea of what features of the .NET Framework people were using.

Also, here's the disclaimer. I did this on a whim, it's not scientific, so the margin of error is +/-101%. That said, the results feel intuitively right to me, personally.

I put the poll out again last week, adding only Silverlight to the end as an option. I realize I could have added many other subsystems and choices, but I felt it would have made this new poll too different from the original. There's certainly many ways that it could be improved as a survey, but it's best to think of it more as a "which direction is the wind blowing" question, than a survey per se.

I also didn't push/promote this survey very hard, so it got only about 1250 responses, vs. the nearly 5000 from last year, but I've kept the same color and attempted to keep the scale so one could extrapolate trends visually.

Hanselman Blog Informal .NET Subsystem Survey CHART - Updated 2010 

Here's the original survey:

Hanselman Blog Informal .NET Subsystem Survey CHART - 2008

It's also worth noting that 'NHibernate' was written into the "other" option 24 times. The poll was taken with TwtPoll.

Here's my conclusions.

  • WinForms remains popular but WPF is closing the gap.
  • ASP.NET MVC is nearly as popular as ASP.NET WebForms. Remember, however, that my readership 'skews Alpha' so might be more likely to be using MVC.
  • ADO.NET Data Services is starting to get some of the appreciation it deserves, but the existence of ADO Datasets persists.
  • Lots of folks use Silverlight, in this example set, even more than WPF.

What are your conclusions and analysis?

Breaking All The Rules with WCF

Sometimes, in my job, I go onsite at partners and work with them, sometimes architecturally, sometimes doing proofs of concepts to make sure they're comfortable with things working together.

This week I’m onsite at a large enterprise and one of the things they wanted to see, amongst many, was .NET interoperating with an existing Web Service. It's not important what platform their Web Service is running on, but it's not Windows and .NET. What was important was that they had WSDL and XSDs for the service, which put them above 99% of the Web Services I come upon in the enterprise.

The team here said that this particular web service used WS-Security and was a compliant web service. I figured, and told them, no problem. That's something .NET is good at. Moving angle-brackets around is something both I, and .NET do pretty well. I figured we had a number of options.

In this scenario was I going to be the Client, I could use:

  • WCF - svcutil.exe - good
  • System.Web.Services - wsdl.exe - pretty good
  • WebClient/XDocument/XmlDocument - not so good, but workable.

You get the idea. There were a few things wrong, though.

Bad-ish WSDL

They gave me the WSDL and when I ran svcutil.exe on it, I got this error (the elements have been changed to protect the innocent.)

C:\Users\Scott\Desktop\foo>svcutil foo.Wsdl foo.xsd /config:app.config
Microsoft (R) Service Model Metadata Tool
[Microsoft (R) Windows (R) Communication Foundation, Version 3.0.4506.2152]
Copyright (c) Microsoft Corporation. All rights reserved.

Error: Cannot import wsdl:binding
Detail: The WSDL binding named FooBinding is not valid because no match for
operation GetFooDetails was found in the corresponding portType definition.
XPath to Error Source: //wsdl:definitions[@targetNamespace='urn:foo:v1']/wsdl:
binding[@name='FooBinding']

Error: Cannot import wsdl:port
Detail: There was an error importing a wsdl:binding that the wsdl:port is dependent on.
XPath to wsdl:binding: //wsdl:definitions[@targetNamespace='urn:foo:v1']
/wsdl:binding[@name='FooBinding']
XPath to Error Source: //wsdl:definitions[@targetNamespace='urn:foo:v1']
/wsdl:service[@name='FooService']/wsdl:port[@name='FooPort']

I googled binged around for this to no avail. After staring at the file long enough, I realized that while this is a lousy error message (to be clear) it was telling me (obscurely) what was up all the while.

Here's a snippet of what I was looking at:

    <Type name="FooType">
<operation name="FooSearch">
<input message="tns:FooSearchRequest"></input>
<output message="tns:FooSearchResponse"></output>
<fault name="FooFault" message="tns:FooFault"></fault>
</operation>
</Type>

<binding name="FooBinding" type="tns:FooType">

<soap:binding style="document" trans="http://schemas.xmlsoap.org/soap/http"></soap:binding>

<operation name="FooSearch">
<soap:operation soapAction=""></soap:operation>
<input name="FooSearchRequest">
<soap:body use="literal"></soap:body>
</input>
<output name="FooSearchResponse">
<soap:body use="literal"></soap:body>
</output>
<fault name="FooFault">
<soap:fault name="FooFault" use="literal"></soap:fault>
</fault>
</operation>
...

The key was that their WSDL didn't have the name="" attribute on the input and output elements of the operation. The name needs to line up to the operation name in the binding.

<Type name="FooType">
<operation name="FooSearch">
<input name="FooSearchRequest" message="tns:FooSearchRequest"></input>
<output name="FooSearchResponse" message="tns:FooSearchResponse"></output>
<fault name="FooFault" message="tns:FooFault"></fault>
</operation>
</Type>

Once these new name="" attributes were added, I was able to generate my client-side stubs. I had to edit their WSDL, which sucks. However, you might argue svcutil.exe could chill out. Either way, a speed bump.

Claiming Compliance

I was told the Web Service would use WS-Security and a usernameToken. However, the actual message seemed like it was missing something.

<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" xmlns:wsse="http://schemas.xmlsoap.org/ws/2002/12/secext" xmlns:wsu="http://schemas.xmlsoap.org/ws/2002/07/utility" xmlns:tns="urn:foo:v1" xsi:schemaLocation="http://www.w3.org/2003/05/soap-envelope http://www.w3.org/2003/05/soap-envelope/soap-envelope.xsd urn:foo:v1 com.foo.messages.v1.xsd">
<soapenv:Header>
<wsse:Security>
<wsse:UsernameToken>
<wsse:Username>secret</wsse:Username>
</wsse:UsernameToken>
</wsse:Security>
</soapenv:Header>
<soapenv:Body>
<tns:FooRequest>
...

It's been a while (about 18 months) since I did any WCF and WS-Security, but UsernameToken really needs to have a Password element also. Additionally, when you're using WS-Security, you typically get WS-Addressing, etc along for the ride. There's other headers I'd expect to see.

I trudged on, built up the message and tried to send it off. First problem was that the endpoint URI I had was http, not https. It's not possible to send a UsernameToken in plain-text - the system explicitly forbids it. However, their system was setup to default to basic HTTP. Some gnashing of teeth and I found an SSL endpoint I could use. However, it's a hassle to debug SSL traffic. I usually use ProxyTrace or TCPTrace but with SSL, not so much.

Sniffing SSL Traffic with a Proxy

I ended up using Charles, an HTTP Proxy that can act as a man-in-the middle, issue an SSL cert, then decrypt the traffic, and forward it along to the real endpoint. However, the SSL Cert Charles issues isn't from a certificate authority, so I had to make a Policy to blindly (temporarily) accept all certificates:

internal class AcceptAllCertificatePolicy : ICertificatePolicy
{
public AcceptAllCertificatePolicy(){}

public bool CheckValidationResult(ServicePoint sPoint,
X509Certificate cert, WebRequest wRequest, int certProb)
{
return true; //Always accept
}
}

Then I apply it in this (obsolete, but easy) way:

ServicePointManager.CertificatePolicy = new AcceptAllCertificatePolicy();

Now I can run all my traffic through my local man-in-the-middle. I can set the proxy in my config file:

<basicHttpBinding>
<binding name="FooBinding"
...
proxyAddress="http://BigAssLaptop:8888"
useDefaultWebProxy="false">

or in my own binding:

WSHttpBinding oldBinding = new WSHttpBinding();
oldBinding.ProxyAddress = new Uri("http://BIGASSLAPTOP:8888");

FooPortTypeClient svc = new FooPortTypeClient(oldBinding, new EndpointAddress("https://example.com/foo/v1"));

This let me see the outgoing request. I noticed immediately that my WCF client was sending a LOT more stuff that I needed.

Breaking the Rules

It was hard for the client to hear, but here's the deal. They were using the usernameToken element, alone, in the WS-Security namespace in the style of an apiKey. You often see these kinds of APIs in the Web 2.0 world, when intense security isn't needed. You get a key that's unique to you, basically a GUID, and it also acts as a tracker for the provider.

However, this isn't how WS-Security usernameTokens work, or are supposed to work. Perhaps a better way would have been for them to use a custom soap:header, rather than trying to tunnel "apikey" semantics into an existing token.

At this point, regardless of relative-wrongness, I still need to get the WCF client to talk to this unusual endpoint. I could use one of the other XML mechanism available, or, gasp, a StringBuilder, but since I wasn't having trouble with the body of the message, just the envelope.

This essentially means that I wanted WCF to do something incorrect, on purpose. After a call to Steve Maine and team, along with some general freaking out, I was able to get WCF to spit out JUST a usernameToken, like this.

WSHttpBinding oldBinding = new WSHttpBinding();
oldBinding.Security.Mode = SecurityMode.TransportWithMessageCredential;
//Just the username
oldBinding.Security.Message.ClientCredentialType = MessageCredentialType.UserName;
//And basically nothing else
oldBinding.Security.Message.NegotiateServiceCredential = false;
oldBinding.Security.Message.EstablishSecurityContext = false;

//oldBinding.ProxyAddress = new Uri("http://BIGASSLAPTOP:8888");
//oldBinding.UseDefaultWebProxy = false;

//remove the timestamp
BindingElementCollection elements = oldBinding.CreateBindingElements();
elements.Find<SecurityBindingElement>().IncludeTimestamp = false;

//sets the content type to application/soap+xml
elements.Find<TextMessageEncodingBindingElement>().MessageVersion = MessageVersion.Soap12;
CustomBinding newBinding = new CustomBinding(elements);
FooPortTypeClient svc = new FooPortTypeClient(newBinding, new EndpointAddress("https://example.com/foo/v1"));
FooRequest req = new FooRequest();
//...etc...now it's just request and response.

Unfortunate, but I'll put this configuration of a custom binding, and hopefully when they fix it, it'll be a configuration change. This at least got us to a point where I can reliably call their web services.

Long day, but interesting stuff.

Page 1 of 88 in the Web Services category Next Page
Disclaimer: The opinions expressed herein are my own personal opinions and do not represent my employer’s view in any way.