다음을 통해 공유


BinaryFormatter 기능 참조

2002년 .NET Framework의 초기 릴리스와 함께 BinaryFormatter이(가) 처음 도입되었습니다. BinaryFormatter 사용법을 바꾸는 방법을 이해하려면 BinaryFormatter의 작동 방식을 아는 것이 도움이 됩니다.

BinaryFormatter은(는) [Serializable](으)로 주석이 달리거나 ISerializable 인터페이스를 구현한 모든 유형의 인스턴스를 직렬화할 수 있습니다.

멤버 이름

가장 일반적인 시나리오에서는 [Serializable](으)로 형식에 주석이 달리고 직렬 변환기는 리플렉션을 사용하여 주석이 추가된 필드를 제외한 모든 필드(공개 및 비공개 모두)를 [NonSerialized](으)로 직렬화합니다. 기본적으로 형식의 필드 이름과 직렬화된 멤버 이름은 일치합니다. 이로 인해 [Serializable] 형식에서 프라이빗 필드의 이름이 바뀐 경우에도 비호환성이 발생했습니다. BinaryFormatter(으)로부터 마이그레이션하는 동안 직렬화된 필드 이름이 처리되고 재정의되는 방법을 이해해야 합니다.

C# 자동 속성

C#BinaryFormatter이 아닌 C# 컴파일러에서 생성되는 지원 필드를 직렬화합니다. 직렬화된 백업 필드의 이름은 제어할 수 없으며, 잘못된 C# 문자를 포함합니다. (https://sharplab.io/ 또는 ILSpy와 같은) C# 디컴파일러는 런타임에 C# 자동 속성이 표시되는 방법을 보여 줄 수 있습니다.

[Serializable]
internal class PropertySample
{
    public string Name { get; set; }
}

이전 클래스는 C# 컴파일러에서 다음과 같이 변환됩니다.

[Serializable]
internal class PropertySample
{
    private string <Name>k__BackingField;

    public string Name
    {
        get
        {
            return <Name>k__BackingField;
        }
        set
        {
            <Name>k__BackingField = value;
        }
    }
}

이 경우, <Name>k__BackingField은(는) 직렬화된 페이로드에서 BinaryFormatter이(가) 사용하는 멤버의 이름입니다. nameof을(를) 사용하거나 다른 C# 연산자를 사용하여 이 이름을 가져올 수 없습니다.

ISerializable 인터페이스에는 사용자가 GetObjectData 메서드 중 하나를 사용하여 이름을 제어할 수 있는 AddValue 메서드가 함께 제공됩니다.

// Note lack of any special attribute.
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
    info.AddValue("Name", this.Name);
}

이와 같은 사용자 지정이 적용된 경우, 역직렬화하는 동안에도 정보를 제공해야 합니다. 이는 제공하는 Get 메서드 중 하나를 사용하여 SerializationInfo에서 모든 값을 읽고, serialization 생성자을 사용함으로써 가능합니다.

private PropertySample(SerializationInfo info, StreamingContext context)
{
    this.Name = info.GetString("Name");
}

참고 항목

nameof 연산자는 여기서 의도적으로 사용되지 않았으며, 이는 페이로드를 유지할 수 있고 나중에 속성 이름을 바꿀 수 있기 때문입니다. 따라서 이름을 바꾸더라도(LastName 속성도 도입하기로 결정했기 때문에 FirstName) 이전 버전과 호환되는 상태를 유지하려면 serialization은 여전히 어딘가에 유지될 수 있는 이전 이름을 사용해야 합니다.

Serialization 바인더

SerializationBinder을(를) 클래스 로드를 제어하고 로드할 클래스를 위임하기 위해 사용하는 것이 권장됩니다. 이렇게 하면 보안 취약성이 최소화됩니다(그러므로 공격자가 페이로드를 수정하여 다른 항목을 역직렬화하고 로드하는 경우에도 허용된 형식만 로드됩니다).

이 형식에서 상속하고 BindToType 메서드를 재정의해야 이 형식을 사용할 수 있습니다.

직렬화 가능한 형식 목록은 닫혀 있는 것이 가장 권장되며, 이는 보안 취약성을 줄이는 데 도움이 되는 인스턴스화할 수 있는 형식을 알고 있기 때문입니다.