>
 Thursday, July 27, 2006

There's a nice little diagnostic tool that ships with the SDK for .NET 3.0 - svctraceviewer.exe. You WILL need this tool. It is a great way to inspect messages when things are going as expected, you can see the service model trace to inspect components leading up to an exception, you can see the details leading up to a service fault, more than is shown in the inner exception at times.

Here's an example configuration for the service-side for June/July CTP:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <system.serviceModel>
        <services>
            ...            
        </services>

    <diagnostics performanceCounters="All" wmiProviderEnabled="true">
            <messageLogging logEntireMessage="true" logMalformedMessages="true" logMessagesAtServiceLevel="true" logMessagesAtTransportLevel="true" maxMessagesToLog="100000"/>
        </diagnostics>

    </system.serviceModel>
    <system.diagnostics >
        <sharedListeners>
            <add name="sharedListener"
                 type="System.Diagnostics.XmlWriterTraceListener"
                 initializeData="c:\logs\servicetrace.svclog" />
        </sharedListeners>
        <sources>
            <source name="System.ServiceModel" switchValue="Verbose, ActivityTracing" >
                <listeners>
                    <add name="sharedListener" />
                </listeners>
            </source>
            <source name="System.ServiceModel.MessageLogging" switchValue="Verbose">
                <listeners>
                    <add name="sharedListener" />
                </listeners>
            </source>
        </sources>
    </system.diagnostics>
</configuration>

To view trace output launch svctraceviewer.exe and open the .svclog file. The Messages tab will take you directly to the actual messages that move between client and service, including full XML output (excluding binary data). The items in yellow are warnings, items in red are exceptions...where you can view details of the exception in the XML dump. Make sure you scroll all...the...way...down and look for the details of the exception...good stuff in there (or, bad stuff...I guess, if there is an exception).

 

7/27/2006 5:31 PM Indigo  | Comments [176]  |  View reactions  |  Trackback
 Monday, March 20, 2006

Updated 04/09/06

See the previous few entries with code for my interoperability tutorial, and web services tutorial. Collectively they include the code for this session. Thanks!

 

UPDATED: 3/27/06

At last, here are the links to our interop code from the tutorial at SD West. For those that didn't attend, we covered the following:

Please enjoy!

 

3/20/2006 9:20 AM Indigo | Interoperability | Speaking/Events | WebLogic  | Comments [16]  |  View reactions  |  Trackback
 Wednesday, March 08, 2006

A few people asked me for this, so here you go! Feburary CTP links, and order of installation are:

3/8/2006 6:34 AM Indigo  | Comments [3]  |  View reactions  |  Trackback
 Wednesday, February 01, 2006

I blog when I have time and have something important to share, but I don't always have time to blog everything important I have to share (that's what articles and books are for I guess)...sometimes I blog just to hook you up to content references for events I've been part of...but today...I'm just blogging to vent my frustration with code snippet management in Visual Studio 2005. Aaarrrrghhhh...

Don't get me wrong, code snippets rock for productivity, but creating your own and getting them to freaking appear in the right place seems like a feat of great energy and time that I really do not have...sigh...but I took the time anyways because I figure if I just spend 2 hours (or 7200 seconds) now to get it working, then spend and extra 5 minutes (or 300 seconds) creating snippets for my repeatable code...it will pay off after I use about 200 snippets. Assuming I use about 3 code snippets per code sample, and that I create several code samples per day for my WCF book, not to mention other code samples and vertical slices for clients...I should be able to recover this time about 20 days time or less. Of course, I'm not factoring in time to write this blog...

So here goes my experience creating code snippets:

Creating new XML config snippets, no problem at all. Just copied an existing code snippet sample and away we go! Off to a good start.

Adding the code snippet to the Code Snippet Manager. Well first of all, figuring out what Add... versus Import... mean in that dialog is a pain. No, I didn't take the time to read an article about it...and frankly I expected it to be pretty easy to figure out. Well it seemed like sometimes Add worked, sometimes it didn't, but I seem to have finally figured out that you are supposed to select a directory that holds the code snippet type for the language you are adding folders to.

