Click here to Skip to main content
11,920,394 members (48,626 online)
Click here to Skip to main content
Add your own
alternative version


10 bookmarked

Conditional WCF DataContract Serialization (Using DataContractSurrogate)

, 11 Jul 2012 CPOL
Rate this:
Please Sign up or sign in to vote.
How to add conditional DataContract Serialization in a declarative manner.


During the development of Web Services for our system, we wanted to design a common service layer, and common data contracts which would cater to requirements of different role based users. User role distinction was important, because there were some sensitive data points which could be shared only with privileged users. One way to design this was to make the data translators role specific. The translators could ascertain the user role, and serialize the data accordingly. The approach was simple but not elegant, and would have introduced lot of additional role checks in various translators.  

An alternative was to keep the service layer and translators role agnostic, and use a more declarative approach by using Data Contract Surrogates. Data Contract Surrogate is an advanced feature which can be used to introduce special behavior during Data Contracts Serialization\Deserialization.


Let's start by defining an attribute ConditionalDataMemberAttribute. This attribute will be used to decorate DataMembers which need to be conditionally serialized. Usage of this attribute is discussed later. 

[AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = false)]
public class ConditionalDataMemberAttribute : Attribute

Next step is to create a custom Service Behavior called ConditionalDataBehavior.

[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
public class ConditionalDataBehavior : Attribute, IServiceBehavior

In service behavior ConditionalDataBehavior,we override the DataContractSurrogate for each operation with our custom implementation of Data Contract Surrogate   ConditionalDataContractSurrogate

public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
  foreach (ServiceEndpoint ep in serviceHostBase.Description.Endpoints) {
    foreach (OperationDescription od in ep.Contract.Operations) {

private static void ApplyDataContractSurrogate(OperationDescription description)
  var dcsOperationBehavior = description.Behaviors.Find<datacontractserializeroperationbehavior>();
  if (dcsOperationBehavior != null) {
    dcsOperationBehavior.DataContractSurrogate = new ConditionalDataContractSurrogate(dcsOperationBehavior.DataContractSurrogate);

The class ConditionalDataContractSurrogate implements the Interface IDataContractSurrogate. We add our custom implementation to the method GetObjectToSerialize. During serialization this method is called on every object that needs to be serialized. This gives an opportunity to inspect each object before serialization. If the calling context is not authorized (checked inside IsAuthorized) to receive the object, then  we prevent the actual value from being serialized.

public object GetObjectToSerialize(object obj, Type targetType)
  if (obj == null) return null;

  var type = obj.GetType();
    .ForEach(prop => {
      try {
        var attr = prop.GetCustomAttributes(typeof(ConditionalDataMemberAttribute), false);
        if (attr.Any()) {
          var role = ((ConditionalDataMemberAttribute)attr[0]).Role;
          //Is the user authorized
          if (!IsAuthorized(role)) {
            var proptype = prop.PropertyType;
            //Set the property value to its default value
                                       new[] { proptype.IsValueType ? Activator.CreateInstance(proptype) : null });
      } catch { }

  return _baseSerializer != null ? _baseSerializer.GetObjectToSerialize(obj, targetType) : obj;

Using the code  

Step 1:  Decorate your webservice with ConditionalDataBehavior attribute.   

[ServiceBehavior(Namespace = "")]
public class MyWebService

Step 2:  Decorate the Data Contracts with ConditionalDataMember attribute.

public class UserInformation
    public string FirstName { get; set; }
    public string LastName { get; set; }
    [ConditionalDataMember(Role = "Level2")]
    public string Email { get; set; }
    [ConditionalDataMember(Role = "Level2")]
    public string Phone { get; set; }

Step 3: Add your own implementation of IsAuthroized function.

private bool IsAuthorized(string role)
  //Implement your own Authorization check
  // currentUser.Roles.HasDesiredRole
  return true;


//Object Returned by Translator
new UserInformation {
    FirstName = "Joe", 
    LastName = "Doe", 
    Email = "", 
    PhoneNumber = "408000000"
<!-- Data values received by Level 2 user -->
<!-- Data values received by Level 3 user -->


Data Contract Surrogate -


This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


About the Author

Sumit Chawla
Software Developer (Senior)
United States United States
I am currently working as a Senior Software Developer. My primary skills include .NET, WPF,MSSQL,and C++. I have also worked in ASP.NET, XML, XSL, JavaScript,and Web Automation.
I love to solve problems,and love to do programming. In my idle time i love to explore new technologies and domains.

You may also be interested in...

Comments and Discussions

QuestionHow do I apply this to MVC 4 WebApi? Pin
seanxd10-Jul-12 14:16
memberseanxd10-Jul-12 14:16 
AnswerRe: How do I apply this to MVC 4 WebApi? Pin
Sumit Chawla10-Jul-12 19:38
memberSumit Chawla10-Jul-12 19:38 
QuestionDownload missing Pin
Smitha Vijayan9-Jul-12 7:22
staffSmitha Vijayan9-Jul-12 7:22 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web03 | 2.8.151120.1 | Last Updated 11 Jul 2012
Article Copyright 2012 by Sumit Chawla
Everything else Copyright © CodeProject, 1999-2015
Layout: fixed | fluid