web-dev-qa-db-fra.com

WCF s'étouffe sur des propriétés sans "set". Une solution?

J'ai une classe que je passe à la suite d'une méthode de service, et cette classe a une propriété get-only:

[DataContract]
public class ErrorBase
{
  [DataMember]
  public virtual string Message { get { return ""; } }
}

Je reçois une exception côté service:

System.Runtime.Serialization.InvalidDataContractException: aucune méthode définie pour la propriété 'Message' dans le type 'MyNamespace.ErrorBase'.

Je dois avoir cette propriété comme seul getter, je ne peux pas permettre aux utilisateurs de lui attribuer une valeur. Une solution de contournement que je pourrais utiliser? Ou ai-je manqué un attribut supplémentaire?

93
Andrey

Donnez à Message un getter public mais un setter protégé, de sorte que seules les sous-classes (et le DataContractSerializer, car il triche :) peuvent modifier la valeur.

102
rh.

Même si vous n'avez pas besoin de mettre à jour la valeur, le setter est utilisé par le WCFSerializer pour désérialiser l'objet (et réinitialiser la valeur).

Ceci SO est ce que vous recherchez: WCF DataContracts

12
Russell
[DataMember(Name = "PropertyName")]
public string PropertyName
{
    get
    {
        return "";
    }
    private set
    { }
}
10
Rikin Patel

Si vous ne disposez que d'un getter, pourquoi devez-vous sérialiser la propriété? Il semble que vous puissiez supprimer l'attribut DataMember pour la propriété en lecture seule, et le sérialiseur ignorerait simplement la propriété.

5
Rob Lambert

Ne pourriez-vous pas simplement avoir un setter "ne rien faire" ??

[DataContract]
public class ErrorBase
{
  [DataMember]
  public virtual string Message 
  {
      get { return ""; } 
      set { }
  }
}

Ou est-ce que le sérialiseur DataContract est également là?

3
marc_s

J'ai eu ce problème avec ASP.NET MVC et moi voulant utiliser DataContractSerializer afin de pouvoir contrôler les noms des éléments dans la sortie JSON. Finalement, j'ai basculé le sérialiseur vers JSON.NET, qui prend en charge les propriétés sans setters (ce que DataContractSerializer ne fait pas) et le contrôle du nom de propriété (ce que le sérialiseur JSON intégré dans ASP.NET MVC ne fait pas) via [JsonProperty(PropertyName = "myName")] .

2
Thomas Lundström

Si c'est une option viable, au lieu d'avoir ErrorBase comme classe de base, définissez-la comme suit:

    public interface IError
    {
        string Message
        {
            [OperationContract]
            get;

            // leave unattributed
            set;
        }
    }

Maintenant, même si un setter existe, il est inaccessible au client via le canal WCF, c'est donc comme s'il était privé.

2
Gilad

Les propriétés avec l'attribut DataMember nécessitent toujours un ensemble. Vous devez réécrire l'objet simmilar sur l'application client car les membres DataContract peuvent toujours recevoir des valeurs.

2
Jojo Sardez