Cet article a fait l’objet d’une traduction automatique. Pour afficher l’article en anglais, activez la case d’option Anglais. Vous pouvez également afficher le texte anglais dans une fenêtre contextuelle en faisant glisser le pointeur de la souris sur le texte traduit.
Traduction
Anglais

IDataContractSurrogate interface

 

Date de publication : novembre 2016

Fournit les méthodes nécessaires pour substituer un type à un autre par le DataContractSerializer pendant la sérialisation, la désérialisation, l'exportation et l'importation de documents de schéma XML (XSD).

Espace de noms:   System.Runtime.Serialization
Assembly:  System.Runtime.Serialization (dans System.Runtime.Serialization.dll)

public interface IDataContractSurrogate

NomDescription
System_CAPS_pubmethodGetCustomDataToExport(MemberInfo, Type)

Lors des opérations d'exportation du schéma, insère des annotations dans le schéma pour les valeurs de retour non null.

System_CAPS_pubmethodGetCustomDataToExport(Type, Type)

Lors des opérations d'exportation du schéma, insère des annotations dans le schéma pour les valeurs de retour non null.

System_CAPS_pubmethodGetDataContractType(Type)

Pendant la sérialisation, la désérialisation et l’importation et exportation de schémas, retourne un type de contrat de données qui substitue le type spécifié.

System_CAPS_pubmethodGetDeserializedObject(Object, Type)

Pendant la désérialisation, retourne un objet qui est un substitut pour l’objet spécifié.

System_CAPS_pubmethodGetKnownCustomDataTypes(Collection<Type>)

Définit la collection de types connus à utiliser pour la sérialisation et la désérialisation des objets de données personnalisés.

System_CAPS_pubmethodGetObjectToSerialize(Object, Type)

Pendant la sérialisation, retourne un objet qui substitue l'objet spécifié.

System_CAPS_pubmethodGetReferencedTypeOnImport(String, String, Object)

Pendant l'importation de schéma, retourne le type référencé par le schéma.

System_CAPS_pubmethodProcessImportedType(CodeTypeDeclaration, CodeCompileUnit)

Traite le type qui a été généré à partir du schéma importé.

Utilisez le IDataContractSurrogate lors de l'utilisation du DataContractSerializer si vous devez effectuer l'une des opérations suivantes : la substitution d'un type ou d'un objet à un autre ou la génération dynamique des variations de schéma. Pour obtenir un exemple d'application, consultez DataContract Surrogate. Pour plus d'informations sur les contrats de données, consultez Utilisation de contrats de données.

Au moment de l'exécution, vous pouvez rechercher le DataContractSerializer spécifique pour toute opération dans un service en utilisant le OperationDescription pour rechercher l'instance DataContractSerializerOperationBehavior. Pour plus d'informations sur l'implémentation de l'interface afin de créer un substitut, consultez Substituts de contrats de données.

Vous pouvez également utiliser le IDataContractSurrogate pour affecter l'importation et l'exportation de schémas XML lorsque vous utilisez les classes XsdDataContractExporter et XsdDataContractImporter. Pour ce faire, assignez le IDataContractSurrogate à la propriété DataContractSurrogate de la classe ExportOptions ou à la propriété DataContractSurrogate de la classe ImportOptions. Pour plus d'informations, consultez Importation et exportation de schémas.

L'exemple suivant illustre une implémentation de l'interface IDataContractSurrogate. Le code substitue la sérialisation du type Person à une classe PersonSurrogated.


class program
{
    static void Main(string[] args)
    {
        SerializeWithSurrogate("surrogateEmployee.xml");
        DeserializeSurrogate("surrogateEmployee.xml");
        // Create an XmlSchemaSet to hold schemas from the
        // schema exporter. 
        //XmlSchemaSet schemas = new XmlSchemaSet();
        //ExportSchemas("surrogateEmployee.xml", ref schemas);
        //// Pass the schemas to the importer.
        //ImportSchemas(schemas);

    }


    static  DataContractSerializer CreateSurrogateSerializer()  
    {
        // Create an instance of the DataContractSerializer. The 
        // constructor demands a knownTypes and surrogate. 
        // Create a Generic List for the knownTypes. 
        List<Type> knownTypes = new List<Type>();
        LegacyPersonTypeSurrogate surrogate = new LegacyPersonTypeSurrogate ();
        DataContractSerializer surrogateSerializer = 
            new DataContractSerializer(typeof(Employee), 
           knownTypes, Int16.MaxValue, false, true, surrogate);
        return surrogateSerializer;
    }

