I had a similar problem with serializing immutable types before, in the end I decided to implement the ISerializable interface and use the SerializationInfo to store & retrieve the private variables at both ends of the serialization/deserialization process:
http://theburningmonk.com/2010/04/net-tips-making-a-serializable-immutable-struct/
I just built and run a test app using the same technique and it seems to work for me. So in terms of changes to your Clinic class you could change it to:
[Serializable]
public class Clinic : ISerializable
{
public Clinic(string name, string id)
{
Name = name;
Id = id;
}
public Clinic(SerializationInfo info, StreamingContext context)
{
Name= info.GetString("Name");
Id= info.GetString("Id");
}
public string Name{get; private set;}
public string Id{get; private set;}
[SecurityPermission(SecurityAction.Demand, SerializationFormatter = true)]
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
info.AddValue("Name", Name);
info.AddValue("Id", Id);
}
}
This will solve the problem you're having passing the data back from WCF. But from a design point of view, I agree with what Ladislav is saying and typically you will want to separate your domain objects with objects purely intended for message passing (DataTransferObjects), and in that case here's an example of how you MIGHT approach it:
// the domain object (NOT EXPOSED through the WCF service)
public class Clinic
{
public Clinic(string name, string id)
{
Name = name;
Id = id;
}
public string Name{ get; private set;}
public string Id{ get; private set;}
// other methods encapsulating some business logic, etc.
...
}
// the corresponding DTO object for the domain object Clinic
// this is the type exposed through the WCF layer, that the client knows about
[DataContract]
public class ClinicDTO
{
[DataMember]
public string Name { get; set; }
[DataMember]
public string Id { get; set; }
}
// WCF service contract, NOTE it returns ClinicDTO instead of Clinic
[ServiceContract]
public interface IClinicService
{
[OperationContract]
ClinicDTO GetClinicById(string id);
}
To ease the pain of converting from Clinic to ClinicDTO, you could either add a method on Clinic to do this or implement an implicit/explicit converter. I've got an example on how to do this here:
http://theburningmonk.com/2010/02/controlling-type-conversion-in-c/
Hope this helps!