Aracılığıyla paylaş


Bağımlılık özelliği güvenliği (WPF .NET)

Windows Presentation Foundation (WPF) özellik sistemi aracılığıyla okuma-yazma bağımlılık özelliklerinin erişilebilirliği, bunları etkin bir şekilde genel özellikler haline getirir. Sonuç olarak, okuma-yazma bağımlılık özelliği değerleri hakkında güvenlik garantileri vermek mümkün değildir. WPF özellik sistemi, yazma erişimini kısıtlayabilmek için salt okunur bağımlılık özellikleri için daha fazla güvenlik sağlar.

Önemli

.NET 7 ve .NET 6 için Masaüstü Kılavuzu belgeleri yapım aşamasındadır.

Özellik sarmalayıcılarının erişimi ve güvenliği

Özellik değerlerini almayı veya ayarlamayı basitleştirmek için genellikle okuma-yazma bağımlılık özelliği uygulamalarına ortak dil çalışma zamanı (CLR) özellik sarmalayıcısı eklenir. Dahil edilirse, CLR özellik sarmalayıcısı, temel bağımlılık özelliğiyle etkileşim kuran ve SetValue statik çağrılarını GetValue uygulayan bir kolaylık yöntemidir. Temel olarak, CLR özellik sarmalayıcı bir bağımlılık özelliğini özel alan yerine bağımlılık özelliği tarafından desteklenen bir CLR özelliği olarak kullanıma sunar.

Güvenlik mekanizmaları uygulamak ve CLR özellik sarmalayıcısına erişimi kısıtlamak kolaylık yönteminin kullanımını engelleyebilir, ancak bu teknikler veya SetValueöğesine GetValue doğrudan çağrı yapılmasını engellemez. Başka bir deyişle, okuma-yazma bağımlılık özelliğine WPF özellik sistemi üzerinden her zaman erişilebilir. Okuma-yazma bağımlılık özelliği uyguluyorsanız CLR özellik sarmalayıcısına erişimi kısıtlamaktan kaçının. Bunun yerine, çağıranların bağımlılık özelliğinin gerçek erişim düzeyini bilmesi için CLR özellik sarmalayıcısını genel üye olarak bildirin.

Bağımlılık özelliklerinin özellik sistemiyle açığa çıkarma

WPF özellik sistemi, tanımlayıcısı aracılığıyla okuma-yazma bağımlılığı özelliğine DependencyProperty erişim sağlar. Tanımlayıcı içinde kullanılabilir GetValue ve SetValue çağrıları. Statik tanımlayıcı alanı genel olmayan olsa bile, özellik sisteminin çeşitli yönleri bir DependencyProperty sınıfın veya türetilmiş sınıfın örneğinde mevcut olduğu için bir döndürür. Örneğin, GetLocalValueEnumerator yöntemi yerel olarak ayarlanmış bir değere sahip bağımlılık özelliği örnekleri için tanımlayıcıları döndürür. Ayrıca, değeri değiştirilmiş bağımlılık özelliklerinin tanımlayıcısını raporlayacak DependencyProperty olay verilerini almak için sanal yöntemi geçersiz kılabilirsinizOnPropertyChanged. Çağıranların okuma-yazma bağımlılık özelliğinin gerçek erişim düzeyini bilmesi için tanımlayıcı alanını ortak üye olarak bildirin.

Dekont

Bağımlılık özelliği tanımlayıcı alanı private olarak bildirilmesi, okuma-yazma bağımlılık özelliğinin erişilebilir olma yollarının sayısını azaltsa da, özellik CLR dil tanımına göre özel olmaz.

Doğrulama güvenliği

' Demand a ValidateValueCallback uygulamak ve doğrulamanın hata durumunda Demand başarısız olmasını beklemek, özellik değeri değişikliklerini kısıtlamak için yeterli bir güvenlik mekanizması değildir. Ayrıca, bu arayanlar uygulama etki alanı içinde çalışıyorsa, aracılığıyla ValidateValueCallback zorlanan yeni değer geçersiz kılma kötü amaçlı arayanlar tarafından gizlenebilir.

Salt okunur bağımlılık özelliklerine erişim

Erişimi kısıtlamak için yöntemini çağırarak RegisterReadOnly özelliğinizi salt okunur bağımlılık özelliği olarak kaydedin. yöntemi, RegisterReadOnly ortak olmayan bir DependencyPropertyKeysınıf alanına atayabileceğiniz bir döndürür. Salt okunur bağımlılık özellikleri için WPF özellik sistemi yalnızca başvurusu olan kişilere DependencyPropertyKeyyazma erişimi sağlar. Bu davranışı göstermek için aşağıdaki test kodu:

  • Hem okuma-yazma hem de salt okunur bağımlılık özelliklerini uygulayan bir sınıf örneği oluşturur.
  • Her tanımlayıcıya bir private erişim değiştirici atar.
  • Yalnızca erişimcileri get uygular.
  • GetLocalValueEnumerator WPF özellik sistemi aracılığıyla temel bağımlılık özelliklerine erişmek için yöntemini kullanır.
  • her bağımlılık özelliği değerine erişimi test etmek için ve SetValue çağrılarıGetValue.
    /// <summary>
    ///  Test get/set access to dependency properties exposed through the WPF property system.
    /// </summary>
    public static void DependencyPropertyAccessTests()
    {
        // Instantiate a class that implements read-write and read-only dependency properties.
        Aquarium _aquarium = new();
        // Access each dependency property using the LocalValueEnumerator method.
        LocalValueEnumerator localValueEnumerator = _aquarium.GetLocalValueEnumerator();
        while (localValueEnumerator.MoveNext())
        {
            DependencyProperty dp = localValueEnumerator.Current.Property;
            string dpType = dp.ReadOnly ? "read-only" : "read-write";
            // Test read access.
            Debug.WriteLine($"Attempting to get a {dpType} dependency property value...");
            Debug.WriteLine($"Value ({dpType}): {(int)_aquarium.GetValue(dp)}");
            // Test write access.
            try
            {
                Debug.WriteLine($"Attempting to set a {dpType} dependency property value to 2...");
                _aquarium.SetValue(dp, 2);
            }
            catch (InvalidOperationException e)
            {
                Debug.WriteLine(e.Message);
            }
            finally
            {
                Debug.WriteLine($"Value ({dpType}): {(int)_aquarium.GetValue(dp)}");
            }
        }

        // Test output:

        // Attempting to get a read-write dependency property value...
        // Value (read-write): 1
        // Attempting to set a read-write dependency property value to 2...
        // Value (read-write): 2

        // Attempting to get a read-only dependency property value...
        // Value (read-only): 1
        // Attempting to set a read-only dependency property value to 2...
        // 'FishCountReadOnly' property was registered as read-only
        // and cannot be modified without an authorization key.
        // Value (read-only): 1
    }
}

