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.

Setting up SMTP on windows 2008 server (windows 2003) To use Gmail as SMTP host

December 6, 2008 by · 18 Comments
Filed under: Software Configuration 

This is a post about how to setup an SMTP relay on windows 2008 server(should work same on windows 2003 since Microsoft didn’t update the SMTP console) to use a different mail server like gmail, or yahoo, or any email provider which offers an SMTP feature (currently i don’t think hotmail allows this.)

Step 1: Install SMTP and the Admin UI (which is the IIS 6.0 MMC different from the new IIS 7.0 MMC)

Step 2: Run SMTP IIS 6.0 MMC as Admin (if using UAC), and configure the outbound rules

To use SMTP server as a relay to gmail you would simply set these outbound connection settings.  You need to right-click on the virtual server and select properties.

Step 3: Test it out

To test it out you can create a new text file call it “mail.txt” and put this inside “

From:<the email address your from>
To:<yourtestemailaccount>
Subject: testing 1 2 3
Mail content to send.”

copy this file into the mailrootpickup folder, which should automatically be sent to see if it does indeed relay directly.

So this relay will send all mail to the gmail server using your gmail account (it overwrites the from address to always be from the gmail account but it is a free smtp relay and pretty easy to accomplish. If there are any problems forwarding make sure to check the relay/authentication settings for the inbound connections and don’t leave your relay open to public it could cause spam problems and get your gmail account removed.

Warning: Service reliability and Auto restart

I have noticed that if you restart IIS the SMTP server doesn’t come back online all the time, you may need to manually open IIS 6  console and start SMTP virtual servers, I am investigating this but wanted to point out a word of warning.

Update:  Apparently when you install SMTP it doesn’t default to auto-start as a service in the services snap-in, just update this to auto-start it should then work as expected.

Happy Mailing!