WCF 3.5 SP1 allows for circular references without adding any code

April 7, 2009 by · 1 Comment
Filed under: Programming, Software Configuration, WCF 

WCF now provides a way to avoid circular reference problems on serialization, which before required you to initialize the Data Contract Serializer with a KeepReferences setting. Another option was to cheat and use a NetDataContractSerializer which wasn’t easier without cusotm behaviors or special code, now it is as simple as adding an attribute.

 Here is one such exception you may receive if you are having issues:

“Object Graph for Type X Contains Cycles and

Cannot be Serialized if Reference Tracking is Disabled”

 

Example that will work wonders without anything else required.

[DataContract(IsReference = true)]

    public class Person

    {

        [DataMember]

        public string Name

        { get; set; }

       

        [DataMember]

        public string Address

        { get; set; }

 

  [DataMember]

        public List<Person> Children

        { get; set; }

 

    }

Now it works, Another example more appropriate is using eXtensible Access Control Markup Language (XACML)  specification.

[DataContract(IsReference = true)]

    public class PolicySet

    {

        [DataMember]

        public string Name

        { get; set; }

       

 

  [DataMember]

        public List<PolicySet> PolicySets

        { get; set; }

 

  [DataMember]

        public List<PolicySet> ParentPolicySet

        { get; set; }

 

 

    }

[DataContract(IsReference = true)]

    public class Policy

    {

[DataMember]

        public string Name

        { get; set; }

 

        [DataMember]

        public PolicySet ParentPolicySet

        { get; set; }

 

  [DataMember]

        public List<Rule> Rules

        { get; set; }

 

 

    }

[DataContract(IsReference = true)]

    public class Rule

    {

[DataMember]

        public string Name

        { get; set; }

 

        [DataMember]

        public Policy ParentPolicy

        { get; set; }

 

  [DataMember]

        public List<Targets> Targets

       { get; set; }

    }

Serializing types that return interfaces instead of instances in WCF 3.5 SP1

April 7, 2009 by · Leave a Comment
Filed under: Programming, Software Configuration, WCF 

I came across interesting problems with WCF serialization specifically the DataContractSerializer and limitations of the runtime.

Say you have a class like so

[Serializable]

    public class Service

    {

        public IList<Person> People

        {

            get; set;

        }

    }

   

    [Serializable]

    public class Person

    {

        public string Name

        { get; set; }

       

        public string Address

        { get; set; }

    }

 

 

 

 If you try to get this working in a WCF service it won’t work, basically the problem is that you are returning an interface, not a concrete type, and the serializer doesn’t know how to deal with it. To allow this to work you basically have to implement a data contract for the types invovled, then it seems to understand, and also adding a KnownType attribute helps it to serializer things without getting generic random errors on the service.

    [ServiceContract]

    [KnownType(typeof(Person))]

    public class Service

    {

        [DataMember]

        public IList<Person> People

        {

            get; set;

        }

    }

 

    [DataContract]

    public class Person

    {

        [DataMember]

        public string Name

        { get; set; }

       

        [DataMember]

        public string Address

        { get; set; }

    }

 

 

Another common issue is that best practices say your shouldn’t have setters on a collection, but let users add to it or remove, from the collection itself.   the WCF serializer requires read/write access to the collection for its duty, so a way around it is to do this

    [ServiceContract]

    [KnownType(typeof(Person))]

    public class Service

    {

        [DataMember(Name = “People”)]

        private List<Person> people = new List<Person>();

 

       

        public IList<Person> People

        {

            get

            {

                return people;

            }

        }

    }

   

    [DataContract]

    public class Person

    {

        [DataMember]

        public string Name

        { get; set; }

       

        [DataMember]

        public string Address

        { get; set; }

    }

WCF 3.5 SP1 issue with service to service authentication error (caller not authenticated)

April 6, 2009 by · 3 Comments
Filed under: Programming, Software Configuration, WCF 

I recently discovered an issue with WCF 3.5 SP1, specifically the error is “The caller was not authenticated by the service”

System.ServiceModel.Security.SecurityNegotiationException was unhandled
  Message=”The caller was not authenticated by the service.”

My setup was using WSHttpBinding with message security, and it worked locally but not on a hosted machine in a domain.  I had two services on same box, calling each other, and this issue cropped up.  I was using the dns as the identity in the configuration file, however there was a change in 3.5 SP1 and now it requires either a SPN (service principal name) or a UPN (user principal name) to work correctly.  The interesting thing is you don’t even need to know the spn since it is automatically created when the service is hosted.  This is only needed for client configuration calling the services.

You can leave SPN blank it will work if default is kerberos, otherwise you will want to specify the specific spn for negotiate to fall back on.

So, if the host is running with user credentials, you should use its UPN:

<identity>
<
userPrincipalName value=user@example.com” />
</identity>

And if the host is running as s service, specify the SPN

<identity>
<
servicePrincipalName value=Host/MACHINENAME” />
</identity>

I hope this helps.