public class Aquarium : DependencyObject
{
    public Aquarium()
    {
        // Assign locally-set values.
        SetValue(FishCountProperty, 1);
        SetValue(FishCountReadOnlyPropertyKey, 1);
    }

    // Failed attempt to restrict write-access by assigning the
    // DependencyProperty identifier to a non-public field.
    private static readonly DependencyProperty FishCountProperty =
        DependencyProperty.Register(
          name: "FishCount",
          propertyType: typeof(int),
          ownerType: typeof(Aquarium),
          typeMetadata: new PropertyMetadata());

    // Successful attempt to restrict write-access by assigning the
    // DependencyPropertyKey to a non-public field.
    private static readonly DependencyPropertyKey FishCountReadOnlyPropertyKey =
        DependencyProperty.RegisterReadOnly(
          name: "FishCountReadOnly",
          propertyType: typeof(int),
          ownerType: typeof(Aquarium),
          typeMetadata: new PropertyMetadata());

    // Declare public get accessors.
    public int FishCount => (int)GetValue(FishCountProperty);
    public int FishCountReadOnly => (int)GetValue(FishCountReadOnlyPropertyKey.DependencyProperty);
}
    ''' <summary>
    ''' ' Test get/set access to dependency properties exposed through the WPF property system.
    ''' </summary>
    Public Shared Sub DependencyPropertyAccessTests()
        ' Instantiate a class that implements read-write and read-only dependency properties.
        Dim _aquarium As New Aquarium()
        ' Access each dependency property using the LocalValueEnumerator method.
        Dim localValueEnumerator As LocalValueEnumerator = _aquarium.GetLocalValueEnumerator()
        While localValueEnumerator.MoveNext()
            Dim dp As DependencyProperty = localValueEnumerator.Current.[Property]
            Dim dpType As String = If(dp.[ReadOnly], "read-only", "read-write")
            ' Test read access.
            Debug.WriteLine($"Attempting to get a {dpType} dependency property value...")
            Debug.WriteLine($"Value ({dpType}): {CInt(_aquarium.GetValue(dp))}")
            ' Test write access.
            Try
                Debug.WriteLine($"Attempting to set a {dpType} dependency property value to 2...")
                _aquarium.SetValue(dp, 2)
            Catch e As InvalidOperationException
                Debug.WriteLine(e.Message)
            Finally
                Debug.WriteLine($"Value ({dpType}): {CInt(_aquarium.GetValue(dp))}")
            End Try
        End While

        ' Test output

        ' Attempting to get a read-write dependency property value...
        ' Value (read-write): 1
        ' Attempting to set a read-write dependency property value to 2...
        ' Value (read-write): 2

        ' Attempting to get a read-only dependency property value...
        ' Value (read-only): 1
        ' Attempting to set a read-only dependency property value to 2...
        ' 'FishCountReadOnly' property was registered as read-only
        ' and cannot be modified without an authorization key.
        ' Value (read-only): 1
    End Sub

End Class

Public Class Aquarium
    Inherits DependencyObject

    Public Sub New()
        ' Assign locally-set values.
        SetValue(FishCountProperty, 1)
        SetValue(FishCountReadOnlyPropertyKey, 1)
    End Sub

    ' Failed attempt to restrict write-access by assigning the
    ' DependencyProperty identifier to a non-public field.
    Private Shared ReadOnly FishCountProperty As DependencyProperty =
        DependencyProperty.Register(
            name:="FishCount",
            propertyType:=GetType(Integer),
            ownerType:=GetType(Aquarium),
            typeMetadata:=New PropertyMetadata())

    ' Successful attempt to restrict write-access by assigning the
    ' DependencyPropertyKey to a non-public field.
    Private Shared ReadOnly FishCountReadOnlyPropertyKey As DependencyPropertyKey =
        DependencyProperty.RegisterReadOnly(
            name:="FishCountReadOnly",
            propertyType:=GetType(Integer),
            ownerType:=GetType(Aquarium),
            typeMetadata:=New PropertyMetadata())

    ' Declare public get accessors.
    Public ReadOnly Property FishCount As Integer
        Get
            Return GetValue(FishCountProperty)
        End Get
    End Property

    Public ReadOnly Property FishCountReadOnly As Integer
        Get
            Return GetValue(FishCountReadOnlyPropertyKey.DependencyProperty)
        End Get
    End Property

End Class

Ayrıca bkz.