JavaScriptTypeResolver Klasse

Definition

Stellt die abstrakte Basisklasse zum Implementieren eines benutzerdefinierten Typresolvers bereit.

public ref class JavaScriptTypeResolver abstract
public abstract class JavaScriptTypeResolver
type JavaScriptTypeResolver = class
Public MustInherit Class JavaScriptTypeResolver
Vererbung
JavaScriptTypeResolver
Abgeleitet

Beispiele

Im folgenden Beispiel wird gezeigt, wie ein benutzerdefiniertes JavaScriptTypeResolver Objekt erstellt und zum Serialisieren oder Deserialisieren eines Objekts verwendet wird.

using System;
using System.Linq;
using System.Web.Script.Serialization;

namespace SampleApp
{
    class Program
    {
        static void Main(string[] args)
        {
            // The object array to serialize.
            Person[] people = new Person[]
            {
                new Person()
                {
                    Name = "Kristen Solstad",
                    Age = 15,
                    HomeAddress = new Address()
                    {
                        Street1 = "123 Palm Ave",
                        City = "Some City",
                        StateOrProvince = "ST",
                        Country = "United States",
                        PostalCode = "00000"
                    }
                },
                new Adult()
                {
                    Name = "Alex Johnson",
                    Age = 39,
                    Occupation = "Mechanic",
                    HomeAddress = new Address()
                    {
                        Street1 = "445 Lorry Way",
                        Street2 = "Unit 3A",
                        City = "Some City",
                        Country = "United Kingdom",
                        PostalCode = "AA0 A00"
                    }
                }
            };

            // Serialize the object array, then write it to the console.
            string serializedData = SerializePeopleArray(people);
            Console.WriteLine("Serialized:");
            Console.WriteLine(serializedData);
            Console.WriteLine();

            // Now deserialize the object array.
            Person[] deserializedArray = DeserializePeopleArray(serializedData);
            Console.WriteLine("Deserialized " + deserializedArray.Length + " people.");
            foreach (Person person in deserializedArray)
            {
                Console.WriteLine(person.Name + " (Age " + person.Age + ") [" + person.GetType() + "]");
            }
        }

        static string SerializePeopleArray(Person[] people)
        {
            // The custom type resolver to use.
            // Note: Except for primitives like int and string, *every* type that
            // we might see in the object graph must be listed here.
            CustomTypeResolver resolver = new CustomTypeResolver(
                typeof(Person),
                typeof(Adult),
                typeof(Address));

            // Instantiate the serializer.
            JavaScriptSerializer serializer = new JavaScriptSerializer(resolver);

            // Serialize the object array, then return it.
            string serialized = serializer.Serialize(people);
            return serialized;
        }

        static Person[] DeserializePeopleArray(string serializedData)
        {
            // The custom type resolver to use.
            // Note: This is the same list that was provided to the Serialize routine.
            CustomTypeResolver resolver = new CustomTypeResolver(
                typeof(Person),
                typeof(Adult),
                typeof(Address));

            // Instantiate the serializer.
            JavaScriptSerializer serializer = new JavaScriptSerializer(resolver);

            // Deserialize the object array, then return it.
            Person[] deserialized = serializer.Deserialize<Person[]>(serializedData);
            return deserialized;
        }
    }

    public class Person
    {
        public string Name { get; set; }
        public int Age { get; set; }
        public Address HomeAddress { get; set; }
    }

    public class Adult : Person
    {
        public string Occupation { get; set; }
    }

    public class Address
    {
        public string Street1 { get; set; }
        public string Street2 { get; set; }
        public string City { get; set; }
        public string StateOrProvince { get; set; }
        public string Country { get; set; }
        public string PostalCode { get; set; }
    }

    // A custom JavaScriptTypeResolver that restricts the payload
    // to a set of known good types.
    class CustomTypeResolver : JavaScriptTypeResolver
    {
        private readonly Type[] _allowedTypes;

        public CustomTypeResolver(params Type[] allowedTypes)
        {
            if (allowedTypes == null)
            {
                throw new ArgumentNullException("allowedTypes");
            }

            // Make a copy of the array the caller gave us.
            _allowedTypes = (Type[])allowedTypes.Clone();
        }

        public override Type ResolveType(string id)
        {
            // Iterate over all of the allowed types, looking for a match
            // for the 'id' parameter. Calling Type.GetType(id) is dangerous,
            // so we instead perform a match on the Type.FullName property.
            foreach (Type allowedType in _allowedTypes)
            {
                if (allowedType.FullName == id)
                {
                    return allowedType;
                }
            }

            // The caller provided a type we don't recognize. This could be
            // dangerous, so we'll fail the operation immediately.
            throw new ArgumentException("Unknown type: " + id, "id");
        }

        public override string ResolveTypeId(Type type)
        {
            // Before we serialize data, quickly double-check to make
            // sure we're allowed to deserialize the data. Otherwise it's
            // no good serializing something if we can't deserialize it.
            if (_allowedTypes.Contains(type))
            {
                return type.FullName;
            }

            throw new InvalidOperationException("Cannot serialize an object of type " + type + ". Did you forget to add it to the allow list?");
        }
    }
}

Die vorherige App gibt Folgendes an die Konsole aus, formatiert für die Lesbarkeit.

Serialized:
[
    {
        "__type": "SampleApp.Person",
        "Name": "Kristen Solstad",
        "Age": 15,
        "HomeAddress": {
            "__type": "SampleApp.Address",
            "Street1": "123 Palm Ave",
            "Street2": null,
            "City": "Some City",
            "StateOrProvince": "ST",
            "Country": "United States",
            "PostalCode": "00000"
        }
    },
    {
        "__type": "SampleApp.Adult",
        "Occupation": "Mechanic",
        "Name": "Alex Johnson",
        "Age": 39,
        "HomeAddress": {
            "__type": "SampleApp.Address",
            "Street1": "445 Lorry Way",
            "Street2": "Unit 3A",
            "City": "Some City",
            "StateOrProvince": null,
            "Country": "United Kingdom",
            "PostalCode": "AA0 A00"
        }
    }
]

