Question

J'ai une classe côté serveur que je fais sur le côté client par un [DataContract]. Cette classe a un champ que je readonly voudrais mettre à la disposition par le biais d'une propriété. Cependant, je suis incapable de le faire parce qu'il ne semble pas que je suis autorisé à ajouter une propriété [DataMember] sans avoir à la fois et ECRIRE.

- est-il possible d'avoir une propriété [DataMember] sans setter?

[DataContract]
class SomeClass
{
    private readonly int _id; 

    public SomeClass() { .. }

    [DataMember]
    public int Id { get { return _id; } }        

    [DataMember]
    public string SomeString { get; set; }
}

Ou la solution soit utiliser le [DataMember] comme champ - (comme par exemple montré ici )? J'ai essayé de faire cela aussi, mais il ne semble pas se soucier du champ est en lecture seule ..?

Modifier : La seule façon de faire une propriété en lecture seule comme le piratage cela? (Pas - je ne veux pas le faire ...)

[DataMember]
public int Id
{
    get { return _id; }
    private set { /* NOOP */ }
}
Était-ce utile?

La solution

Votre classe « côté serveur » ne sera pas « mis à la disposition » au client, vraiment.

Qu'est-ce qui se passe est la suivante: sur la base du contrat de données, le client crée une nouvelle catégorie distincte du schéma XML du service. Il ne peut pas utiliser la classe côté serveur en soi!

Il recréera une nouvelle classe de la définition de schéma XML, mais ce schéma ne contient aucune des choses spécifiques .NET comme modificateurs de visibilité ou d'accès - il est juste un schéma XML, après tout. La classe côté client sera créé de telle manière qu'il a la même « empreinte » sur le fil - par exemple il sérialise dans le même format XML, essentiellement.

ne peut pas "transport" NET savoir-faire spécifique de la classe grâce à un service SOAP standard - après tout, tout ce que vous passer sont autour de messages sérialisés - pas de cours

Cochez la case "Quatre principes de la SOA" (défini par Don Box de Microsoft):

  1. Les limites sont explicites
  2. Services sont autonomes
  3. Services schéma d'actions et le contrat, pas de classe
  4. Compability est basée sur la politique

Voir le point # 3 - Schéma des services de partage et de contrat, pas classe - vous ne partagez jamais l'interface et le schéma XML pour le contrat de données - qui est tout -. Pas de classes .NET

Autres conseils

mettre DataMember attribut sur un champ non la propriété.

Rappelez-vous la pensée, que WCF ne connaît pas l'encapsulation. Encapsulation est un terme POO, pas un terme SOA.

Cela dit, rappelez-vous que le champ sera readonly pour les personnes utilisant votre classe -. Toute personne utilisant le service aura accès au champ de leur côté

J'ai eu quelques propriétés dans une classe dans ma couche de service que je voulais passer à Silverlight. Je ne voulais pas créer une nouvelle classe.

Pas vraiment « recommandé », mais cela semblait le moindre de deux maux pour passer au-dessus de la propriété Total à silverlight (uniquement pour la liaison de données visuelle).

public class PricingSummary
{
    public int TotalItemCount { get; set; } // doesnt ideally belong here but used by top bar when out of store area

    public decimal SubTotal { get; set; }
    public decimal? Taxes { get; set; }
    public decimal Discount { get; set; }
    public decimal? ShippingTotal { get; set; }
    public decimal Total
    {
        get
        {
            return + SubTotal
                   + (ShippingTotal ?? 0)
                   + (Taxes ?? 0)
                   - Discount;
        }
        set
        {
            throw new ApplicationException("Cannot be set");
        }
    }
}

Il existe un moyen d'y parvenir. Mais soyez averti qu'il viole directement le principe suivant cité dans cette réponse :

  

"3. Services schéma d'actions et de contrat, pas de classe".

Si cette violation ne cela vous concerne pas, ce que vous faites:

  1. Déplacer les contrats de service et les données dans une bibliothèque de classes séparées (portable). (Appelons cette SomeService.Contracts de montage.) Voici comment vous définissez une classe [DataContract] immuable:

    namespace SomeService.Contracts
    {
        [DataContract]
        public sealed class Foo
        {
            public Foo(int x)
            {
                this.x = x;
            }
    
            public int X
            {
                get
                {
                    return x;
                }
            }
    
            [DataMember]  // NB: applied to the backing field, not to the property!
            private readonly int x;
        }
    }
    

    Notez que [DataMember] est appliqué au champ de support, et pas à la

  2. propriété en lecture seule correspondant.
  3. Référence de l'ensemble du contrat à la fois votre projet d'application de service (je vais appeler mes SomeService.Web) et de vos projets clients (le mien est appelé SomeService.Client). Cela pourrait se traduire dans les dépendances de projet suivantes dans votre solution:

    capture d'écran mettant en évidence les dépendances du projet dans l'Explorateur de solutions

  4. Ensuite, lorsque vous ajoutez la référence de service à votre projet client, assurez-vous d'avoir l'option « types de réutilisation » est activée, et veiller à ce que votre ensemble de contrat (de SomeService.Contracts) sera inclus dans ceci:

    capture d'écran mettant en évidence le paramètre de référence de service pertinent

Voilà! Visual Studio, au lieu de générer un nouveau type de Foo à partir du schéma WSDL du service, réutilisera le type immuable de Foo de votre ensemble de contrat.

Un dernier avertissement: Vous avez déjà écartés des principes de service cités dans cette autre réponse . Mais essayez de ne pas écarter plus loin. Vous pourriez être tenté de commencer à ajouter la logique (d'affaires) à vos classes de contrat de données; ne sont pas. Ils doivent rester au plus près des objets de transfert de données stupides que vous pouvez gérer (DTO).

Définir le contrat de service (Interface) Avant la mise en œuvre du contrat avec la classe.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top