    static void SerializeWithSurrogate(string filename )
    {
        // Create and populate an Employee instance.
        Employee emp = new Employee();
        emp.date_hired = new DateTime(1999, 10, 14);
        emp.salary = 33000;

        // Note that the Person class is a legacy XmlSerializable class
        // without a DataContract.
        emp.person = new Person();
        emp.person.first_name = "Mike";
        emp.person.last_name = "Ray";
        emp.person.age = 44;

        // Create a new writer. Then serialize with the 
        // surrogate serializer.
        FileStream  fs =new FileStream(filename, FileMode.Create);
        DataContractSerializer surrogateSerializer = CreateSurrogateSerializer();
        try{
            surrogateSerializer.WriteObject(fs, emp);
            Console.WriteLine("Serialization succeeded. ");
            fs.Close();
        }
        catch (SerializationException exc )
            {
            Console.WriteLine(exc.Message);
            }

    }

    static void DeserializeSurrogate( string filename )
    {
        // Create a new reader object.
        FileStream fs2 = new FileStream(filename, FileMode.Open);
        XmlDictionaryReader reader = 
            XmlDictionaryReader.CreateTextReader(fs2, new XmlDictionaryReaderQuotas());

        Console.WriteLine("Trying to deserialize with surrogate.");
        try
        {
            DataContractSerializer surrogateSerializer = CreateSurrogateSerializer();
            Employee newemp = (Employee) surrogateSerializer.ReadObject(reader, false);

            reader.Close();
            fs2.Close();

            Console.WriteLine("Deserialization succeeded. \n\n");
            Console.WriteLine("Deserialized Person data: \n\t {0} {1}",
                    newemp.person.first_name, newemp.person.last_name);
                Console.WriteLine("\t Age: {0} \n", newemp.person.age);
            Console.WriteLine("\t Date Hired: {0}", newemp.date_hired.ToShortDateString());
            Console.WriteLine("\t Salary: {0}", newemp.salary);
            Console.WriteLine("Press Enter to end or continue");
            Console.ReadLine();
        }
        catch (SerializationException serEx  )
        {
            Console.WriteLine(serEx.Message);
            Console.WriteLine(serEx.StackTrace);
        }

    }

    static void ExportSchemas(string filename , ref XmlSchemaSet schemas)
{
        Console.WriteLine("Now doing schema export.");
        // The following code demonstrates schema export with a surrogate.
        // The surrogate indicates how to export the non-DataContract Person type.
        // Without the surrogate, schema export would fail.
        XsdDataContractExporter xsdexp = new XsdDataContractExporter();
        xsdexp.Options = new ExportOptions();
        xsdexp.Options.DataContractSurrogate = new LegacyPersonTypeSurrogate();
        xsdexp.Export(typeof(Employee));

        // Write out the exported schema to a file.
        using (FileStream fs3 = new FileStream("sample.xsd", FileMode.Create))
        {
            foreach (XmlSchema sch in xsdexp.Schemas.Schemas())
            {
                sch.Write(fs3);
            }
        } 
    }

    static void ImportSchemas(XmlSchemaSet schemas ){
        Console.WriteLine("Now doing schema import.");
        // The following code demonstrates schema import with 
        // a surrogate. The surrogate is used to indicate that 
        // the Person class already exists and that there is no 
        // need to generate a new class when importing the
        // PersonSurrogated data contract. If the surrogate 
        // was not used, schema import would generate a 
        // PersonSurrogated class, and the person field 
        // of Employee would be imported as 
        // PersonSurrogated and not Person.
        XsdDataContractImporter xsdimp = new XsdDataContractImporter();
        xsdimp.Options = new ImportOptions();
        xsdimp.Options.DataContractSurrogate = new LegacyPersonTypeSurrogate();
        xsdimp.Import(schemas);

        // Write out the imported schema to a C-Sharp file.
        // The code contains data contract types.
        FileStream fs4 = new FileStream("sample.cs", FileMode.Create);
        try
        {
            StreamWriter tw = new StreamWriter(fs4);
            Microsoft.CSharp.CSharpCodeProvider cdp = new Microsoft.CSharp.CSharpCodeProvider();
            cdp.GenerateCodeFromCompileUnit(xsdimp.CodeCompileUnit, tw, null);
            tw.Flush();
        }
        finally
        {
            fs4.Dispose();
        }


        Console.WriteLine( "\t  To see the results of schema export and import,");
        Console.WriteLine(" see SAMPLE.XSD and SAMPLE.CS." );

        Console.WriteLine(" Press ENTER to terminate the sample." );
        Console.ReadLine();
    }


}


