JavaScriptTypeResolver Kelas

Definisi

Menyediakan kelas dasar abstrak untuk menerapkan pemecah masalah jenis kustom.

public ref class JavaScriptTypeResolver abstract
public abstract class JavaScriptTypeResolver
type JavaScriptTypeResolver = class
Public MustInherit Class JavaScriptTypeResolver
Warisan
JavaScriptTypeResolver
Turunan

Contoh

Contoh berikut menunjukkan cara membuat kustom JavaScriptTypeResolver dan cara menggunakannya untuk menserialisasikan atau mendeserialisasi objek.

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?");
       }
   }
}

Aplikasi sebelumnya menghasilkan yang berikut ini ke konsol, yang diformat untuk keterbacaan.

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]

Dalam sampel sebelumnya, Adult jenis mensubkelas jenisnya Person . Kustom JavaScriptTypeResolver digunakan untuk menyertakan informasi jenis sebagai bagian dari payload JSON yang dihasilkan. Ini memungkinkan polimorfisme terbatas saat mendeserialisasi payload JSON kembali ke grafik objek .NET. Payload dapat mengontrol apakah akan mengembalikan instans dasar Person atau instans turunan Adult kembali ke pemanggil.

Sampel ini aman karena menggunakan allow-list mekanisme untuk mengontrol deserialisasi. Kode:

  • Menginisialisasi CustomTypeResolver dengan daftar eksplisit jenis yang diizinkan.
  • Membatasi proses deserialisasi hanya untuk daftar jenis yang disetujui. Pembatasan mencegah serangan deserialisasi, di mana klien jarak jauh menentukan berbahaya __type dalam payload JSON dan mengelabui server untuk mendeserialisasi jenis berbahaya.

Meskipun aplikasi hanya mengharapkan Person dan Adult instans dideserialisasi sebagai bagian dari array tingkat atas, masih perlu ditambahkan Address ke daftar izin karena:

  • Menserialisasikan Person atau Adult juga menserialisasikan Address sebagai bagian dari grafik objek.
  • Semua jenis yang mungkin ada dalam grafik objek perlu diperhitungkan dalam daftar izinkan. Primitif seperti int dan string tidak perlu ditentukan.

Warning

Jangan panggil Type.GetType(id) dalam ResolveType metode . Ini dapat memperkenalkan vunerability keamanan ke dalam aplikasi. Sebagai gantinya, iterasi melalui daftar jenis yang diizinkan dan bandingkan Type.FullNamepropertinya id dengan yang masuk , seperti yang ditunjukkan dalam sampel sebelumnya.

Keterangan

Kelas ini JavaScriptTypeResolver menyediakan layanan untuk:

  • Mengonversi informasi jenis terkelola menjadi nilai string melalui ResolveTypeId metode .

  • Menyelesaikan nilai string kembali ke jenis terkelola yang sesuai melalui ResolveType metode .

JavaScriptSerializer Saat objek menserialisasikan jenis kustom, objek dapat secara opsional disertakan dalam string JavaScript Object Notation (JSON) serial nilai yang berisi informasi jenis. Selama deserialisasi, JavaScriptSerializer kemudian dapat mereferensikan nilai string ini untuk menentukan jenis terkelola yang sesuai tempat string JSON akan dikonversi.

Jika Anda memberikan pemecah masalah jenis ke JavaScriptSerializer instans, serializer akan menggunakan ResolveTypeId metode dan ResolveType untuk memetakan antara jenis terkelola dan nilai string selama proses serialisasi dan deserialisasi.

Kelas JavaScriptTypeResolver adalah kelas dasar untuk SimpleTypeResolver kelas , yang menyediakan implementasi pemecah masalah jenis yang menggunakan nama yang memenuhi syarat rakitan jenis terkelola.

Note

Saat menggunakan payload JSON yang JavaScriptTypeResolverdihasilkan berisi properti khusus __type . Properti ini mencakup nama jenis lengkap, termasuk namespace layanan, dari jenis target. Sebelum menggunakan resolver kustom, verifikasi bahwa nama lengkap jenis target tidak berisi informasi sensitif atau istimewa.

Catatan Bagi Implementer

Saat Anda menerapkan pemecah masalah jenis, string yang dikembalikan oleh ResolveTypeId(Type) metode harus memetakan kembali ke jenis terkelola yang sama ketika nilai string diteruskan ke ResolveType(String) metode .

Konstruktor

Nama Deskripsi
JavaScriptTypeResolver()

Menginisialisasi instans baru dari kelas JavaScriptTypeResolver.

Metode

Nama Deskripsi
Equals(Object)

Menentukan apakah objek yang ditentukan sama dengan objek saat ini.

(Diperoleh dari Object)
GetHashCode()

Berfungsi sebagai fungsi hash default.

(Diperoleh dari Object)
GetType()

Mendapatkan Type instans saat ini.

(Diperoleh dari Object)
MemberwiseClone()

Membuat salinan dangkal dari Objectsaat ini.

(Diperoleh dari Object)
ResolveType(String)

Saat ditimpa dalam kelas turunan, mengembalikan Type objek yang terkait dengan nama jenis yang ditentukan.

ResolveTypeId(Type)

Saat ditimpa dalam kelas turunan, mengembalikan nama jenis untuk objek yang ditentukan Type .

ToString()

Mengembalikan string yang mewakili objek saat ini.

(Diperoleh dari Object)

Berlaku untuk