2009-06-10 4 views
9

J'ai une classe générée par SQL LINQ 2 que je souhaite exposer via un service web. Certaines propriétés internes ne sont pas disponibles.Utilisation de XmlIgnore sur les classes partielles générées

Normalement je lancerais [XmlIgnore] dedans mais parce que les propriétés sont dans la moitié générée je ne peux pas faire cela.

J'ai cherché à utiliser MetadataType suivant this post qui devrait me permettre de définir les attributs de propriété dans une autre classe.

Mon code ressemble à ceci:

[MetadataType(typeof(ProspectMetaData))] 
public partial class Prospect : ApplicationBaseObject 
{ 
} 

public class ProspectMetaData 
{ 
    [XmlIgnore] 
    public object CreatedDateTime { get; set; } 

    [XmlIgnore] 
    public object AmendedDateTime { get; set; } 

    [XmlIgnore] 
    public object Timestamp { get; set; } 
} 

Je fais référence ce grâce à un service Web ASP.NET à partir d'un projet Silverlight.

Le problème est que les attributs [XmlIgnore] sont ignorés, ces propriétés sont envoyées à travers.

Quelqu'un a-t-il un aperçu de ce qui pourrait mal se passer ici? et quelle pourrait être la meilleure façon de le faire?

Répondre

3

AFAIK, MetadataTypeAttribute est pas pris en charge par XmlSerializer (bien qu'il serait bien - je l'ai tout simplement jamais vérifié). Et comme vous le dites, vous ne pouvez pas ajouter d'attributs de membre dans une classe partielle.

Une option peut être de rendre les propriétés générées non publiques (private, protected ou internal) - et nommez quelque chose comme TimestampStorage (etc) - puis les ré-exposer (dans la classe partielle) sur l'API publique:

[XmlIgnore] 
public object Timestamp { 
    get {return TimestampStorage; } 
    set {TimestampStorage = value; } 
} 
// and other properties 

(depuis XmlSerializer on ne considère que l'API publique). Le plus gros problème ici est que les requêtes LINQ-to-SQL (Where etc.) ne fonctionneront qu'avec les colonnes générées (TimestampStorage etc). J'ai utilisé cette approche auparavant avec le membre comme internal, permettant à ma classe DAL d'utiliser la propriété internal ... mais c'est un peu un fudge.

+0

il semble certainement de cette façon et il est vraiment dommage. Je n'ai aucun contrôle sur les accesseurs sur les propriétés générées donc ça ne le résout pas vraiment pour moi. Je suppose que je vais devoir aller avec une classe proxy plutôt que d'envoyer mes objets métier. –

+0

Vous devez réinitialiser les niveaux d'accès lors de la régénération. :( –

1

Je suis d'accord avec Marc. La chose la plus facile à faire est de les marquer en interne. Vous pouvez éventuellement les réexposer dans la classe partielle avec [XmlIgnore]. BTW, vous pouvez contrôler l'accessibilité des propriétés dans le concepteur linq2sql. Obtenez dans la boîte de dialogue des propriétés et vous verrez un endroit pour les définir

+0

Nous utilisons actuellement nos propres outils de génération de code pour générer les moitiés générées, quand j'ai dit LINQ2SQL, c'est le parallèle le plus proche.Ceci pourrait être pratique pour les autres. + 1 –

11

Vous pouvez faire cela en passant votre propre XmlAttributeOverrides à XmlSerializer, dans le XmlAttributeOverrides vous pouvez changer le XmlIgnore à true pour les champs/propriétés que vous souhaitez sans toucher le DBML code généré et il fonctionne comme un charme, utilisez les mêmes remplacements désérialiser et ...

Refer this link pour plus d'informations

// Create the XmlAttributeOverrides and XmlAttributes objects. 
    XmlAttributeOverrides xOver = new XmlAttributeOverrides(); 

    XmlAttributes attrs = new XmlAttributes(); 
    attrs.XmlIgnore = true; 

    /* Setting XmlIgnore to true overrides the XmlIgnoreAttribute 
     applied to the following fields. Thus it will be serialized.*/ 
    xOver.Add(typeof(Prospect), "CreatedDateTime", attrs); 
    xOver.Add(typeof(Prospect), "AmendedDateTime", attrs); 
    xOver.Add(typeof(Prospect), "Timestamp", attrs); 

    XmlSerializer xSer = new XmlSerializer(typeof(Prospect), xOver); 
    TextWriter writer = new StreamWriter(outputFilePath); 
    xSer.Serialize(writer, object); 
+2

Informations vraiment utiles, merci. –

+0

C'est le meilleur choix pour moi, merci! –

+0

Existe-t-il un moyen de le faire pour le sérialiseur Newtonsoft.Json JSON? – Dave