// This is the Employee (outer) type used in the sample.

[DataContract()] 
public class Employee
{
    [DataMember()] 
    public DateTime date_hired ;

    [DataMember()]
public decimal salary ;

    [DataMember()]
    public Person person;
}


// This is the Person (inner) type used in the sample.
// Note that it is a legacy XmlSerializable type and not a DataContract type.

public class Person
{
    [XmlElement("FirstName")]
    public string first_name ;

    [XmlElement("LastName")]
    public string last_name ;

    [XmlAttribute("Age")]
    public Int16 age ;

    public Person()  {}   
}

// This is the surrogated version of the Person type
// that will be used for its serialization/deserialization.

[DataContract] class PersonSurrogated
{
    // xmlData will store the XML returned for a Person instance 
    // by the XmlSerializer.
    [DataMember()]
    public string xmlData;

}

 //This is the surrogate that substitutes PersonSurrogated for Person.
public class LegacyPersonTypeSurrogate:IDataContractSurrogate
{
    public Type GetDataContractType(Type type) 
{
        Console.WriteLine("GetDataContractType invoked");
        Console.WriteLine("\t type name: {0}", type.Name);
        // "Person" will be serialized as "PersonSurrogated"
        // This method is called during serialization,
        // deserialization, and schema export.
        if (typeof(Person).IsAssignableFrom(type)) 
{
Console.WriteLine("\t returning PersonSurrogated");
            return typeof(PersonSurrogated);
        }
        return type;

    }

public object GetObjectToSerialize(object obj, Type targetType)
{ 
        Console.WriteLine("GetObjectToSerialize Invoked");
        Console.WriteLine("\t type name: {0}", obj.ToString());
        Console.WriteLine("\t target type: {0}", targetType.Name);
        // This method is called on serialization.
        // If Person is not being serialized...
        if (obj is Person )
        {
            Console.WriteLine("\t returning PersonSurrogated");
            // ... use the XmlSerializer to perform the actual serialization.
            PersonSurrogated  ps = new PersonSurrogated();
            XmlSerializer xs = new XmlSerializer(typeof(Person));
            StringWriter sw = new StringWriter();
            xs.Serialize(sw, (Person)obj );
            ps.xmlData = sw.ToString();
            return ps;
        }
        return obj;

    }

    public object GetDeserializedObject(Object obj , Type targetType) 
    {
        Console.WriteLine("GetDeserializedObject invoked");
        // This method is called on deserialization.
        // If PersonSurrogated is being deserialized...
        if (obj is PersonSurrogated)
            {
                //... use the XmlSerializer to do the actual deserialization.
                PersonSurrogated ps = (PersonSurrogated)obj;
                XmlSerializer xs = new XmlSerializer(typeof(Person));
                return (Person)xs.Deserialize(new StringReader(ps.xmlData));
            }
            return obj;

    }

    public Type GetReferencedTypeOnImport(string typeName,
        string typeNamespace, object customData)
    {
        Console.WriteLine("GetReferencedTypeOnImport invoked");
        // This method is called on schema import.
        // If a PersonSurrogated data contract is 
        // in the specified namespace, do not create a new type for it 
        // because there is already an existing type, "Person".
        Console.WriteLine( "\t Type Name: {0}", typeName);

        if (typeName.Equals("PersonSurrogated") )
        {
            Console.WriteLine("Returning Person");
            return typeof(Person);
        }        
        return null;
    }

    public System.CodeDom.CodeTypeDeclaration ProcessImportedType(
        System.CodeDom.CodeTypeDeclaration typeDeclaration, 
        System.CodeDom.CodeCompileUnit compileUnit)
    {
        // Console.WriteLine("ProcessImportedType invoked")
        // Not used in this sample.
        // You could use this method to construct an entirely new CLR 
        // type when a certain type is imported, or modify a 
        // generated type in some way.
        return typeDeclaration;
    }



        public object GetCustomDataToExport(Type clrType, Type dataContractType)
        {
            // Not used in this sample
            return null;
        }

        public object GetCustomDataToExport(System.Reflection.MemberInfo memberInfo, Type dataContractType)
        {
            // Not used in this sample
            return null;
        }

        public void GetKnownCustomDataTypes(Collection<Type> customDataTypes)
        {
            // Not used in this sample
        }
}

.NET Framework
Disponible depuis 3.0
Retour au début
Afficher: