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?
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.
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
[DataMember(Name = "PropertyName")]
public string PropertyName
{
get
{
return "";
}
private set
{ }
}
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é.
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à?
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")]
.
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é.
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.