WCF DataContract with readonly properties

江枫思渺然 提交于 2019-12-30 02:45:06

问题


I'm trying to return a complex type from a service method in WCF. I'm using C# and .NET 4. This complex type is meant to be invariant (the same way .net strings are). Furthermore, the service only returns it and never receives it as an argument.

If I try to define only getters on properties I get a run time error. I guess this is because no setters causes serialization to fail. Still, I think this type should be invariant.

Example:

[DataContract]
class A 
{
   [DataMember]
   int ReadOnlyProperty {get; private set;}
}

The service fails to load due to a problem with serialization.

Is there a way to make readonly properties on a WCF DataContract? Perhaps by replacing the serializer? If so, how? If not, what would you suggest for this problem?

Thanks,
Asaf


回答1:


DataMember Field can't be readonly, because wcf dont serialize object as-is and every time befor deserialization starts creates new object instance, using default constructor. Dispatchers use setters to set field values after deserialization.

But all upper text can be a big mistake :)

To make them realy readonly, make the server logic, validating thiss field values.




回答2:


put [DataMember] on backing field, you won't need a setter.




回答3:


Make your setter public to satisfy the serializer, but just don't do anything on the setter. Not 'purist' but gets it done

public string MyProperty 
{
    get {
        return this._myProperty
    }
    set {}
}



回答4:


You can't make the properties readonly, however you can get close to readonly by making the fields part of your contract instead of the properties:

[DataContract]
public class A 
{
   public class A(){}
   public class A(int readonlyproperty){ _readonlyproperty = readonlyproperty}

   [DataMember(Name = "ReadOnlyProperty")]
   internal int _readonlyproperty;

   public int ReadOnlyProperty {
      get {return _readonlyproperty;}
      private set {_readonlyproperty = value;}
}

next make your internals accesable in wcf:

[assembly: InternalsVisibleTo("System.Runtime.Serialization")]

Some samples on how to use this to your advantage: wcf-and-datacontract-serialization-internals-and-tips




回答5:


Like others have said, WCF needs getters and setters. That being said, I came here with the same question and the answers made me ask why I needed a read-only property. If you use the MVVM pattern, the class returned by the service is the Model and so should not be exposed directly by the UI. You can easily make the ViewModel read-only. Alternatively you could use a non UI-targetted facade class.




回答6:


Actually, you can make the read-only fields serializable. You need to set the 'SerializeReadOnlyTypes' property of the DataContractSerializerSettings to 'True', when constructing the DataContractSerializer, as below:

var xmlSerializer = new DataContractSerializer(typeof(yourTypeHere),  new DataContractSerializerSettings {SerializeReadOnlyTypes=true});

See the MSDN description and details, here: https://msdn.microsoft.com/en-us/library/system.runtime.serialization.datacontractserializersettings(v=vs.110).aspx




回答7:


WCF needs to able to serialize / deserialize the property, which is not possible with a private property. To have a readonly property (within a complex type):

  • Decorate class as [DataContract(IsReference = true)]
  • Decorate each / the property as [DataMember]
  • Public Get, Internal Set
    [DataContract(IsReference = true)]
    public class Format : ValueObject<Format>
    {
        [DataMember]
        public int Height { get; internal set; }
    }



回答8:


Have you tried making the setter private?

Something like:

public string MyProperty
{
get;
private set;
}


来源:https://stackoverflow.com/questions/2494917/wcf-datacontract-with-readonly-properties

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!