So, I created a WCFSnippets folder with two subdirectories:

\WCFCode -> holds my C# WCF code snippets

\WCFConfig -> holds my XML WCF code snippets for configuration

Then, from the code snippet manager, you select XML for the language and click Add. What you are supposed to do is find the folder with your XML snippets, so I navigate to \WCFConfig...but don't just navigate to that directory, drill all the way into the directory where the snippets are stored before you select the directory. Here are the screenshots: wrong, right and result...respectively.

For C# or VB.NET snippets, just select the right language, and drill into the directory where those are located.

Extra crap in my code snippets intellisense...make no "sense". I know the above seems really super easy...and it is once you know where to navigate and how to organize your stuff. Still, I had all kinds of extra crap left over in my snippet manager, and in my code snippet intellisense...let me explain.

After trying Add/Import, I was left with extra folders in my code snippet manager, that somehow didn't reflect all the snippets I was creating...it was nuts...I was going nuts...maybe I am nuts...anyways it turns out that Import is not really necessary if you have added your snippets folder according to the Add method I explained. Any new snippets you create in those custom folders will now appear in the magical snippets list. But, if you want to copy (import) a snippet from somewhere and put it into one of your folders (or, one of the predefined snippet folders for VS) you can Import.

If I navigate to my WCF configuration snippets folder and select a snippet, I will be presented with the already existing XML folders (preexisting or resulting from Add). You decide where you want the snippet to go and a copy is made there. Watch out for dupes!

The bugger of it is, you can't remove snippets. You can add them, but they will never go away...that is unless you delete the actual snippet from the file folder. So much for snippet management. You can remove folders, just not those living in the VS snippet folder, that's too official to remove...

Things to watch out for.

1. Beware not to add your snippet directories more than once. Or not to add the parent directory, only to decide on the child directory as in my WCFSnippets and WCFConfiguration example earlier. What happens? Well, somewhere out in snippet configuration land (a lost land that I cannot find) there is memory of every (wrong) directory you ever added using Add...and you can't freaking get rid of it. Well...I'm sure you can, but I care not spend more time to figure out why...perhaps someone else can tell me!!!

2. Make sure you put the correct language in your snippet code. If you call it XML but it's really C# (spelled csharp in snippet terms) you won't see it appear in your C# snippets after all...another ghost I chased...for a short while.

Sample snippet...for your time...more to come :)

<?xml version="1.0" encoding="utf-8" ?>
<CodeSnippet Format="1.0.0" xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">
<Header>
<Title>system.serviceModel.diagnostics</Title>
<Author>Michele Leroux Bustamante</Author>
<Shortcut>serviceModel.diagnostics</Shortcut>
<Description>Sample system.serviceModel.diagnostics section.</Description>
<SnippetTypes>
<SnippetType>Expansion</SnippetType>
</SnippetTypes>
</Header>
<Snippet>
<Declarations>
<Literal>
<ID>perfCounters</ID>
<Default>true</Default>
<ToolTip>Enable performance counters: true|false</ToolTip>
</Literal>
<Literal>
<ID>wmiProvider</ID>
<Default>true</Default>
<ToolTip>Enable WMI provider: true|false</ToolTip>
</Literal>
<Literal>
<ID>logEntire</ID>
<Default>false</Default>
<ToolTip>Log entire message content (beware! production performance hit): true|false</ToolTip>
</Literal>
<Literal>
<ID>logMalformed</ID>
<Default>true</Default>
<ToolTip>Log malformed messages (or, provide your own logging mechanism, don't do both!): true|false</ToolTip>
</Literal>
<Literal>
<ID>logServiceLevel</ID>
<Default>false</Default>
<ToolTip>Log messages at service level: true|false</ToolTip>
</Literal>
<Literal>
<ID>logTransportLevel</ID>
<Default>true</Default>
<ToolTip>Log messages at transport level: true|false</ToolTip>
</Literal>
<Literal>
<ID>maxLog</ID>
<Default>100000</Default>
<ToolTip>Maximum message log count (runs out fast, must backup the file!)</ToolTip>
</Literal>
</Declarations>
<Code Language="XML" Format="CData">
<![CDATA[ <diagnostics performanceCountersEnabled="$perfCounters$" wmiProviderEnabled="$wmiProvider$" >
         <messageLogging logEntireMessage="$logEntire$" logMalformedMessages="$logMalformed$" logMessagesAtServiceLevel="$logServiceLevel$" logMessagesAtTransportLevel="$logTransportLevel$" maxMessagesToLog="$maxLog$" />
     </diagnostics>]]>
</Code>
</Snippet>
</CodeSnippet>

 

2/1/2006 9:05 PM Indigo | Visual Studio  | Comments [14]  |  View reactions  |  Trackback
 Tuesday, January 31, 2006

Ok folks...here's a sample (er full blown wicked application) that makes all my 6 project WCF samples that include security, transactions, reliable messaging, MTOM file uploads and more...look like Hello World...

Clemens Vasters, founder of Newtelligence, leader of the community project dasBlog (my blog engine), well known blogger/speaker/writer/thought leader, and a person I am proud to call my friend...has really done it this time.

Newtellivision, get it here (he's popular, hence the site might be slightly slow)...

http://www.newtellivision.tv/2006/01/30/GoingOutAndInWithABangNewtellivision.aspx

 

1/31/2006 4:59 PM Indigo  | Comments [8]  |  View reactions  |  Trackback
 Wednesday, January 25, 2006

The January CTP was released last week. I won't be updating my chapters for this CTP, because I have received a later CTP (Feb CTP/RC0) to work with...so if you are reviewing my book you may have to email me with questions. 

Here's the instructions to build a machine or VPC for this latest release.

  1. Operating System: XP Professional with SP2 or Windows 2003 Server (note: I'm not including Vista/Longhorn yet, VPC isn't working well with those)
  2. SQL Server: Install SQL Server 2000 or 2005, but you can skip this step if you want to use SQL Express which is installed with Visual Studio 2005 if you elect to.
  3. Visual Studio 2005: include SQL Express if you didn't do step 2. NOTE: I like to keep a VPC handy up to this point, and make copies of it as I need to rebuild for future WinFX CTP releases.
  4. WinFX Runtime Components (Jan CTP): http://www.microsoft.com/downloads/details.aspx?FamilyId=61DD9CA7-1668-42E4-BD37-03716DD83E53&displaylang=en
  5. Windows SDK (Jan CTP):  http://www.microsoft.com/downloads/details.aspx?FamilyId=64750EEF-D4A7-4CC8-92F2-9A201268A231&displaylang=en
  6. Visual Studio Extensions for WinFX (Jan CTP): http://www.microsoft.com/downloads/details.aspx?FamilyId=5A0AE4CD-DC79-4B12-8A05-B6195F89FFA2&displaylang=en
  7. Visual Studio Extensions for Workflow (Jan CTP): http://www.microsoft.com/downloads/details.aspx?FamilyId=A2151993-991D-4F58-A707-5883FF4C1DC2&displaylang=en

There's a Go Live license now available for WCF and WWF. Here's the link to details: http://msdn.microsoft.com/winfx/getthebeta/golive/default.aspx

UPDATE 01/26/06 - Don't forget to read the January CTP notes regarding support for WS-AT. You have to install COM+ QFE for this functionality. http://msdn.microsoft.com/windowsvista/support/relnotes/winfxjanctp/default.aspx

 

1/25/2006 9:30 PM Indigo  | Comments [6]  |  View reactions  |  Trackback
 Tuesday, January 24, 2006

Thanks to everyone who attended my sessions at Code Camp this past weekend. Here are the links to content I promised you, related to each talk I delivered:

Cool things: I'm already working with several clients to design their enterprise systems using WCF - replacing former ASMX, remoting and ES approaches...so adoption seems to be heating up fast!!! If you need the same services, you know who to call :) www.idesign.net

1/24/2006 4:49 PM Indigo | Speaking/Events  | Comments [13]  |  View reactions  |  Trackback
 Thursday, January 05, 2006

I had some questions on versioning contracts, so I thought I'd write up a quick list of tips on this subject, some of which applies to any platform where contracts drive communications (read: web services in general).

Point #1 – breaking changes require contract versioning

Here are an example of some breaking changes that cause serialization requirements for a service to change:

  • Remove operations
  • Change operation name
  • Remove operation parameters
  • Add operation parameters
  • Change an operation parameter name or data type
  • Change an operation's return value type
  • Change the serialized XML format for a parameter type (data contract) or operation (message contract) by explicitly using .NET attributes or custom serialization code
  • Modify service operation encoding formats (RPC Encoding vs. Document Literal)

Point #2 – modifications to implementation semantics require contract versioning

Even if there are no contract versioning violations from #1, if the implementation semantics of an operation have changed this warrants contract versioning. If your clients call an Add operation and you decide that Add will no longer add, it will subtract...then your existing clients should continue to call the "old service operation" and you should create a new operation for the subtract operation. If the change is subtle, and if clients will not be affected by the change, no need to create a new operation.

Do you have to version the contract if you add a new operation? Not necessarily, however if you have a contract that has been published with methods A, B and C...and clients have been programming against that contract, then when you add methods D and E it would be good to provide a distinction between the original contract, and the new one. If the new methods are still related to the same contract, you can provide a new contract by the same name, with a new namespace.

Point #3 – you can avoid contract versioning

You can reduce the changes of #1 and #2 being directly violated. For example, a parameter can receive alternate serialization formats, the service can opt to forgive missing elements, or ignore extra elements. You can design the service contract to be forgiving by things like this:

  • Using optional elements in data contracts
  • Using IXmlSerializable types and “handling” serialization differences behind the scenes
  • Intercepting parameter serialization and deserialization at a lower level to overcome differences

You can also avoid parameter list modification issues by avoiding specifying a list of parameters in your methods. For example instead of:

void Add(int x, int y);

use:

void Add(AddRequest message);

where AddRequest is a type that receives x and y:

[DataContract] public class AddRequest
{

  [DataMember] public int x;

  [DataMember] public int y;

}

Now, if you add another public member to the AddRequest type, and make sure it is not a required element, old clients can send their reduced set along:

  [DataMember(IsRequired="false")] public int z;

You can preserve unknown serialization elements as well, on the client or on the service side, by implementing IUnknownSerializationData in your data contract types. You can find out more about this in my book chapter on Contracts, which will be posted when I launch my book blog this week.

1/5/2006 2:29 AM Indigo  | Comments [14]  |  View reactions  |  Trackback

This article was published last month on The Server Side...I just forgot to let you know :)

http://www.theserverside.net/articles/showarticle.tss?id=DesignServiceContracts

 

1/5/2006 2:06 AM Indigo  | Comments [17]  |  View reactions  |  Trackback
 Saturday, December 31, 2005

This CTP was released December 21st, so I have been updating my existing book chapters to make sure things still “work” if you know what I mean. Here's the instructions to build a machine or VPC for this latest release.

  1. Operating System: XP Professional with SP2 or Windows 2003 Server
  2. SQL Server: Install SQL Server 2000 or 2005, but you can skip this step if you want to use SQL Express which is installed with Visual Studio 2005 if you elect to.
  3. Visual Studio 2005: include SQL Express if you didn't do step 2. NOTE: I like to keep a VPC handy up to this point, and make copies of it as I need to rebuild for future WinFX CTP releases.
  4. WinFX Runtime Components (Dec CTP): http://www.microsoft.com/downloads/details.aspx?familyid=BD3BA2D5-6ADB-4FB2-A3AA-E16A9EA5603F&displaylang=en
  5. Windows SDK (Dec CTP): http://www.microsoft.com/downloads/details.aspx?FamilyId=2297BDC9-B5AE-4B8A-B601-EEF54A52867A&displaylang=en
  6. Visual Studio Extensions for WinFX (Dec CTP): http://www.microsoft.com/downloads/details.aspx?familyid=D1336F3E-E677-426B-925C-C84A54654414&displaylang=en

A few things you might want to know after completing this installation:

  • The installation directory for the SDK has changed since earlier CTP: C:\Program Files\Microsoft SDKs\Windows\v1.0\
  • To get at the samples for W*F you must unzip the rather large AllSamples zip file located in C:\Program Files\Microsoft SDKs\Windows\v1.0\samples (NOTE: this can take 1 hour on VPC...and I have a pretty fast machine with lots of RAM!)

I'll be posting links to my WCF book code updated for Dec CTP this week...with a really cool new site update, stay tuned!

12/31/2005 7:09 PM Indigo  | Comments [10]  |  View reactions  |  Trackback
 Wednesday, November 30, 2005

I posted some WCF samples earlier in this blog, and they were built against a (then) unreleased version of the bits. Now you can get them too, here: http://www.microsoft.com/downloads/details.aspx?FamilyId=E5376297-DA10-4FC3-967D-38C96F767FC4&displaylang=en

This build works with VS 2005, the steps to build a machine:

Enjoy! Check out my earlier Indigo posts for code samples. Some are built for PDC bits, later are built for these bits... thought I can't absolutely guarantee it since I am using early builds before they are public. Let me know if you find incompatibilities so I can try to help.

11/30/2005 11:13 PM Indigo  | Comments [4]  |  View reactions  |  Trackback
 Wednesday, November 16, 2005

I delivered these two WCF/Indigo talks at DevConnections last week, and this post contains sample code demonstrated in both talks.

NOTE: I am building all sample code with November 2005 bits, so they will NOT work with PDC bits. I will update these samples for the very next public CTP so you can look for that.

  • HelloIndigo – a simple WCF service, decoupled host
  • ComplexTypes – serialization via DataContract
  • ComplexTypesV2 – serialization of base types and interfaces
  • CustomMessage – my WS-Transfer implementation is not compiling with the current build I have, so I will update this when the issue is resolved
  • Messaging – illustrates sessions and instancing
  • SimpleQueue – simple msmq example
  • WindowsAuthentication – windows auth and security context information display
  • SecureService – windows auth and username auth demo, with custom membership provider

I am also posting the slides from this talk. I took this talk over at the last minute for Clemens, and we didn’t have time to get the slides in for the printed books.

VID307DesigningServicesWithIndigo.zip (55.37 KB)

I also promised a tutorial, and my plan is to get permission from my publisher to post a few labs from each chapter in my book, including the security tutorial I showed in the security session. I will update this post to let you know where that will be found…stay tuned for a few more days.

 

11/16/2005 11:50 PM DevConnections | Indigo | Speaking/Events  | Comments [0]  |  View reactions  |  Trackback
 Monday, October 03, 2005

Never ever ever ever ever ever ever ever ever ever ever ever ever ever ever ever ever ever ever ever ever ever ever ever ever ever ever ever ever ever ever ever ever ever ever ever ever ever ever ever ever ever ever ever ever ever ever ever ever ever ever write service contracts and implementations inline.

With the PDC bits for WCF, using the Indigo Service template is like opening a box of chocolates...you never know what you'll get...IService, IMyService, IIndigoService...but that's just Beta stuff...

For Web sites the template generates the .svc endpoint and service implementation, for other project types it generates only the service implementation. Normally the service implementation would be in a .cs or .vb file (pick your language)...and this is true in all cases but one: adding a new Indigo Service to an existing Web site project in Visual Studio.

This template is evil...it creates inline code like this, with all the implementation in the target IIS endpoint file:

<%@ Service Language="C#" Class="IndigoService" %>

using System;
using System.ServiceModel;

[ServiceContract()]
public interface IIndigoService
{
    [OperationContract]
    string MyOperation1(string myValue);
}

public class IndigoService : IIndigoService
{
    public string MyOperation1(string myValue)
    {
        return "Hello: " + myValue;
    }
}

Now if I want to host this service outside of this Web site application I'll have to copy the service code into another file somewhere, or migrate this code to use a class library and share it. Why would I not just create the service in the class file from the beginning?

This may change before release...but just in case bookmark this post ...

10/3/2005 8:39 AM Indigo  | Comments [3]  |  View reactions  |  Trackback

Getting back to my earlier brain dump on the many ways you can create WCF services today...I have uploaded two samples:

The first sample is a solution with three projects: service, host and client. The service is a class library with a HelloIndigo.Service implementation, the host is a console application that initializes the ServiceHost for the service (self-host over HTTP), and the client consumes the service. ServiceFromScratchConfig.zip (54.5 KB)

THe second sample is a solution with two projects: a Web site created from the Indigo Service template, and a client to consume the service. The Web site acts as the host for the service (through IIS) but actually references the HelloIndigo.Service from the previous example. IISHostedService.zip (22.11 KB)

Same service, two hosts with possibly different bindings, behaviors, instancing.

If you always designer your services to be “moveable“ you will have an agile service-oriented system on your hands. The service contract and implementation (as expected) does not change, that should be appropriately versioned once it has been published. Oh, and guess what? Since the service is contained in a separate class library (assembly) it can be versioned appropriately with CLR versioning as well as contract versioning semantics.

So I have now explained why you should never use the Indigo Template “as is” when you build Web site, console, class library, or other applications that contain or host services. Sorry...templates are for kids...

10/3/2005 8:24 AM Indigo  | Comments [1]  |  View reactions  |  Trackback

I had several conversations this weekend with Steve Swartz (one of my favorite people, not just because he's smart, but he's a really cool guy too!) about best practices in various aspects of the service model. I'll eventually get a chance to blurt all of my thoughts on this (and confirmations a-la Steve) but let's start with the subject: base address and endpoints...how “should” it work?

Consider this example that creates a new self-hosted service with a base address and endpoint Uri as shown here hard-coded:

Uri baseAddress = new Uri("http://localhost:8000/HelloIndigo");
using (ServiceHost host = new ServiceHost(typeof(HelloIndigo.Service), baseAddress))
{

host.AddEndpoint(typeof(HelloIndigo.IService), new BasicHttpBinding(), new Uri("http://localhost:8000/HelloIndigo/Service"));

host.Open();
Console.ReadLine();
host.Close();
}

Seems harmless, and it will work. Clients will bind against the target Uri of the endpoint:

http://localhost:8000/HelloIndigo/Service

But the truth of the matter is that the base address should be relied on as the...well as the base address for all endpoints that share the same protocol, port, etc. In the above example that would suggest that when I add an endpoint to the service host, I should only submit “Service“ as a string (something you can do with one of the overloaded methods for AddEndpoint):

host.AddEndpoint(typeof(HelloIndigo.IService), new BasicHttpBinding(), "Service");

The same goes for declarative configuration for the service host, no need to specify the complete Uri, it will be inferred from the base address:

<service type="HelloIndigo.Service" >
  <endpoint address="Service" contract="HelloIndigo.IService, HelloIndigo"
binding="basicHttpBinding" />
</service>

This makes your services more configurable, modify the base address and relative Uri will follow suit.


 

10/3/2005 8:06 AM Indigo  | Comments [18]  |  View reactions  |  Trackback
 Sunday, October 02, 2005

I thought I'd share this observation in the interest of coding practices for the WCF. For client applications invoking services, you'll see lots of samples already out there that use the following syntax:


ChannelFactory<IService> factory = new ChannelFactory<IService>("");
IService proxy = factory.CreateChannel();

string s = proxy.HelloIndigo();


But, the proxy generated for you, that inherits ClientBase<T>, will handle creating the channel for you so you can use syntax like this:


using (ServiceProxy proxy = new ServiceProxy(""))
{
  string s = proxy.HelloIndigo();
}


Besides its relative simplicity, another slant in favor of using the proxy generated for your service is that its base class implements IDisposable, therefore you can use the using statement to expedite cleanup of channel resources.

There are probably cases where you will need to interact with the channel directly, though none come to mind at the moment...for the most part you should be able to configure the channel using binding configurations.


 

10/2/2005 4:33 AM