BinaryFormatter işlevsellik başvurusu

ilk BinaryFormatter olarak 2002'de .NET Framework'ün ilk sürümüyle kullanıma sunulmuştur. kullanımını BinaryFormatterdeğiştirmeyi anlamak için nasıl BinaryFormatter çalıştığını bilmenize yardımcı olur.

BinaryFormatter ile açıklama ekleyen [Serializable] veya arabirimi uygulayan herhangi bir türün herhangi bir örneğini ISerializable seri hale getirebilir.

Üye adları

En yaygın senaryoda, türüne açıklama eklenir ve seri hale getirici, ile [Serializable] açıklama ekleyenler dışında tüm alanları[NonSerialized]için yansıma kullanır. Varsayılan olarak, serileştirilmiş üye adları türün alan adları ile eşleşecektir. Bu, geçmişte özel alanlar bile türlerde yeniden adlandırıldığında [Serializable] uyumsuzluklara yol açmıştı. 'den BinaryFormatteruzağa geçişler sırasında, seri hale getirilmiş alan adlarının nasıl işlendiğini ve geçersiz kılındığını anlamak gerekir.

C# otomatik özellikleri

C# için otomatik olarak uygulanan özellikler (){ get; set; }BinaryFormatter özellikleri değil, C# derleyicisi tarafından oluşturulan yedekleme alanlarını seri hale getirecektir. Bu serileştirilmiş yedekleme alanlarının adları geçersiz C# karakterleri içerir ve denetlenemez. C# ayrıştırıcısı (veya ILSpy gibi https://sharplab.io/), C# otomatik özelliklerinin çalışma zamanına nasıl sunulduğunu gösterebilir.

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

Önceki sınıf C# derleyicisi tarafından şu şekilde çevrilir:

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

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

Bu durumda, <Name>k__BackingField serileştirilmiş yükte kullanan BinaryFormatter üyenin adıdır. Bu adı almak için veya başka bir C# işleci kullanmak nameof mümkün değildir.

ISerializable Arabirim, kullanıcıların yöntemlerden birini GetObjectData kullanarak adları denetlemesine olanak tanıyan bir yöntemle birlikte AddValue gelir.

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

Böyle bir özelleştirme uygulanmışsa, seri durumdan çıkarma sırasında da bilgilerin sağlanması gerekir. Bu, tüm değerlerin 'den sağladığı SerializationInfo yöntemlerinden biriyle okunduğu Get kullanarak mümkündür.

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

Not

nameof Yük kalıcı hale getirilebildiği ve özelliğin daha sonra yeniden adlandırılabildiği için işleç burada amaçla kullanılmadı. Bu nedenle, geriye dönük olarak uyumlu kalmak için FirstName yeniden adlandırılsa bile (örneğin, bir LastName özelliği tanıtmaya karar verirseniz), seri hale getirme işlemi yine de bir yerde kalıcı olabilecek eski adı kullanmalıdır.

Serialization ciltçi

Sınıfın yüklenmesini denetlemek ve yüklenecek sınıfı zorunlu yapmak için kullanılması SerializationBinder önerilir. Bu, güvenlik açıklarını en aza indirir (dolayısıyla saldırgan yükü seri durumdan çıkarmak ve başka bir şey yüklemek için değiştirse bile yalnızca izin verilen türler yüklenir).

Bu türü kullanmak için ondan devralma ve yöntemini geçersiz kılma BindToType gerekir.

Serileştirilebilir türlerin listesi ideal olarak kapatılır çünkü hangi türlerin örneklenebileceğini bildiğiniz anlamına gelir ve bu da güvenlik açıklarını azaltmaya yardımcı olur.