Posts tagged WCF

Five Things to Know About the WCF Runtime

Since working with WCF I have gleaned quite a bit about how the runtime works through reading various blogs and writing proofs-of-concept/experiments.  One thing that has become apparent to me is that many people working with WCF do not fully understand how it works because Visual Studio makes it very easy to create & consume WCF services.  In most cases there is no need to understand the “guts” of WCF, but you may reach a point where you want to extend WCF.  Here are five things that will help you know where to begin your quest for extension.

.Svc file are the activators that kick off the WCF runtime.  In IIS or WAS, .Svc files are what activates a service host which in turn creates a service host and calls your service.  The .Svc file specifies the full name of your class and an optional service host factory.  If you are self-hosting a service you are responsible for implementing the same functionality in code.

ServiceHosts control your service instances and dispatch calls to your service using ChannelDispatchers.  The ServiceHost is the central actor and you can control a lot of behavior by altering the service host or extending it.  If you want to use an Inversion of Control container with WCF the best place to stick it is on a custom ServiceHost.  The service host also maintains listeners that enable your service to receive calls over the wire at the specified endpoint (e.g., http://mydomain.com/services/myservice.svc). 

ServiceHostFactory creates a ServiceHost.  If you want to create a custom service host you’ll need a ServiceHostFactory to return an instance of your service host to the WCF runtime.

Everything can be done through configuration or code.  I used to be a huge configuration fan, but after dealing with WCF configuration in .NET 3.5 it can get hairy, especially when you have dozens of services.  Favor code where you can and save configuration for the stuff that could really change.  WCF in .NET 4 has far less configuration, especially in development (which is good because the last thing you want to fight is configuration problems during development of your service).

By default service instances are created per call.  This is typically OK and helps you avoid most threading problems.  Try to avoid creating expensive objects within your services constructor or any of its dependencies as this could delay your services response time.  You can change this using the InstanceContextMode on your service class. Tip: If you are using a container to resolve service instances then you need to remove the InstanceContextMode attribute and let the container manage instances.

(Bonus, a 6th thing to know!) WCF has many extension points, the biggest one being behaviors.  Behaviors allow you to control how the service executes at runtime.  This applies to anything from instancing to message inspection, and much more.  Here are a few posts to get you started:

Put Up your Shields: Shielding Exceptions in WCF Services

When using services an important best practice is to keep details of exceptions from leaking beyond the service boundary.  Letting such details out of the boundary could create unnecessary coupling between the service callers and the service and would expose internal details of the service that you may wish to keep hidden.

Microsoft Patterns & Practices Enterprise Library (EL) provides an extension to the Exception Handling Application Block that hooks directly into WCF to provide the capability to replace service exceptions with custom faults.

Configuring Shielding

Exception shielding requires you to configure a Exception Handling Application Block with an exception policy.  The policy consists of the exceptions you want to handle and a post-handling action for each exception.  To work with the WCF Exception Shielding you need to set each exceptions post-handling action to ThrowNewException.

image

Once you have your basic policy set up you need to add a Fault Contract Exception Handler to each exception in your policy.

image

You can map properties from the exception thrown to the Fault you return.  This is set up in the PropertyMapping as the following screenshot indicates.  Source represents the source property on the Exception and Name is the property name on your fault to map to the source.  In this case the WidgetNotFoundException has a “Message” property which we will map to the “Details” property on our WidgetNotFoundFault.

image

Lastly, you need to mark your Service Class with the ExceptionShielding Attribute and give it the name of your exception policy.

image

Once everything is wired up you can test the service to see your exceptions get replaced by the fault contract types. 

A Quick Integration Test

When I fired up the service in Visual Studio 2010 and used the WCF Test Client, I ran a quick test to find a widget with the name of “Whatzit”.  The service had something to say about that request:

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
  <s:Header />
  <s:Body>
    <s:Fault>
      <faultcode>s:Client</faultcode>
      <faultstring xml:lang="en-US">Widget Whatzit not found!</faultstring>
      <detail>
        <WidgetNotFoundFault           xmlns="http://schemas.datacontract.org/2004/07/ExceptionShieldingService2"
          xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
          <Details>Widget Whatzit not found!</Details>
        </WidgetNotFoundFault>
      </detail>
    </s:Fault>
  </s:Body>
</s:Envelope>

You can also test this using something like MSTest and decorating your integration test with [ExcpectedException(typeof(FaultContract<MyServiceReference.MyFaultType>)].  Just point the FaultContract<TDetail> to the type from your ServiceReference.  You can’t test fault contracts (to my knowledge) by calling the service imlementation class directly, you’ll need to do this by adding a service reference and calling the service that way.

Tips & Common Errors

After setting up a few of these I have run into some configuration problems which seem to be the most common issue hit with any of the EL blocks.

  • Use the Enterprise Library “Load from assembly” option to select your Exception and Fault Contract types.  EL seems particularly sensitive to using the fully-qualified assembly name including version & public key token.
  • Turn on some type of logging while testing your policy.  This will help you troubleshoot problems with the policy (mismatched types, etc).
  • “The current build operation (…) failed: Value cannot be null” Parameter name: faultContractType – This error stems from EL not being able to resolve your Fault Contract Type.  This is typically due to a bad mapping of your Fault Contract Type.  Check the Type Name, Assembly and version info to make sure it is correct.  Your best bet is to use the EL Config Editor to browse and select your fault type.

What Do You Call It? Naming WCF Operations & Messages

WCF is a great addition to the .NET framework.  Like all parts of the framework it introduces a lot of new concepts to learn.  Sometimes it’s hard to separate those technical concepts from the decisions like, “What is the best way to architect this service” or “How should I name things?”

Simon Segal, a fellow .NET and SOA junkie posted back in November about how he names operations and messages within WCF and the nServiceBus framework (an open-source Enterprise Service Bus).  Simon, like I do, follows a convention of naming in relation to the business events the operations and messages represent.

When it comes to naming operations we not only imply some intent of the operation we also imply what data might be needed.  When designing services that are more coarsely grained you often run into issues with what data is really required for the service to perform its work.  Simon linked to an article from Thomas Erl, a respected authority on SOA, in which Thomas made the following statement (my emphasis):

Although it is practical and extensible, the use of optional parameters should be limited within Web services. Optional parameters can lead to convoluted service interface designs and a myriad of confusing data exchange scenarios. Additionally, the extent to which optional values can be accommodated is often limited by the underlying XML schemas that define the message structures. Standardized schemas that represent established corporate documents may impose rigid data structures.

Coming from the NIEM world I often emphasized that data exchanges only need 80% of what we think is needed.  There were times when people would want to exchange flags or indicators that could be derived from other fields or were not necessarily needed at all.  Any time we strayed away from the 80% the services became more difficult to consume and maintain.

Let’s Look at An Example

Factoring all of this in, let’s consider an example of how we might name service operations and messages.

Definitions:
Service Operation – A method you call on a service. 
Message – An input/output of a call to a service operation.
Message Parts – Data elements that are included in the message.

Problem: You need to name messages and service operations for a service that will allow customers to place orders for widgets.  This service should also allow orders to be cancelled.  Orders consist of a unique ID, a customer Id, and widgets. 

Request/Response example:

  • Service Operation PlaceWidgetOrder, Message: PlaceWidgetOrderRequest, Message Parts: WidgetOrder (Id, Customer Id, Widgets[] (or WidgetCollection))
  • Service Operation CancelWidgetOrder, Message: CancelWidgetOrderRequest, Message Parts: OrderId

Event-Driven example:

  • Service Operation: CustomerPlacedWidgetOrder, Message: CustomerPlacedWidgetOrderMessage, Message Parts: same as request/response example
  • Service Operation: CustomerCancelledWidgetOrder, Message: CustomerCancelledWidgetOrderMessage, Message Parts: same as request/response example

Notice the difference between the two styles.  In the event-driven style we talk about something that has happened (or is happening) and in the Request/Response style we talk in terms of what we want to do.  Each style has it’s merit and the style you choose will depend on the situation and the maturity of the partners involved in the service collaboration/data exchange.

Also notice that the event-driven example does not imply any type of response to the operation.  Typically event-driven systems will be asynchronously designed and the service operations will reflect that.

Why Messages?

Messages allow us to encapsulate the data needed for the domain as well as data we may need because of technical requirements.  Technical requirements may dictate that we have to log messages or protect messages in other ways (which could require message IDs, encryption keys, etc).  By encapsulating data in a message we also leave room to include the technical requirements within the same message and keep our domain model free of technical bits that aren’t really part of the domain.

How do you name your service operations and messages?

Simon and I would love to hear.  Leave a comment or tweet it!

WCF Test Client in VS 2010

The other day I fired up a WCF service for the “Take Control of Messages” post and to my surprise a test client opened up which felt very similar to SoapUI.

Loading & Adding the service reference (happens auto-magically)

image

Double-clicking on a service operation brings up the test form.

image 

Fill out the data elements and press invoke to test the service.

image

The client was also able to support when I transitioned to a message contract. 

image

After selecting the type, you can then expand the element to view it’s members.

image

This is a great addition to VS and will greatly help testing services!

Take Control of Messages in WCF

With WCF you can control many aspects of how service behave and how you interact with them.  Let’s take a look at Data & Message Contracts and how each behaves on the wire.

Data Contracts – The Basics

Data contracts are the default method for serializing in WCF.  To leverage data contracts you simply markup the classes you wish to expose from the service with the DataContractAttribute.  The data contract serializer does not support all the features of Xml Serialization which yields some performance boosts.  However, the data contract serializer has some default behaviors which may not suit your needs.

The Contract

 [DataContract]
    public class CompositeType
    {
        bool boolValue = true;
        string stringValue = "Hello ";

        [DataMember]
        public bool BoolValue
        {
            get { return boolValue; }
            set { boolValue = value; }
        }

        [DataMember]
        public string StringValue
        {
            get { return stringValue; }
            set { stringValue = value; }
        }
    }

The SOAP Message

Request (Showing soap:body only)

<s:Body>
<GetDataUsingDataContract xmlns="http://tempuri.org/">
<composite xmlns:a="http://schemas.datacontract.org/2004/07/ContractExamples" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<a:BoolValue>true</a:BoolValue>
<a:StringValue>Hello Service!</a:StringValue>
</composite>
</GetDataUsingDataContract>
</s:Body>

Response

<s:Body>
<GetDataUsingDataContractResponse xmlns="http://tempuri.org/">
<GetDataUsingDataContractResult xmlns:a="http://schemas.datacontract.org/2004/07/ContractExamples" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<a:BoolValue>true</a:BoolValue>
<a:StringValue>Hello Service!Suffix</a:StringValue>
</GetDataUsingDataContractResult>
</GetDataUsingDataContractResponse>
</s:Body>

With the data contract, notice how our messages are actually wrapped in an outer element in the Xml.  For the request, the CompositeType is wrapped in a “GetDataUsingDataContract” element which is derived from the operation name.  The response is where it is interesting, our message is actually double wrapped. 

How do we change this default behavior?  Enter Message Contracts.

Message Contracts – For Control Freaks

Message contracts are another way to work with WCF to take more control of how the messages are serialized in the SOAP envelope.  These can be a key strategy to creating services that can support better interoperability with other stacks such as Java.  You define message contracts with the MessageContractAttribute.

The Message Contract

     [MessageContract(IsWrapped=true, WrapperNamespace=http://christopherDeweese.com/WCF/Examples)]
    public class CompositeTypeRequest
    {
        [MessageBodyMember]
        public CompositeType CompositeData { get; set; }
    }

    [MessageContract(IsWrapped=true, WrapperNamespace=http://christopherDeweese.com/WCF/Examples)]
    public class CompositeTypeResponse
    {
        [MessageBodyMember]
        public CompositeType CompositeData { get; set; }
    }

Here we have defined a request and a response message which contains our CompositeType.  What result does this yield?

The SOAP Message

Request

<s:Body>
<CompositeTypeRequest xmlns="http://christopherDeweese.com/WCF/Examples">
<CompositeData xmlns="http://tempuri.org/" xmlns:a="http://schemas.datacontract.org/2004/07/ContractExamples" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<a:BoolValue>true</a:BoolValue>
<a:StringValue>Hello Service with messages! </a:StringValue>
</CompositeData>
</CompositeTypeRequest>
</s:Body>

Response

<s:Body>
<CompositeTypeResponse xmlns="http://christopherDeweese.com/WCF/Examples">
<CompositeData xmlns="http://tempuri.org/" xmlns:a="http://schemas.datacontract.org/2004/07/ContractExamples" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<a:BoolValue>true</a:BoolValue>
<a:StringValue>Hello Service with messages! Suffix</a:StringValue>
</CompositeData>
</CompositeTypeResponse>
</s:Body>

A Little ‘Philosophy’

In past posts on services I’ve discussed the opinion that you interact with services through messages.  Encapsulating inputs and outputs to the service using messages allows for a clearer semantic representation of the what the capabilities the service provides access to.

Using Message contracts in WCF lets you explicitly control how the messages are serialized and allows you to build services from canonical data models created in raw Xml.  This also provides the greatest interoperability and you don’t have to deal with the default behaviors of the data contract serializer.

Final Thought

You may not always need this type of control.  For instance if your service is only being consumed by other .NET clients the messages may not be that important to you.  But if you are designing services for an Enterprise SOA, then message contracts will be a great help.

NIEM Q&A – When to Use, Why, and Tips to Get Started

Every month or so I receive questions about using NIEM in projects.  The questions typically have the same theme, so I thought I would write up a quick post summarizing the questions I get most often and some answers to get you started.

Should I use NIEM in my project?

Do you need a single, canonical data model for exchanging data between systems?  Do you have control of the systems you are integrating?  Do you have an existing data model used within your systems?  Is NIEM a requirement for your project/grant/contract?

If you answer ‘Yes’ to any of these questions then you may consider using NIEM.  NIEM is best used where it will have the most benefit – describing exchanges of information between organizations & systems, harmonizing the language we use to talk to each other (i.e., Organization instead of Agency, Sur Name instead of Last Name), and defining requirements at the data exchange level.  NIEM is not a one-size-fits-all tool and you will not get maximum ROI unless you have a strong use case for it and implement it properly.

Should I use NIEM for my database schema?

The short answer is probably not.

NIEM is an Xml data model and it’s best use is describing the data elements exchanged between systems.  If you need to send data from System X to System Y then NIEM is a good candidate for doing this.  You can define the elements you need to exchange and then build a NIEM IEPD to define the exchange.  Using NIEM as a database schema does not always yield the best results.  In most cases you are better off storing the data in an optimized way for your database platform and using adapters to translate data from the DB into NIEM.

How do I add new fields to NIEM?

In response to this question I would pose a different one – why do you need to add the fields?  Can you derive them from other fields in the exchange?  In most cases the 80% NIEM has built in will get you what you want.  Fields like row-level timestamps or system specific ones may not be necessary and I would tactfully question those.  If you find that you must add a field the best route to take is to define an extension schema in a custom namespace and add the fields there.  Try to derive from base NIEM fields. For example, if you need to add a field to OrganizationType then derive your new type from OrganizationType and add the necessary elements.

Avoid adding the field and not specifying it in the schema properly.  The pitfalls of doing so may not happen immediately but eventually one will and you’ll thank me for warning you.

I would question why you need to add fields as long as possible without delaying your implementation and deployment.  In most cases you really don’t need the fields.

Can I use [Name_of_IEPD] for my project?

It depends.  Does it have what you need?  Are you ok reusing someone else’s work (one of the benefits of NIEM!), then yes.  Sometimes existing IEPDs will be a good fit and get you the 80% or more.  Other times the perspective may be vastly different from yours.  You can certainly propose the use of an existing IEPD and have your business analysts and other technical staff review to see if it is a good fit.

The key to success with NIEM is that it brings together the business and technical teams involved in the exchange. If a particular IEPD is not able to bridge those gaps you may need to create your own.  As NIEM adoption grows, more IEPDs are becoming available and many of them are coming from national groups that are looking at how things are done across the country to find the best 80% that fits most cases.

Getting Started with NIEM – Quick Tips

  • Build a dictionary of the data you have or would like to have
  • Search IEPDs to find one that matches your needs
  • Map your data elements to the elements in the IEPD
  • Store the data in a manner that makes sense for your database platform
  • Translate your data from its source into NIEM and vice-versa
  • Shoot for the 80% because in most cases that is what is really needed

More information about NIEM

  • NIEM.gov – official NIEM Site
  • LEXS.gov – DOJ Logical Entity eXchange IEPDs

For those of you working in the .NET Space check out my previous articles on NIEM + .Net

Inverting Control in WCF – Follow Up

The code from “Inverting Control in WCF” has been posted to Codeplex here.  Feel free to ping me with questions on Twitter or through this blog!

Thanks to all who attended and a big thanks to Alvin Ashcraft for hosting and to all the other organizers & sponsors!

Webcast: Inverting Control in WCF – 11/20/2009 1:30 CST

I will be presenting “Inverting Control in WCF” for #notatpdc in a live webcast tomorrow.  If you have time, join us on for this live meeting! 

“WCF provides many extension points and in this session Chris will cover how to wire up an Inversion of Control container into the WCF stack. Chris will discuss behaviors, instance providers, and the architecture of WCF in order to illustrate the best way to invert control in your services. “

Details here.

Visual Studio/.NET/WCF/LINQ and NIEM Tips

Over the years while working with .NET and NIEM I’ve run into a few kinks that require a setting tweak or an extra step to get it to work. 

.NET General

Choices for working with NIEM Xml (From the .NET Base class library.  There are third-party tools out there to assist as well):

Linq

  • System.Xml.Linq.XDocument, XElement, et. al. are not Serializable.  You cannot accept them as an input or return them as an output from services (Web/Sockets/Queues/etc) or any place that will attempt serialize them.
  • With Linq to Xml using XDocument or XElement changes the axis for your query.  If you parse a string to an XDocument your query starts at the root node.  If you parse a string into XElement your query starts from the first element in the Xml and not at the root.  Typically this isn’t a major hassle but the problem is that you may not notice it until you actually try a query at run time and do not get the results you expect. (See also Unit Testing!)

WCF

  • MaxReceivedMessageSize and MaxStringContentLength will be your enemies.  Every service you write, you will want to change those values from the default 65536 otherwise callers to your service will get a nice Fault Exception when they send you a message larger than that.
  • MaxItemsInObjectGraph will need to be adjusted if you are going to be serializing large objects using direct serialization or you try to return a very large list or array of objects.
  • MaxArrayLength should be adjusted in conjunction with MaxItemsInObjectGraph.  Typically you’ll need to adjust both.  You’ll use arrays more if you do any interop work between .NET and other technology stacks as Arrays are typically safer for Xml serialization.
  • For interop scenarios your best bets are to stay with simple data types supported by Xml Schema (Xsd): String, Date, Integer, and arrays thereof.  Adding specific .NET types like GUID, List<T>, etc will add additional schemas to your service contract and may cause issues with other technology stacks.
  • Data Contract Serialization (the default) gives you less control over your Xml messages.  Xml Serialization gives you fine grain control and is usually a better fit for working with NIEM in WCF.

Visual Studio

  • Visual Studio solutions only allow an Xml Namespace to be defined once.  If you try to import two XSDs that define the same namespace you will not be able to leverage the Xml Intellisense and document validations provided by the Xml parser in Visual studio.  This really comes into play if you attempt to import LEXS digest and payload schemas in the same solution.
  • Typically I would create a project in a VS Solution just for Xml Schemas.  You can use a class library and it is not necessary to reference it from other projects.  Schemas are used at the solution level, even when the schemas are in a project.
  • While navigating an Xml document if you type an opening bracket, select an Xml element, and press tab twice studio will create an Xml fragment with all the required elements.

These are certainly not all the tips, but its a start.  Feel free to contact me if you have some to share or have any questions!

WCF: NetMsmqBinding and Non-Transactional Queues

Recently we had a situation where we needed to remove transactions from the equation in a WCF service because we were calling a downstream component that could not support transactions.  The new transaction infrastructure in .NET 2.0 and the use of ambient transactions makes it easy to leverage transactional functionality in your service calls with no real coding required on your part.  By default, using the NetMsmqBinding enables Durable and Exactly once on the binding which implies the use of transactions in the background, and those transactions are applied to any transactional call made including sending to other message queues, database connections, etc.

The new transaction infrastructure leveraged by WCF is great, except when you need to opt out, because the key to getting the result you want is understanding how the different "knobs and switches" (as coined by Juval Lowy) or configuration options on the binding affect each other.  In the case of Durable and Exactly Once you may be lead to believe disabling exactly once will remove transactions if you go solely by the descriptions of each option.  However, you will quickly be notified by the WCF runtime that enabling Durable and disabling ExactlyOnce on the NetMsmqBinding is not supported.

Disabling both Durable and ExactlyOnce on the NetMsmqBinding ultimately removed transactions from the equation and produced the result we expected once we did this on both the client and the service.

The other key is how we ultimately found the correct way to do this.  Once we changed the queue to non-transactional the symptom we saw was that our message we were sending kept ending up in the system wide Transactional Dead-Letter queue.  There was no error message or exception logged by our service because the message never got there.  A little research and a couple tests and we arrived at our solution.  We could have handled this with an IErrorHandler implementation but at the time we knew what direction to look (transactions were the issue) so we took the manual route.