JavaScriptTypeResolver 클래스
정의
중요
일부 정보는 릴리스되기 전에 상당 부분 수정될 수 있는 시험판 제품과 관련이 있습니다. Microsoft는 여기에 제공된 정보에 대해 어떠한 명시적이거나 묵시적인 보증도 하지 않습니다.
사용자 지정 형식 확인자를 구현하기 위한 추상 기본 클래스를 제공합니다.
public ref class JavaScriptTypeResolver abstract
public abstract class JavaScriptTypeResolver
type JavaScriptTypeResolver = class
Public MustInherit Class JavaScriptTypeResolver
- 상속
-
JavaScriptTypeResolver
- 파생
예제
다음 예제에서는 사용자 지정 JavaScriptTypeResolver 을 만드는 방법 및 개체를 직렬화하거나 역직렬화하는 데 사용하는 방법을 보여줍니다.
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?");
}
}
}
이전 앱은 가독성을 위해 형식이 지정된 콘솔에 다음을 출력합니다.
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]
앞의 샘플에서 형식은 Adult 형식을 Person 서브클래싱합니다. 사용자 지정 JavaScriptTypeResolver 은 생성된 JSON 페이로드의 일부로 형식 정보를 포함하는 데 사용됩니다. 이렇게 하면 JSON 페이로드를 다시 .NET 개체 그래프로 역직렬화할 때 다형성이 제한됩니다. 페이로드는 기본 Person 인스턴스 또는 파생 Adult 인스턴스를 호출자에게 다시 반환할지 여부를 제어할 수 있습니다.
이 샘플은 역직렬화를 제어하는 메커니즘을 allow-list 사용하기 때문에 안전합니다. 코드:
- 허용된 형식의
CustomTypeResolver명시적 목록을 사용하여 초기화합니다. - deserialization 프로세스를 승인된 형식 목록으로만 제한합니다. 이 제한은 원격 클라이언트가 JSON 페이로드에서 악성
__type을 지정하고 서버를 속여 위험한 형식을 역직렬화하는 역직렬화 공격을 방지합니다.
앱은 최상위 배열의 일부로 인스턴스를 Adult 역직렬화할 것으로 예상 Person 하지만 다음 때문에 허용 목록에 추가 Address 해야 합니다.
- 개체 그래프의
Person일부로 직렬화하거나Adult직렬화Address합니다. - 개체 그래프에 있을 수 있는 모든 형식은 허용 목록에서 고려해야 합니다. 기본 형식은
intstring지정하지 않아도 됩니다.
Warning
메서드 내에서 ResolveType 호출 Type.GetType(id) 하지 마세요. 이로 인해 앱에 보안 부가가 발생할 수 있습니다. 대신, 이전 샘플과 같이 허용된 형식 목록을 반복하고 해당 속성을 들어오는 id형식과 비교 Type.FullName 합니다.
설명
클래스는 JavaScriptTypeResolver 다음에 대한 서비스를 제공합니다.
메서드를 통해 관리되는 형식 정보를 문자열 값으로 변환합니다 ResolveTypeId .
메서드를 통해 ResolveType 문자열 값을 적절한 관리형 형식으로 다시 확인합니다.
개체가 JavaScriptSerializer 사용자 지정 형식을 직렬화할 때 형식 정보가 포함된 값을 직렬화된 JSON(JavaScript Object Notation) 문자열에 선택적으로 포함할 수 있습니다. 역직렬화하는 JavaScriptSerializer 동안 이 문자열 값을 참조하여 JSON 문자열이 변환될 적절한 관리되는 형식을 결정할 수 있습니다.
인스턴스에 JavaScriptSerializer 형식 확인자를 제공하는 경우 serializer는 serialization 및 ResolveType deserialization 프로세스 중에 각각 관리되는 형식과 문자열 값 간에 매핑하는 데 해당 및 메서드를 사용합니다ResolveTypeId.
클래스는 JavaScriptTypeResolver 관리되는 형식 어셈블리 정규화된 이름을 사용하는 형식 확인자의 구현을 제공하는 클래스의 기본 클래스 SimpleTypeResolver 입니다.
메모
사용 시 JavaScriptTypeResolver결과 JSON 페이로드에는 특수 __type 속성이 포함됩니다. 이 속성에는 대상 형식의 네임스페이스를 포함한 전체 형식 이름이 포함됩니다. 사용자 지정 확인자를 사용하기 전에 대상 형식의 전체 이름에 중요한 정보나 권한 있는 정보가 포함되어 있지 않은지 확인합니다.
구현자 참고
형식 확인자를 구현할 때 메서드에서 반환 ResolveTypeId(Type) 되는 문자열은 문자열 값이 메서드에 전달될 때 동일한 관리되는 형식으로 ResolveType(String) 다시 매핑되어야 합니다.
생성자
| Name | Description |
|---|---|
| JavaScriptTypeResolver() |
JavaScriptTypeResolver 클래스의 새 인스턴스를 초기화합니다. |
메서드
| Name | Description |
|---|---|
| Equals(Object) |
지정한 개체와 현재 개체가 같은지 여부를 확인합니다. (다음에서 상속됨 Object) |
| GetHashCode() |
기본 해시 함수로 작동합니다. (다음에서 상속됨 Object) |
| GetType() |
현재 인스턴스의 Type 가져옵니다. (다음에서 상속됨 Object) |
| MemberwiseClone() |
현재 Object단순 복사본을 만듭니다. (다음에서 상속됨 Object) |
| ResolveType(String) |
파생 클래스에서 재정의 Type 된 경우 지정된 형식 이름과 연결된 개체를 반환합니다. |
| ResolveTypeId(Type) |
파생 클래스에서 재정의되는 경우 지정된 Type 개체의 형식 이름을 반환합니다. |
| ToString() |
현재 개체를 나타내는 문자열을 반환합니다. (다음에서 상속됨 Object) |