Skip to main content

Blog

Go Search
Home
  

Blog of Petar Vucetin, containing my thoughts, comments and questions.
7 Hidden Gems - tools for everyday WCF / WF developers

WCF, WF and CardSpace Samples is a treasure throve of samples for WCF and WF. In these samples there are five hidden tools you should know about. Also, in well hidden folder under Microsoft SDKs there are two incredibly useful tools for your every day WCF developer.

 

WCF Tools

WCF Service and Client Configuration editor

Location: C:\Program Files\Microsoft SDKs\Windows\v6.0A\bin\SvcConfigEditor.exe

What is it for: Nice and easy way to edit your WCF configuration files.

You can run this tool either from the location above or from Visual Studio. In VS its located under Tools menu. If you have your project setup correctly you could just right click any .config file to start editing.

image

 

WCF Service Log Viewer

Location: C:\Program Files\Microsoft SDKs\Windows\v6.0A\bin\SvcTraceViewer.exe

What is it for: Reviewing the trace logs from WCF service.

Using the WCF Configuration editor open up the Diagnostics folder. You can find bunch of knobs to turn on service tracing.

image

 

Custom Binding Configuration Code Generator

Location: \WCF_WF_CardSpace_Samples\WCF\Tools\ConfigurationCodeGenerator

What is it for: It generates all necessary plumbing for custom bindings.

If you are into writing custom bindings this tools is a must. Custom bindings are plugged in via the <extensions> element in the <system.serviceModel> element.

<extensions>
  <bindingElementExtensions>
    <add name="udpTransport" type="Microsoft.ServiceModel.Samples.UdpTransportElement, UdpTransport" />
  </bindingElementExtensions>
  <bindingExtensions>
    <add name="sampleProfileUdpBinding" type="Microsoft.ServiceModel.Samples.SampleProfileUdpBindingCollectionElement, UdpTransport" />
  </bindingExtensions>
</extensions>

This is a command line tool. You can see this blog post about how to setup command prompt with Vista so you can right click on any folder and drop in the command prompt window.

Usage:

ConfigurationCodeGenerator

/be:<BindingElementTypeName>]

/sb:<StandingBindingTypeName>]

/dll:<Dll>

Example:

ConfigurationCodeGenerator.exe /be:UdpTransportBindingElement /sb:SampleProfileUdpBinding /dll:..\..\..\..\Extensibility\Transport\Udp\CS\UdpTestService\bin\Debug\UdpTransport.dll

image

image

 

Custom Channels Tester

Location: \WCF_WF_CardSpace_Samples\WCF\Tools\CustomChannelsTester

What is it for: Creates a sample application using your custom binding and tests the client and server implementations.

image

 

Workflow Tools

External RuleSet Toolkit

Location: \WCF_WF_CardSpace_Samples\WCF\Extensibility\Rules\ExternalRuleSetToolkit

What is it for: Creating workflow rules outside Visual Studio.

Rules are stored in the database or they can be exported to .rule XML file. In the sample you will find the Setup.cmd and Setup.sql which creates the Rules database and RuleSet table in SQLEXPRESS instance by default.

You use these rules with the Policy activity in your workflow or you can load and execute rules with the System.Workflow.Activities.Rules.RuleEngine in your code.

image 

image

Exported .rule file.

image

Rules stored in the database.

image

Tracking Profile Designer

Location: \WCF_WF_CardSpace_Samples\WF\Applications\TrackingProfileDesigner

What is it for: Recoding Workflow, Activity or User level tracking points. Good for debugging. Also generates tracking profile XML.

You will need to install few scripts in the WF tracking database (just create empty database) C:\Windows\Microsoft.NET\Framework\v3.0\Windows Workflow Foundation\SQL\EN\


image

There are few good articles here and here about tracking.

image

Workflow Monitor

Location: \WCF_WF_CardSpace_Samples\WF\Applications\WorkflowMonitor

What is it for: Monitors current workflow instance.

Useful as a first aid kit for debugging your workflow.

image

 

What tools do you use and find useful in your every day WCF/WF adventures?

Petar

Share this post :
Edit WCF Configuration context menu missing

If you find your self missing the WCF configuration editing tool when you right click the config file in your project don't PANIC. There are couple of ways to get this working again. One way is to modify your proj file and another way is to add ServiceConfig.exe as one of the file type editors in Visual Studio. And there is an ultimate super geeky way too!

 

image

Modifying the Visual Studio proj file route

In your solution right click the project file and select Unload Project from the context menu. Now right click the project file again and select edit from the context menu. You will see a ton of XML goo. Again don't PANIC.

Add this XML

<ProjectTypeGuids>{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>

right after the AssemblyName XML element, like so:

<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5">
  <PropertyGroup>
    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
    <ProductVersion>9.0.30428</ProductVersion>
    <SchemaVersion>2.0</SchemaVersion>
    <ProjectGuid>{86A43EFA-B018-421B-B67F-C170139A79E4}</ProjectGuid>
    <OutputType>Exe</OutputType>
    <RootNamespace>Microsoft.ServiceModel.Samples</RootNamespace>
    <AssemblyName>WCF_Router.Router</AssemblyName>
<ProjectTypeGuids>{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
    <WarningLevel>4</WarningLevel>
    <FileUpgradeFlags>
    </FileUpgradeFlags>
    <UpgradeBackupLocation>
    </UpgradeBackupLocation>
    <OldToolsVersion>2.0</OldToolsVersion>
    <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
  </PropertyGroup>

Now right click the project in the solution and select Reload from the context menu. Click Yes. That should be it.

Open With route

If the method above looks to esoteric and scary or just simply does not work you can use this technique. Right click the config file and from the context menu select  "Open With".  Click Add and you will be presented with Add Program dialog box. For the program name navigate to C:\Program Files\Microsoft SDKs\Windows\v6.0A\bin\SvcConfigEditor.exe (or just copy paste this path). Set Friendly Name to WCF Config Editor.

image

Now you can right click the config file and from the context menu select Open With then select WCF Config Editor and click Ok. And all is good.

For super geek's only

If none of these methods are to exciting you can always select this tool from Tools menu :)

image

The only drag is that you will have to navigate to your config file from within the configuration editor. This certainly puts a little bit of excitement in your day hunting down config files on your box. It's a jungle out there.

Petar.

Share this post :
Twitter WCF Client

Well this was interesting experience! You would think this would be very simple to write a Twitter client. Right?! I was confronted with many interesting problems. Service was  thrown at me all kinds of curve balls. Malformed XML, using protocol status codes to raise errors, different message shapes for a single operation. Come see how WCF architecture was handling it all through custom bindings, operation behavior and channel modifications.

How do you go about creating WCF client for Twitter service?

The first step is figuring out the end point communication method, security requirements and message shape of the service APIs. Twitter API is located here http://groups.google.com/group/twitter-development-talk/web/api-documentation

image

In the case of Twitter its API request model uses REST  for service calls, HTTP Basic Auth for security model and response message format is either POX (Plain Old XML) or JSON. I chose to implement POX because there are plenty of tools in CLR base class library that can manipulate XML.

How does this translate to WCF client configuration?

We can configure WCF client many ways. One of my objectives is that WCF client implementation (aka proxy) should be the most basic vanilla C# implementation out of the box I can get away with.

This is what I wanted the client code to look like:

using (TwitterClient proxy = new TwitterClient("[USER]", "[PASSWORD]"))
{
    var response = proxy.Update("hello");
    
    Console.WriteLine(response);
}

Accompanying this client is the configuration file with settings that will configure our proxy at runtime. The key element that will bind our proxy with this endpoint is the contract, ITwitterClient.

   1: <client>
   2:     <endpoint 
   3:         address="http://twitter.com" 
   4:         binding="customBinding" 
   5:         contract="ITwitterClient" 
   6:         
   7:         behaviorConfiguration="WebGet"
   8:         bindingConfiguration="TwitterBinding"
   9:         
  10:         name="TwitterClient" />
  11: </client>

The obvious ABCs of WCF: address - where is the service located; Binding - how is the WCF runtime configured to communicate with the service; Contract - what the service communicates. 

Enabling REST

Looking at the config file will not give you any hints just yet about how did I configure proxy to use REST or Basic auth. To get the REST model I had to tell the end point to use different behavior than standard SOAP. You turn this on by modifying the end point behavior and adding webHttp behavior.

   1: <behaviors>
   2:     <endpointBehaviors>
   3:         <behavior name="WebGet">
   4:             <webHttp />
   5:         </behavior>
   6:     </endpointBehaviors>
   7: </behaviors>

This behavior modifier enables the Web programming model. What this means is that you can use POST, GET and other standard web methods and use RESTful service call pattern.

Configuring Basic Authentication

This could have been dead simple to configure but I had to deal with some unusual service behaviors and configure my endpoint to use custom binding.  More about this latter in this article. In normal circumstances I could have just used new webHttpBinding that comes with WCF 3.5 and configure it like this:

<webHttpBinding>
    <binding name="BasicAuth">
        <security mode="TransportCredentialOnly" >
            <transport clientCredentialType="Basic"/>
        </security>
    </binding>
</webHttpBinding>

But I could not use this binding. I had to create my own custom binding.

Client implementation

If you look at any proxy auto-generated code you will find that all proxy clients derive from ClientBase<T> class. I did not generate the client but I created my own following the same idea:

image

I wanted to keep with "out of the box" code as much as I can. You might notice that there are bunch of ITiwtterxxxx interface implementations.

Why this many interfaces?

If you look through the Twitter API you will notice that the API is divided in different method sections. It seemed logical to divide these into different interfaces for clarity and give opportunity for developers to implement clients that focus on different functions. Twitter client inherits from all these interfaces.

[ServiceContract]
public interface ITwitterClient : ITwitterStatus, ITwitterHelp, ITwitterBlock, ITwitterNotification,
    ITwitterFavorite, ITwitterAccount, ITwitterFriendship, ITwitterDirectMessage, ITwitterUser
{
}

Each of the interfaces is a service contract and defines operation contracts for each method in the API specification.

image

WebGet and WebInvoke  combined with webHttp end point behavior enable Web http programing. WebGet operations should be logical retrieval operations while WebInvoke represents HTTP invocation methods i.e. POST, PUT, DELETE. Both of these attributes accept the UriTemplate.

For example, FriendsTimeline service operation from above requires user to be passed in. Template below shows how to configure URL to use the passed in variable.

image 

Problems and solutions

Issuing first call to the service I was presented with immediate problem.

DataContract serializer and arrays

First obstacle was trying to figure out how to map the array of elements coming from the Twitter. Calling FriendsTimeline method returns this response:

<?xml version="1.0" encoding="UTF-8"?>
<statuses type="array">
    <status>
        <created_at>Sat Jun 21 01:27:49 +0000 2008</created_at>
        <id>839961831</id>
        <text>hello</text>
        <source>web</source>
        <truncated>false</truncated>
        <in_reply_to_status_id></in_reply_to_status_id>
        <in_reply_to_user_id></in_reply_to_user_id>
        <favorited>false</favorited>
        <user>
            <id>15161276</id>
            <name>[user name]</name>
            <screen_name>[screen_name]</screen_name>
            <location></location>
            <description></description>
            <profile_image_url>http://static.twitter.com/images/default_profile_normal.png</profile_image_url>
            <url></url>
        </user>
    </status>
</statuses>

I wanted to use DataContract serializer (keeping with out of the box spirit). This provided to be very easy to do. Just inherit from List<T>. ItemName refers to another type that serializer will use to create instances of the items contained in the list.

namespace Vertigo.WCF.TwitterClient.API
{
    [CollectionDataContract(Name = "statuses", ItemName = "status", Namespace = "")]
    public class Statuses : List<Status>, IResponseErrorProvider
    {
        public ResponseError ServiceError { get; set; }
    }
}

Here you also have a hint of how I am going to handle errors returned by the service.

Returning XML fragments

Calling an API method VerifyCredentials returns just this XML fragment:

<authorized>true</authorized>

I could not find a way to de-serialize this response into an instance using plain classes and DataContractSerializer. I resorted to implement IXmlSerializable and handle this problem my self (detailed exception checking not included, this is just a demo).

namespace Vertigo.WCF.TwitterClient.API.Helpers
{
    [Serializable]
    public class BooleanResponseWrapperBase : IXmlSerializable
    {
        public bool Test { get; set; }

        #region IXmlSerializable Members

        public System.Xml.Schema.XmlSchema GetSchema()
        {
            return null;
        }

        public void ReadXml(System.Xml.XmlReader reader)
        {
            reader.MoveToContent();
            reader.Read();
            Test = reader.ReadContentAsBoolean();
        }

        public void WriteXml(System.Xml.XmlWriter writer)
        {
            //noop
        }

        #endregion
    }
}

Now I can add a wrapper class for the authorized response like this:

[Serializable]
[XmlRoot("authorized")]
public class VerifyCredentialsResponseWrapper : BooleanResponseWrapperBase
{
}

WCF has many extension points and I was considering using the MessageContract to solve this problem but MessageContract still required to have well formed XML coming from the service. It would have been better if service responded with proper type encapsulation:

<Verication>
    <authorized>true</authorized>
</Verification>

This could be then easily mapped to

public class Verification
{
    public bool Authorized { get; set; }
}

and DataContractSerializer would be happy.

Handling HTTP 403 status

Well this was an interesting wrinkle. When service encounters an error, for example you try to add non existing user as your friend, service will return 403 status code and send you XML payload with error. Using Microsoft Network Monitor here is the response from the server:

Frame: 
Ethernet: Etype = Internet IP (IPv4)
Ipv4: Next Protocol = TCP, Packet ID = 701, Total IP Length = 929
Tcp: Flags=...PA..., SrcPort=HTTP(80), DstPort=60739, Len=889, Seq=1638460779 - 1638461668, Ack=441960162, Win=64838 (scale factor not found)
Http: Response, HTTP/1.1, Status Code = 403
- Response: 
   ProtocolVersion: HTTP/1.1
   StatusCode: 403, Forbidden
   Reason: Forbidden
   Via:  1.1 twitter-web016.twitter.com, 1.1 ISA
   Connection:  Keep-Alive
   Proxy-Connection:  Keep-Alive
   ContentLength:  169
   Expires:  Mon, 23 Jun 2008 21:07:10 GMT
   Date:  Mon, 23 Jun 2008 20:37:10 GMT
   ContentType:  application/xml; charset=utf-8
   Server:  hi
   Status:  403 Forbidden
   P3P:  CP="NOI DSP COR NID ADMa OPTa OUR NOR"
   X-Runtime:  0.00992
   Cache-Control:  no-cache, max-age=1800
   Set-Cookie:  lang=; path=/
   Set-Cookie:  _twitter_sess=BAh7CDoJdXNlcmkDvFfnOgdpZCIlNDg4OGMyM2Y2MjI4NDEyMzVlNGNiMTNi%250AYTUyNTQzN2YiCmZsYXNoSUM6J0FjdGlvbkNvbnRyb2xsZXI6OkZsYXNoOjpG%250AbGFzaEhhc2h7AAY6CkB1c2VkewA%253D--f8a906186ec107cbb92d6dfda23050b11aebff78; domain=.twitter.com; path=
   Vary:  Accept-Encoding
   HeaderEnd: CRLF
- payload: HttpContentType =  application/xml; charset=utf-8
 - XmlPayload: 
    <?xml version="1.0" encoding="UTF-8"?>
  - <hash>
   - <error>
      Could not follow user: User not found.
      </error>
   - <request>
      /friendships/create/petarvucetin1.xml
      </request>
     </hash>

Of course this did not sit well with the WCF infrastructure. WCF was throwing an exception

System.ServiceModel.Security.MessageSecurityException was unhandled
  Message="The HTTP request was forbidden with client authentication scheme 'Basic'."
  Source="mscorlib"
  StackTrace:
  InnerException: System.Net.WebException
       Message="The remote server returned an error: (403) Forbidden."

Which is correct response. So how do I fool the WCF and let me handle this error? WCF channel extensibility, of course!

WCF Channel, Operation and Message Customization

I need some way to intercept the exception on the transport level, handle it and then re-shape the message in such a way that it can be de-serialized by DCS (DataContractSerializer). This is where I started from Nicholas Allen - ReplyMangler Channel.

If you remember our client configuration looked something like this:

   1: <client>
   2:     <endpoint 
   3:         address="http://twitter.com" 
   4:         binding="customBinding" 
   5:         contract="ITwitterClient" 
   6:         
   7:         behaviorConfiguration="WebGet"
   8:         bindingConfiguration="TwitterBinding"
   9:         
  10:         name="TwitterClient" />
  11: </client>

We are using a custom binding specified by bindingConfiguration attribute (line #8).

<bindings>
    <customBinding>
        <binding name="TwitterBinding">
            <webMessageEncoding />
            <WebReqestExceptionsInterceptor />
            <httpTransport manualAddressing="true" authenticationScheme="Basic" />
        </binding>
    </customBinding>
</bindings>

Custom binding is actually real binding in WCF BCL. This binding allows you to configure your channel stack any way you want. The only requirement is that you have at least one transport protocol and message encoding protocol.

image

If you would to crack open WebHttpBinding with reflector you would see that  it contains two binding elements

image

I have added new custom binding element WebRequestExceptionInterceptor and registered it with WCF inside the config file.

image

image

Callout A shows my custom element inserted between the message encoder and transport. Callout B shows how to register your own custom binding element  extension.

The important thing to note is that order of binding elements does matter. There is a lot of plumbing code for putting this in place so here is the most important part.

image

Callout A shows the capture of the inner channel exception. When exception is thrown we need to create new response message. To the response message we need to add HttpResponse property. I also insert new property that someone else can use to test if we have "fixed" up the message (callout B).

Now that this is done something needs to handle this message on operation level. This is where we add MessageFixer operation behavior.

Modifying operation behavior

The final thing in our chain of changes is converting the message to something that DataContractSerializer can understand. The simplest way to do this is to modify the operation behavior.

/// <summary>
/// Befriends the user specified in the ID parameter as the authenticating user.  Returns the befriended user in the requested format when successful.  Returns a string describing the failure condition when unsuccessful.
/// </summary>
/// <param name="user"></param>
/// <returns></returns>
[OperationContract]
[MessageFixer]
[WebInvoke(UriTemplate = TwitterURITemplates.Friendship.Create, BodyStyle = WebMessageBodyStyle.WrappedRequest, RequestFormat = WebMessageFormat.Xml, ResponseFormat = WebMessageFormat.Xml)]
User AddFriend(string user);

I have created MessageFixer who's job is to inspect the message and fix it when we get an null response or 403 protocol exception. The way message fixer works is by overriding the message formatter for this operation. We hook into the operation behavior when ApplyClientBehvior is called.

namespace Vertigo.WCF.TwitterClient.Customizations
{
    [AttributeUsage(AttributeTargets.Method)]
    public class MessageFixer : Attribute, IOperationBehavior, IClientMessageFormatter
    {
        #region const
        private const string NullMessage = "nil-classes";
        private const string ErrorMessage = "hash";
        private const string ResponseErrorKey = "Service403Response";
        #endregion

        #region fields
        IClientMessageFormatter _formatter;
        Type _return;
        #endregion

        #region IOperationBehavior Members

        public void AddBindingParameters(OperationDescription operationDescription, BindingParameterCollection bindingParameters)
        {
            
        }

        public void ApplyClientBehavior(OperationDescription operationDescription, ClientOperation clientOperation)
        {
            MessageDescription md = operationDescription.Messages.First( m => m.Direction == MessageDirection.Output);
            _return = md.Body.ReturnValue.Type;
            _formatter = clientOperation.Formatter;
            clientOperation.Formatter = this;
        }

First we remember the original formatter and then insert MessageFixer as new client formatter.

#region IClientMessageFormatter Members

public object DeserializeReply(Message message, object[] parameters)
{
    object helperInstance = Activator.CreateInstance(_return);

    //we have special condition where service sets Http response code to 403 that signals that an error has occured 
    KeyValuePair<string,object> serviceErrorProperty = message.Properties.FirstOrDefault(p => p.Key == ResponseErrorKey);
    if (serviceErrorProperty.Key != null)
    {
        //we have an error message
        IResponseErrorProvider responseErrorProvider = helperInstance as IResponseErrorProvider;
        if (responseErrorProvider != null)
        {
            //unpack the error payload from message and assign to the object
            ResponseError payload = message.GetBody<ResponseError>();
            responseErrorProvider.ServiceError = payload;

            //return fixed null type with error attached to it
            return helperInstance;
        }
    }

    //another message we might get is <nil-classes type="array"/> for empty arrays.
    XmlDictionaryReader xdr = message.GetReaderAtBodyContents();
    xdr.MoveToContent();
    
    if (xdr.Name == NullMessage)
    {
        return helperInstance; //standin for the null value
    }

    return _formatter.DeserializeReply(message, parameters);
}

public Message SerializeRequest(MessageVersion messageVersion, object[] parameters)
{
    return _formatter.SerializeRequest(messageVersion, parameters);
}

#endregion

For request serialization we just use the original formatter. When we get request to deserialize the message this is where we need to do the message fixing. If message properties contain our custom service error property and the type supports error assignment via IResponseErrorProvider we can use message GetBody<T> to deserialize the payload to an instance type and assign this error instance to the return type.

I had an option to raise the exception from the channel when service reported an error. The reason I did not go with this route is that raising exception would fault the channel and it would not be usable. Another reason is that I am not sure how client should behave (at this time) when service raises an error.

In case of the null message, that is the message contains <nill-classes> element we just return helper instance of the type we need to de-serialize.

UriTemplate and Enum method parameters

When using URI templates there is no way to dictate how "serialization" of the parameter is performed when substituting it in URI template. For example update delivery device URI template accepts an enumeration of devices in its template:

public const string UpdateDeliveryDevice = "/account/update_delivery_device.xml?device={device}";

Service is expecting the name of the device to be all lower case for example:

http://www.twitter.com/account/update_delivery_device.xml?device=sms

[OperationContract]
[WebInvoke(UriTemplate = TwitterURITemplates.Account.UpdateDeliveryDevice, BodyStyle = WebMessageBodyStyle.Bare, RequestFormat = WebMessageFormat.Xml, ResponseFormat = WebMessageFormat.Xml)]
void UpdateDeliveryDevice(Devices device);

When URI template is constructed, value of the parameter is extracted by calling the ToString() of the type. It would have been nice if there was a way to control this behavior either through XmlEnum or TypeConverter. Instead I had to create enum that matched exactly what service is expecting!

//There is no simple way to control how WCF uri template
// is serialized withouth super heavy lifting. The service uses lower case names and there is no
// easy way to convert from proper case to lower case when WCF is constructing the URL for the call.
public enum Devices 
{
    none,
    im,
    sms
}
DebuggerDisplay

Do provide this very usefully attribute to your classes for easier debugging like so:

[DataContract(Name = "user", Namespace = "")]
[System.Diagnostics.DebuggerDisplay("Name = {Name}, ScreenName = {ScreenName}")]
public class User : IResponseErrorProvider
{
    [DataMember(Name="id", Order = 0)]
    public string ID { get; set; }

Conclusion

I am in no position to criticize the Twitter API but I must say that API designers did not follow some basic rules when creating the public API. I whish that API designers pay more attention to client usability issues when creating new APIs. For example:

  1. Publish your API documentation near your web site, for example  http://twitter.com/Api
  2. Keep your API documentation and examples up to date
  3. If you have decided to publish the API please make sure you provide working examples or at least detailed documentation on request and response formats
  4. Document VERY clearly what each operation input and output should look like with example for each input parameter if there are many.
  5. Don't skimp on explaining the details of how do you handle service errors, logic errors, system errors.
  6. Avoid using protocol status codes to signal service exceptions
  7. Avoid returning generic null type. It would have been much easier for consumer of the service if service would just return the intended type with no data i.e. <Statuses />
  8. Dog food your API :)

Source Code

Source code is here.

Petar

I was once attendee at TechEd

My first TechEd was in 2007. I had so much fun and the sessions were awesome. This is the time I met with Mike Hanley from Vertigo. Now I work for Vertigo and guess what...

IMG_0529

Now I am a speaker!! Thanks to Juval of IDesign for recommending me for the talk!

image

Topic:  Building Secure Web Services Using Windows Communication Foundation

Summary:

Securing messages between clients and services is essential to protecting data. The Windows Communication Foundation (WCF) provides a versatile and interoperable platform for exchanging secure messages based upon both the existing security infrastructure and the recognized security standards for SOAP messages. In this session learn how to use WCF for transfer security and access control using familiar technologies such as HTTPS, Windows integrated security, X.509 certificates, SAML, and usernames and passwords, and also new technologies such as Windows CardSpace. This session also discusses how to extend WCF security to support custom security tokens, custom authentication methods, claims-based authorization, claims transformation, and custom principals.

75 minutes of pure WCF goodness!

Petar.

Still alive after slowing down!

So I lived! Driving 55 mph was not that bad. I finally ran out of gas last Friday and had to tank up. At $3.98 I was happy that my car did 448 miles on 15 gallons!!

IMAGE_044IMAGE_043

IMAGE_048

The strange thing is that my car mpgs went down as I was approaching the empty tank. So the final mpgs deteriorated by 1 gal (3.2%) which I am not sure why.

I am better in handling the stares of the motorists as the pass me by even as I am driving in far right lane. I did fail few times in the city to observe my restraint as I had to move quickly to avoid potentially dangerous situation.

One thing to note, when you have friends in the car it's VERY hard to drive slow, for some reason I feel like I am wasting their time...

I think I will continue with the experiment and see what happens...

Petar

Slowing Down

...not because I am getting old :-) but because I wanted to conduct a little experiment. I decided to not exceed 55 miles per hour (90 km/h) on any highway where the legal speed limit was greater than 55 mph. This is my 5th day into the experiment and the results are interesting so far...

I would not lie to you; my main motivation is the cost of gas, which in San Francisco is already exceeding $4 per gallon! I wanted to change my driving profile and see if it would impact my mileage (read my wallet), my time management (will I be late everywhere?) and if I would succumb to pressure by other motorists to drive faster...

I drive a hybrid SULEV (Super Ultra Low Emission Vehicle) with EPA MPG estimates of 31 City and 27 Highway (Source: California Air Resource Board).

clip_image002

To get the numbers above EPA test assumptions are:

    • Very slow acceleration
    • Straight, level roads
    • Air-conditioning is turned off
    • 18% idle time for city test
    • 0 idle time for highway test
    • Average speed of 20 mph for city test (top speed 56 mph)
    • Average speed of 48 mph for highway test (top speed of 60 mph)

Of course we can debate how realistic these assumptions and estimates are but its a good start...

I have been observing my car fuel consumption for a while using my cool built in Energy Monitor thingamajig (thanks T!). Every time I refuel I reset my consumption tracking and begin observing my fuel management as I drive through various driving and road conditions.

image

In the last 5 days I was driving conservatively (by EPA standards sans #2) and at/or under 55 mph. If I plot all my gas consumption observations over last two years and last 5 days this what it looks like:

image

For a while I was driving conservatively (27.4 mpg) but my speed was always at the maximum allowable speed limit. The difference between the last two numbers is what my experiment was all about. I was able to coax roughly 14% more miles if I drive conservatively AND do NOT EXCEED the maximum speed of 55 mph!

Is there a dollar value of this behavior change? If you drive average of 12,000 miles a year with average consumption of 31 mpg than I would consume about 387 gallons of gas every year. The cost of 387 gallons is $1,550 a year if it stays at $4! At 27.4 the cost is roughly $1750.

Is $200 a year worth it? Yes, if I am not alone!

image

Since the start of my experiment majority of motorists will pass me on the left and than proceed to shake their head and give me that what-is-wrong-with-you look.I am always trying to be in as far right lane as I could without endangering my self or other motorists.

These 5 days of experimenting have been pretty harsh psychologically. It was not easy to keep your speed 55 mph and watch in your rear view mirror 18 wheeler truck barreling down the highway right at you.  The pressure to drive faster is HUGE! I am kind of a big guy and don't get intimidated easily but I was feeling it!

So far I have not been late to anything yet but I am more be-on-time kind of person so I make sure I have ample time before I leave.

speed%20limit.jpg

US National Maximum Speed Law was created 1974 as part of Emergency Highway Energy Conservation Act which capped all speed limits at 55 mph (90 km/h). Do you think this will happen again?

  image

I am continuing to run my experiment and see what happens. You think you can drive 55?

Petar

 

  del.icio.us it! digg it! dotnetkicks it!