Deserialized 2 people.
Kristen Solstad (Age 15) [SampleApp.Person]
Alex Johnson (Age 39) [SampleApp.Adult]

Im vorherigen Beispiel unterklassiert der Adult Typ den Person Typ. Ein benutzerdefinierter JavaScriptTypeResolver Wird verwendet, um die Typinformationen als Teil der generierten JSON-Nutzlast einzuschließen. Dies ermöglicht eine begrenzte Polymorphität beim Deserialisieren der JSON-Nutzlast zurück in ein .NET-Objektdiagramm. Die Nutzlast kann steuern, ob eine Basisinstanz Person oder eine abgeleitete Adult Instanz zurück an den Aufrufer zurückgegeben werden soll.

Dieses Beispiel ist sicher, da es einen allow-list Mechanismus zum Steuern der Deserialisierung verwendet. Der Code:

  • Initialisiert die CustomTypeResolver mit einer expliziten Liste zulässiger Typen.
  • Schränkt den Deserialisierungsprozess nur auf eine genehmigte Liste von Typen ein. Die Einschränkung verhindert Deserialisierungsangriffe, bei denen der Remoteclient einen böswilligen __type In der JSON-Nutzlast angibt und den Server dazu bringt, einen gefährlichen Typ zu deserialisieren.

Obwohl die App nur erwartet, dass Person Instanzen Adult als Teil deserialisiert werden, ist es dennoch notwendig, der Zulassungsliste hinzuzufügen Address , denn:

  • Beim Serialisieren eines Person oder Adult serialisiert ein Address als Teil des Objektdiagramms.
  • Alle Typen, die möglicherweise im Objektdiagramm vorhanden sind, müssen in der Zulassungsliste berücksichtigt werden. Primitiven mögen int und string müssen nicht angegeben werden.

Warnung

Rufen Sie nicht innerhalb der ResolveType -Methode aufType.GetType(id). Dadurch könnte eine Sicherheitsverwendbarkeit in die App eingeführt werden. Durchlaufen Sie stattdessen die Liste der zulässigen Typen, und vergleichen Sie deren Type.FullName Eigenschaft mit dem eingehenden id, wie im vorherigen Beispiel gezeigt.

Hinweise

Die JavaScriptTypeResolver -Klasse stellt die Dienste für folgendes bereit:

  • Konvertieren von Informationen vom verwalteten Typ in einen Zeichenfolgenwert über die ResolveTypeId -Methode.

  • Auflösen eines Zeichenfolgenwerts zurück in den entsprechenden verwalteten Typ über die ResolveType -Methode.

Wenn das JavaScriptSerializer Objekt benutzerdefinierte Typen serialisiert, kann es optional in die serialisierte JSON-Zeichenfolge (JavaScript Object Notation) einen Wert einschließen, der Typinformationen enthält. Kann während der Deserialisierung dann auf diesen Zeichenfolgenwert verweisen, JavaScriptSerializer um den entsprechenden verwalteten Typ zu bestimmen, in den die JSON-Zeichenfolge konvertiert wird.

Wenn Sie einen Typrelöser für die JavaScriptSerializer -Instanz bereitstellen, verwendet der Serialisierer die ResolveTypeId Methoden und ResolveType , um während des Serialisierungs- bzw. Deserialisierungsprozesses zwischen dem verwalteten Typ und dem Zeichenfolgenwert zuzuordnen.

Die JavaScriptTypeResolver -Klasse ist die Basisklasse für die SimpleTypeResolver -Klasse, die eine Implementierung eines Typlösers bereitstellt, der den assemblyqualifizierten Namen des verwalteten Typs verwendet.

Hinweis

Bei Verwendung eines JavaScriptTypeResolverenthält die resultierende JSON-Nutzlast eine spezielle __type Eigenschaft. Diese Eigenschaft enthält den vollständigen Typnamen einschließlich Namespace des Zieltyps. Vergewissern Sie sich vor der Verwendung eines benutzerdefinierten Resolvers, dass der vollständige Name des Zieltyps keine vertraulichen oder privilegierten Informationen enthält.

Hinweise für Ausführende

Wenn Sie einen Typrelöser implementieren, muss die von der ResolveTypeId(Type) -Methode zurückgegebene Zeichenfolge demselben verwalteten Typ zugeordnet werden, wenn der Zeichenfolgenwert an die ResolveType(String) -Methode übergeben wird.

Konstruktoren

JavaScriptTypeResolver()

Initialisiert eine neue Instanz der JavaScriptTypeResolver-Klasse.

Methoden

Equals(Object)

Bestimmt, ob das angegebene Objekt gleich dem aktuellen Objekt ist.

(Geerbt von Object)
GetHashCode()

Fungiert als Standardhashfunktion.

(Geerbt von Object)
GetType()

Ruft den Type der aktuellen Instanz ab.

(Geerbt von Object)
MemberwiseClone()

Erstellt eine flache Kopie des aktuellen Object.

(Geerbt von Object)
ResolveType(String)

Gibt beim Überschreiben in einer abgeleiteten Klasse das Type-Objekt zurück, das dem angegebenen Typnamen zugeordnet ist.

ResolveTypeId(Type)

Gibt beim Überschreiben in einer abgeleiteten Klasse den Typnamen für das angegebene Type-Objekt zurück.

ToString()

Gibt eine Zeichenfolge zurück, die das aktuelle Objekt darstellt.

(Geerbt von Object)

Gilt für: