Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
In diesem Artikel erfahren Sie, wie Sie Ihre Windows Forms-Zwischenablage und Drag-and-Drop-Vorgänge auf die neuen typsicheren APIs in .NET 10 aktualisieren. Sie erfahren, wie Sie die neuen Clipboard.TryGetData und Clipboard.SetDataAsJson<T>(String, T) Methoden verwenden, verstehen, welche integrierten Typen ohne Änderungen funktionieren, und Strategien für die Behandlung von benutzerdefinierten Typen und Legacydaten nach dem Entfernen von BinaryFormatter.
BinaryFormatter wurde aufgrund von Sicherheitsrisiken aus der Laufzeit in .NET 9 entfernt. Diese Änderung hat die Zwischenablage- und Drag-and-Drop-Vorgänge mit benutzerdefinierten Objekten gestört. .NET 10 führt neue APIs ein, die JSON-Serialisierung und typsichere Methoden verwenden, um diese Funktionalität wiederherzustellen, die Sicherheit zu verbessern und eine bessere Fehlerbehandlung und prozessübergreifende Kompatibilität zu bieten.
Clipboard.SetData(String, Object) funktioniert nicht mehr mit benutzerdefinierten Typen, die BinaryFormatter für die Serialisierung erfordern. Diese Methode führt einen Kopiervorgang (standardmäßig) durch, der Daten sofort serialisiert, diese Serialisierung schlägt jedoch jetzt für Typen fehl, die BinaryFormatter benötigt werden, da sie entfernt wurden.
Clipboard.GetData(String) ist in .NET 10 veraltet. Wenn BinaryFormatter für die Deserialisierung erforderlich ist, aber nicht aktiviert wurde, gibt GetData() eine NotSupportedException Instanz zurück. Verwenden Sie die neuen Clipboard.TryGetData und Clipboard.SetDataAsJson<T>(String, T) Methoden für typsichere Vorgänge und JSON-Serialisierung von benutzerdefinierten Objekten.
Die folgenden Abschnitte enthalten detaillierte Anleitungen zur Migration, erläutern, welche Typen ohne Änderungen funktionieren, und zeigen, wie sowohl neue Entwicklungs- als auch Legacydatenszenarien behandelt werden.
Voraussetzungen
Bevor Sie fortfahren, lesen Sie die folgenden Konzepte:
- Wie Anwendungen
BinaryFormatterin Zwischenablage- und Drag-and-Drop-Szenarien bis .NET 9 verwendet wurden. - Die Sicherheitslücken, die zur Entfernung von
BinaryFormatterführten. - So arbeiten Sie mit
System.Text.JsonSerialisierungsmustern und deren Einschränkungen.
Weitere Informationen finden Sie in den folgenden Artikeln:
- Deserialisierungsrisiken bei Verwendung von BinaryFormatter und verwandten Typen.
- BinaryFormatter-Migrationshandbuch.
Entfernen von Änderungen von BinaryFormatter
Das BinaryFormatter Entfernen in .NET 9 ändert grundlegend, wie Windows Forms Zwischenablage- und Drag-and-Drop-Vorgänge mit benutzerdefinierten Typen verarbeitet. Diese Änderungen wirken sich auf vorhandene Codemuster aus und erfordern eine sorgfältige Migration zur Aufrechterhaltung der Funktionalität.
Benutzerdefinierte Typen serialisieren nicht mehr automatisch
In .NET 8 und früheren Versionen können Sie jedes serialisierbare benutzerdefinierte Objekt in der Zwischenablage platzieren, indem Sie die Datei aufrufen SetData(). Die BinaryFormatter behandelte die Serialisierung automatisch. Ab .NET 9 führt SetData() weiterhin einen Kopiervorgang aus, der Daten sofort serialisiert, aber diese Serialisierung schlägt für Typen fehl, die BinaryFormatter erfordern, weil BinaryFormatter entfernt wurde.
Der folgende Code funktioniert nicht mehr:
[Serializable]
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
}
public static void BrokenCustomTypeExample()
{
// This worked in .NET 8 and earlier but silently fails starting with .NET 9
Person person = new Person { Name = "John", Age = 30 };
Clipboard.SetData("MyApp.Person", person); // No data is stored
// Later attempts to retrieve the data return a NotSupportedException instance
object data = Clipboard.GetData("MyApp.Person");
}
<Serializable>
Public Class Person
Public Property Name As String
Public Property Age As Integer
End Class
Public Shared Sub BrokenCustomTypeExample()
' This worked in .NET 8 and earlier but silently fails starting with .NET 9
Dim person As New Person With {.Name = "John", .Age = 30}
Clipboard.SetData("MyApp.Person", person) ' No data is stored
' Later attempts to retrieve the data return a NotSupportedException instance
Dim data As Object = Clipboard.GetData("MyApp.Person")
End Sub
Was Möglicherweise angezeigt wird
- Die
SetData()Methode wird abgeschlossen, ohne eine Ausnahme zu auslösen. - Die Daten werden in der Zwischenablage platziert, aber die Serialisierung schlägt bei Typen fehl, die
BinaryFormatterbenötigen. - Spätere Versuche, die Daten mit
GetData()abzurufen, führen zu einer NotSupportedException-Instanz, die angibt, dassBinaryFormattererforderlich, aber nicht aktiviert ist.
Migrationsleitfaden
Verwenden Sie die neue SetDataAsJson<T>() Methode, oder serialisieren Sie manuell auf ein string oder byte[]. Ausführliche Informationen finden Sie im Abschnitt "Arbeiten mit benutzerdefinierten Typen ".
GetData() ist veraltet - verwenden Sie stattdessen TryGetData<T>()
Die Legacymethode GetData() ist in .NET 10 veraltet. Diese Methode gibt in den meisten Fällen erfolgreich Daten zurück. Wenn jedoch BinaryFormatter für die Deserialisierung erforderlich ist und nicht aktiviert wurde, gibt GetData() eine Instanz zurück, die darauf hinweist, dass BinaryFormatter erforderlich ist. Sie sollten zu den neuen typsicheren TryGetData<T>() Methoden migrieren, um eine bessere Fehlerbehandlung und Typsicherheit zu gewährleisten.
Das folgende Beispiel zeigt das veraltete Muster, das Sie vermeiden sollten:
public static void ObsoleteGetDataExample()
{
// Don't use - GetData() is obsolete in .NET 10
object data = Clipboard.GetData("MyApp.Person"); // Obsolete method
// Returns a NotSupportedException instance for a custom object type
if (data is Person person)
{
Console.WriteLine($"Processing person: {person.Name}, Age: {person.Age}");
}
}
Public Shared Sub ObsoleteGetDataExample()
' Don't use - GetData() is obsolete in .NET 10
Dim data As Object = Clipboard.GetData("MyApp.Person") ' Obsolete method
' Returns a NotSupportedException instance for a custom object type
If TypeOf data Is Person Then
Dim person As Person = DirectCast(data, Person)
Console.WriteLine($"Processing person: {person.Name}, Age: {person.Age}")
End If
End Sub
Verwenden Sie stattdessen den modernen typsicheren Ansatz mit TryGetData<T>():
public static void ModernTryGetDataExample()
{
var data = new Person { Name = "Alice", Age = 28 };
Clipboard.SetDataAsJson("MyAppData", data);
// Use this - type-safe approach with TryGetData<T>()
if (Clipboard.TryGetData("MyApp.Person", out Person person))
{
// person is guaranteed to be the correct type
Console.WriteLine($"Processing person: {person.Name}, Age: {person.Age}");
}
else
{
// Handle the case where data isn't available or is the wrong type
MessageBox.Show("Unable to retrieve person data from clipboard");
}
}
Public Shared Sub ModernTryGetDataExample()
Dim data As New Person With {.Name = "Alice", .Age = 30}
Clipboard.SetDataAsJson("MyAppData", data)
' Use this - type-safe approach with TryGetData(Of T)()
Dim person As Person = Nothing
If Clipboard.TryGetData("MyApp.Person", person) Then
' person is guaranteed to be the correct type
Console.WriteLine($"Processing person: {person.Name}, Age: {person.Age}")
Else
' Handle the case where data isn't available or is the wrong type
MessageBox.Show("Unable to retrieve person data from clipboard")
End If
End Sub
Vorteile von TryGetData<T>()
- Typsicherheit: Keine Umwandlung erforderlich – die Methode gibt den genauen Typ zurück, den Sie anfordern.
- Klare Fehlerbehandlung: Gibt einen booleschen Erfolgsindikator zurück, anstatt null- oder Ausnahmemuster zu verwenden.
- Zukunftssicher: Entwickelt für die Arbeit mit neuen Serialisierungsmethoden und Legacydatenunterstützung.
Identifizieren des betroffenen Codes
Suchen nach:
- Alle
GetData()Aufrufe, da die gesamte Methode unabhängig vom Datentyp veraltet ist. -
DataObject.GetData()undIDataObject.GetData()Verwendung in Drag-and-Drop-Vorgängen.
Migrationsleitfaden
Ersetzen Sie alle GetData() Verwendungen durch typsichere TryGetData<T>() Methoden. Umfassende Beispiele für alle Überladungen finden Sie im Abschnitt " Neue typsichere APIs ".
Neue typsichere APIs
.NET 10 führt drei neue API-Familien ein, die Typsicherheit, bessere Fehlerbehandlung und JSON-Serialisierungsunterstützung für Zwischenablage- und Drag-and-Drop-Vorgänge bieten:
- TryGetData Methoden zum Abrufen von Daten
- SetDataAsJson<T>(String, T) Methoden zum Speichern von Daten
- ITypedDataObject Schnittstelle für Drag-and-Drop-Vorgänge
TryGetData<T>() -Methoden
Die TryGetData<T>() Familie ersetzt die veraltete GetData() Methode. Es bietet ein typensicheres Abrufen und eine klare Erfolg- oder Fehleranzeige für Ihre Zwischenablageoperationen.
Einfacher typsicherer Abruf
public static void BasicTypeSafeRetrievalExamples()
{
// Retrieve text data using a standard format
if (Clipboard.TryGetData(DataFormats.Text, out string textData))
Console.WriteLine($"Text: {textData}");
// Retrieve an integer using a custom format
if (Clipboard.TryGetData("NumberData", out int numberData))
Console.WriteLine($"Number: {numberData}");
// Retrieve Unicode text using a standard format
if (Clipboard.TryGetData(DataFormats.UnicodeText, out string unicodeText))
Console.WriteLine($"Unicode: {unicodeText}");
// Retrieve raw text data with OLE conversion control
if (Clipboard.TryGetData(DataFormats.Text, out string rawText))
Console.WriteLine($"Raw: {rawText}");
// Retrieve file drops using a standard format
if (Clipboard.TryGetData(DataFormats.FileDrop, out string[] files))
Console.WriteLine($"Files: {string.Join(", ", files)}");
}
Public Shared Sub BasicTypeSafeRetrievalExamples()
' Retrieve text data using a standard format
Dim textData As String = Nothing
If Clipboard.TryGetData(DataFormats.Text, textData) Then
Console.WriteLine($"Text: {textData}")
End If
' Retrieve an integer using a custom format
Dim numberData As Integer
If Clipboard.TryGetData("NumberData", numberData) Then
Console.WriteLine($"Number: {numberData}")
End If
' Retrieve Unicode text using a standard format
Dim unicodeText As String = Nothing
If Clipboard.TryGetData(DataFormats.UnicodeText, unicodeText) Then
Console.WriteLine($"Unicode: {unicodeText}")
End If
' Retrieve raw text data with OLE conversion control
Dim rawText As String = Nothing
If Clipboard.TryGetData(DataFormats.Text, rawText) Then
Console.WriteLine($"Raw: {rawText}")
End If
' Retrieve file drops using a standard format
Dim files As String() = Nothing
If Clipboard.TryGetData(DataFormats.FileDrop, files) Then
Console.WriteLine($"Files: {String.Join(", ", files)}")
End If
End Sub
Benutzerdefinierte JSON-Typen
public static void CustomJsonTypesExamples()
{
// Retrieve a custom type stored with SetDataAsJson<T>()
if (Clipboard.TryGetData("Person", out Person person))
Console.WriteLine($"Person: {person.Name}");
// Retrieve application-specific data formats
if (Clipboard.TryGetData("MyApp.Settings", out AppSettings settings))
Console.WriteLine($"Settings: {settings.Theme}");
// Retrieve complex custom objects
if (Clipboard.TryGetData("DocumentData", out DocumentInfo doc))
Console.WriteLine($"Document: {doc.Title}");
}
Public Shared Sub CustomJsonTypesExamples()
' Retrieve a custom type stored with SetDataAsJson(Of T)()
Dim person As Person = Nothing
If Clipboard.TryGetData("Person", person) Then
Console.WriteLine($"Person: {person.Name}")
End If
' Retrieve application-specific data formats
Dim settings As AppSettings = Nothing
If Clipboard.TryGetData("MyApp.Settings", settings) Then
Console.WriteLine($"Settings: {settings.Theme}")
End If
' Retrieve complex custom objects
Dim doc As DocumentInfo = Nothing
If Clipboard.TryGetData("DocumentData", doc) Then
Console.WriteLine($"Document: {doc.Title}")
End If
End Sub
SetDataAsJson<T>() -Methoden
Diese Methoden bieten eine automatische JSON-Serialisierung mit typsicherem Speicher durch System.Text.Json.
Angeben eines benutzerdefinierten Formats
public static void CustomFormatExample()
{
var settings = new AppSettings { Theme = "Dark", AutoSave = true };
// Use a custom format for better organization
Clipboard.SetDataAsJson("MyApp.Settings", settings);
}
Public Shared Sub CustomFormatExample()
Dim settings As New AppSettings With {.Theme = "Dark", .AutoSave = True}
' Use a custom format for better organization
Clipboard.SetDataAsJson("MyApp.Settings", settings)
End Sub
Automatische Format-Ableitung
Durch Angeben des Typnamens als Datenformat TryGetData<T> kann das Format automatisch ableiten:
public static void AutomaticFormatInferenceExample()
{
var person = new Person { Name = "Alice", Age = 25 };
// Use the type name as the format
Clipboard.SetDataAsJson(typeof(Person).FullName, person);
// Retrieve the data and infer the format automatically
if (Clipboard.TryGetData(out Person retrievedPerson))
{
Console.WriteLine($"Retrieved: {retrievedPerson.Name}");
}
}
Public Shared Sub AutomaticFormatInferenceExample()
Dim person As New Person With {.Name = "Alice", .Age = 25}
' Use the type name as the format
Clipboard.SetDataAsJson(GetType(Person).FullName, person)
' Retrieve the data and infer the format automatically
Dim retrievedPerson As Person = Nothing
If Clipboard.TryGetData(retrievedPerson) Then
Console.WriteLine($"Retrieved: {retrievedPerson.Name}")
End If
End Sub
ITypedDataObject-Schnittstelle
Die
Ab .NET 10 wird DataObject (ein allgemeiner Typ in Drag-and-Drop-Szenarien) ITypedDataObject implementieren.
Verwenden von ITypedDataObject in Drag-and-Drop-Szenarien
private void OnDragDrop(object sender, DragEventArgs e)
{
if (e.Data is ITypedDataObject typedData)
{
// Retrieve files from drag data using a standard format
if (typedData.TryGetData(DataFormats.FileDrop, out string[] files))
Console.WriteLine($"Dropped files: {string.Join(", ", files)}");
// Retrieve text using a standard format
if (typedData.TryGetData(DataFormats.Text, out string text))
Console.WriteLine($"Dropped text: {text}");
// Retrieve custom items using an application-specific format
if (typedData.TryGetData("CustomItem", out MyItem item))
Console.WriteLine($"Dropped custom item: {item.Name} = {item.Value}");
}
}
Private Sub OnDragDrop(sender As Object, e As DragEventArgs)
If TypeOf e.Data Is ITypedDataObject Then
Dim typedData As ITypedDataObject = CType(e.Data, ITypedDataObject)
' Retrieve files from drag data using a standard format
Dim files As String() = Nothing
If typedData.TryGetData(DataFormats.FileDrop, files) Then
Console.WriteLine($"Dropped files: {String.Join(", ", files)}")
End If
' Retrieve text using a standard format
Dim text As String = Nothing
If typedData.TryGetData(DataFormats.Text, text) Then
Console.WriteLine($"Dropped text: {text}")
End If
' Retrieve custom items using an application-specific format
Dim item As MyItem = Nothing
If typedData.TryGetData("CustomItem", item) Then
Console.WriteLine($"Dropped custom item: {item.Name} = {item.Value}")
End If
End If
End Sub
Typen, die keine JSON-Serialisierung erfordern
Viele integrierte .NET-Typen funktionieren mit Zwischenablagevorgängen, ohne dass eine JSON-Serialisierung oder BinaryFormatter-Unterstützung erforderlich ist. Diese Typen serialisieren automatisch in das .NET Remoting Binary Format (NRBF), das eine effiziente Speicherung bietet und die Typsicherheit gewährleistet.
Diese Typen verwenden NRBF, dasselbe effiziente Binärformat, das von der Legacyversion BinaryFormatterverwendet wird. DIE NRBF-Serialisierung bietet die folgenden wichtigsten Vorteile:
- Kompakte binäre Darstellung: Ermöglicht eine effiziente Speicherung und Übertragung.
- Integrierte Typinformationen: Behält genaue .NET-Typen während Roundtrip-Vorgängen bei.
- Prozessübergreifende Kompatibilität: Funktioniert zwischen verschiedenen .NET-Anwendungen.
- Automatische Serialisierung: Typen serialisieren ohne benutzerdefinierten Code.
Hinweis
Methoden wie SetData() führen einen Kopiervorgang aus, der Daten sofort serialisiert und so sicherstellt, dass Zwischenablagedaten auch nach dem Beenden des aktuellen Prozesses beibehalten werden. Wenn Sie den DataObject Typ direkt mit SetDataObject(dataObject, copy)verwenden, können Sie steuern, wann die Serialisierung auftritt. Durch Festlegen des copy Parameters auf true (Standard) wird die sofortige Serialisierung erzwungen, während false die Serialisierung zurückverzögert wird, bis sie erforderlich ist. Wenn copy auf false festgelegt ist und die Daten im selben Prozess abgerufen werden, ist die Serialisierung möglicherweise nicht erforderlich, aber die Daten bleiben nach dem Beenden des Prozesses nicht erhalten.
Technische Details finden Sie in der .NET Remoting Binary Format-Spezifikation.
Klassen, die NRBF-codierte Daten unterstützen, werden im System.Formats.Nrbf Namespace implementiert.
Typsicherheitsgarantien
Windows Forms bietet mehrere Sicherheitsmechanismen für diese integrierten Typen:
- Exakter Typabgleich. TryGetData gibt nur den angeforderten Typ zurück.
- Automatische Überprüfung. Windows Forms überprüft während der Deserialisierung die Typkompatibilität.
- Keine beliebige Codeausführung. Im Gegensatz zu benutzerdefinierten Typen mit BinaryFormatter können diese Typen keinen schädlichen Code ausführen.
- Inhaltsüberprüfung erforderlich. Sie müssen weiterhin Dateninhalte und -bereiche für Ihre Anwendungslogik überprüfen.
- Keine Größenbeschränkungen. Große Arrays oder Bitmaps sind nicht automatisch eingeschränkt. Überwachen sie die Speicherauslastung.
Unterstützte Grundtypen
Die folgenden Grundtypen funktionieren nahtlos mit Zwischenablage und DataObject Vorgängen. Sie benötigen keine benutzerdefinierte Serialisierung oder Konfiguration. Das Zwischenablagesystem behandelt diese integrierten .NET-Typen automatisch:
-
bool,byte,char,decimal,double,short,intundlong. -
sbyte,ushort,uint,ulong,floatundstring. -
TimeSpanundDateTime.
Die folgenden Beispiele zeigen, wie diese Grundtypen direkt mit SetData() und TryGetData<T>() Methoden funktionieren:
public static void PrimitiveTypesExample()
{
// Numeric types
Clipboard.SetData("MyInt", 42);
Clipboard.SetData("MyDouble", 3.14159);
Clipboard.SetData("MyDecimal", 123.45m);
// Text and character types
Clipboard.SetData("MyString", "Hello World");
Clipboard.SetData("MyChar", 'A');
// Boolean and date/time types
Clipboard.SetData("MyBool", true);
Clipboard.SetData("MyDateTime", DateTime.Now);
Clipboard.SetData("MyTimeSpan", TimeSpan.FromMinutes(30));
// Later retrieval with type safety
if (Clipboard.TryGetData("MyTimeSpan", out TimeSpan value))
{
Console.WriteLine($"Clipboard value is: {value}");
}
}
Public Shared Sub PrimitiveTypesExample()
' Numeric types
Clipboard.SetData("MyInt", 42)
Clipboard.SetData("MyDouble", 3.14159)
Clipboard.SetData("MyDecimal", 123.45D)
' Text and character types
Clipboard.SetData("MyString", "Hello World")
Clipboard.SetData("MyChar", "A"c)
' Boolean and date/time types
Clipboard.SetData("MyBool", True)
Clipboard.SetData("MyDateTime", DateTime.Now)
Clipboard.SetData("MyTimeSpan", TimeSpan.FromMinutes(30))
' Later retrieval with type safety
Dim value As TimeSpan
If Clipboard.TryGetData("MyTimeSpan", value) Then
Console.WriteLine($"Clipboard value is: {value}")
End If
End Sub
Eine Sammlung primitiver Typen
Arrays und generische Listen unterstützter Grundtypen funktionieren ohne zusätzliche Konfiguration. Beachten Sie jedoch die folgenden Einschränkungen:
- Alle Array- und Listenelemente müssen grundtyptypen unterstützt werden.
- Vermeiden Sie
string[]undList<string>, da das NRBF-Format die Verarbeitung von Nullwerten in Zeichenfolgenauflistungen komplex macht. - Speichern Sie Zeichenfolgen einzeln oder verwenden Sie die JSON-Serialisierung für Zeichenfolgensammlungen.
Die folgenden Beispiele zeigen, wie Arrays und Listen in der Zwischenablage festgelegt werden können:
public static void CollectionsExample()
{
// Arrays of primitive types
int[] numbers = { 1, 2, 3, 4, 5 };
Clipboard.SetData("NumberArray", numbers);
double[] coordinates = { 1.0, 2.5, 3.7 };
Clipboard.SetData("Coordinates", coordinates);
// Generic lists
List<int> intList = new List<int> { 10, 20, 30 };
Clipboard.SetData("IntList", intList);
// Retrieval maintains type safety
if (Clipboard.TryGetData("NumberArray", out int[] retrievedNumbers))
{
Console.WriteLine($"Numbers: {string.Join(", ", retrievedNumbers)}");
}
}
Public Shared Sub CollectionsExample()
' Arrays of primitive types
Dim numbers As Integer() = {1, 2, 3, 4, 5}
Clipboard.SetData("NumberArray", numbers)
Dim coordinates As Double() = {1.0, 2.5, 3.7}
Clipboard.SetData("Coordinates", coordinates)
' Generic lists
Dim intList As New List(Of Integer) From {10, 20, 30}
Clipboard.SetData("IntList", intList)
' Retrieval maintains type safety
Dim retrievedNumbers As Integer() = Nothing
If Clipboard.TryGetData("NumberArray", retrievedNumbers) Then
Console.WriteLine($"Numbers: {String.Join(", ", retrievedNumbers)}")
End If
End Sub
System.Drawing-Typen
Allgemeine Grafiktypen aus dem System.Drawing Namespace funktionieren nahtlos mit Zwischenablage und DataObject Vorgängen. Diese Typen sind nützlich für Anwendungen, die mit visuellen Elementen arbeiten und zeichnungsbezogene Daten zwischen Komponenten oder Anwendungen übertragen müssen. Beachten Sie, dass die Serialisierung eines Bitmap eine große Menge an Arbeitsspeicher verbrauchen kann, insbesondere bei großen Bildern. Die folgenden Typen werden unterstützt:
-
Point,PointF,Rectangle,RectangleF. -
Size,SizeF,Color. -
Bitmap(kann bei Serialisierung erheblichen Speicher beanspruchen).
Die folgenden Beispiele zeigen, wie diese Grafikarten mit Zwischenablagevorgängen verwendet werden können.
public static void SystemDrawingTypesExample()
{
// Geometric types
Point location = new Point(100, 200);
Rectangle bounds = new Rectangle(0, 0, 500, 300);
Size dimensions = new Size(800, 600);
Clipboard.SetData("Location", location);
Clipboard.SetData("Bounds", bounds);
Clipboard.SetData("Size", dimensions);
// Color information
Color backgroundColor = Color.FromArgb(255, 128, 64, 192);
Clipboard.SetData("BackColor", backgroundColor);
// Bitmap data (use with caution for large images)
Bitmap smallIcon = new Bitmap(16, 16);
Clipboard.SetData("Icon", smallIcon);
}
Public Shared Sub SystemDrawingTypesExample()
' Geometric types
Dim location As New Point(100, 200)
Dim bounds As New Rectangle(0, 0, 500, 300)
Dim dimensions As New Size(800, 600)
Clipboard.SetData("Location", location)
Clipboard.SetData("Bounds", bounds)
Clipboard.SetData("Size", dimensions)
' Color information
Dim backgroundColor As Color = Color.FromArgb(255, 128, 64, 192)
Clipboard.SetData("BackColor", backgroundColor)
' Bitmap data (use with caution for large images)
Dim smallIcon As New Bitmap(16, 16)
Clipboard.SetData("Icon", smallIcon)
End Sub
Arbeiten mit benutzerdefinierten Typen
Wenn Sie SetDataAsJson<T>(String, T) und TryGetData mit benutzerdefinierten Typen verwenden, behandelt System.Text.Json die Serialisierung automatisch. Viele Typen funktionieren ohne spezielle Konfiguration – Datensätze, einfache Klassen und Strukturen mit öffentlichen Eigenschaften serialisieren nahtlos.
Einfache Typen, die ohne Attribute funktionieren
Die einfachsten benutzerdefinierten Typen erfordern keine spezielle Konfiguration:
// Records work without any attributes.
public record PersonInfo(string Name, int Age, string Email);
// Simple classes serialize all public properties automatically.
public class DocumentMetadata
{
public string Title { get; set; }
public DateTime Created { get; set; }
public string Author { get; set; }
}
// Structs with public properties work seamlessly.
public struct Point3D
{
public double X { get; set; }
public double Y { get; set; }
public double Z { get; set; }
}
' Simple classes serialize all public properties automatically.
Public Class DocumentMetadata
Public Property Title As String
Public Property Created As DateTime
Public Property Author As String
End Class
' Structs with public properties work seamlessly.
Public Structure Point3D
Public Property X As Double
Public Property Y As Double
Public Property Z As Double
End Structure
Verwenden von JSON-Attributen für erweiterte Steuerelemente
Verwenden Sie System.Text.Json Attribute nur, wenn Sie das Serialisierungsverhalten anpassen müssen. Umfassende Anleitungen zur System.Text.Json Serialisierung, Attributen und erweiterten Konfigurationsoptionen finden Sie unter JSON-Serialisierung und Deserialisierung in .NET.
Das folgende Beispiel zeigt, wie Sie JSON-Attribute verwenden können, um die Serialisierung zu steuern:
public class ClipboardFriendlyType
{
// Include a field that normally isn't serialized
[JsonInclude]
private int _privateData;
// Public properties are always serialized
public string Name { get; set; }
// Exclude sensitive or non-essential data
[JsonIgnore]
public string InternalId { get; set; }
// Handle property name differences for compatibility
[JsonPropertyName("display_text")]
public string DisplayText { get; set; }
// Control null value handling
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public string OptionalField { get; set; }
}
Public Class ClipboardFriendlyType
' Include a field that normally isn't serialized
<JsonInclude>
Private _privateData As Integer
' Public properties are always serialized
Public Property Name As String
' Exclude sensitive or non-essential data
<JsonIgnore>
Public Property InternalId As String
' Handle property name differences for compatibility
<JsonPropertyName("display_text")>
Public Property DisplayText As String
' Control null value handling
<JsonIgnore(Condition:=JsonIgnoreCondition.WhenWritingNull)>
Public Property OptionalField As String
End Class
Example: Zwischenablagevorgänge mit benutzerdefinierten Typen
public static void CustomTypesClipboardOperationsExample()
{
var data = new ClipboardFriendlyType
{
Name = "Sample",
DisplayText = "Sample Display Text",
InternalId = "internal-123" // This property isn't serialized due to [JsonIgnore]
};
Clipboard.SetDataAsJson("MyAppData", data);
if (Clipboard.TryGetData("MyAppData", out ClipboardFriendlyType retrieved))
{
Console.WriteLine($"Retrieved: {retrieved.Name}");
// retrieved.InternalId is null because of [JsonIgnore]
}
}
Public Shared Sub CustomTypesClipboardOperationsExample()
Dim data As New ClipboardFriendlyType With {
.Name = "Sample",
.DisplayText = "Sample Display Text",
.InternalId = "internal-123" ' This property isn't serialized due to <JsonIgnore>
}
Clipboard.SetDataAsJson("MyAppData", data)
Dim retrieved As ClipboardFriendlyType = Nothing
If Clipboard.TryGetData("MyAppData", retrieved) Then
Console.WriteLine($"Retrieved: {retrieved.Name}")
' retrieved.InternalId is null because of <JsonIgnore>
End If
End Sub
Aktivieren der BinaryFormatter-Unterstützung (nicht empfohlen)
Vorsicht
BinaryFormatter Unterstützung wird nicht empfohlen. Verwenden Sie sie nur als temporäre Migrationsbrücke für Ältere Anwendungen, die nicht sofort zu den neuen typsicheren APIs migrieren können.
Um die Verwendung von BinaryFormatter für Zwischenablagevorgänge in .NET 10 fortzusetzen, können Sie eine eingeschränkte Unterstützung durch eine explizite Konfiguration aktivieren. Dieser Ansatz birgt erhebliche Sicherheitsrisiken und erfordert mehrere Schritte.
Vollständige schrittweise Anleitungen finden Sie unter Aktivieren der BinaryFormatter-Zwischenablageunterstützung (nicht empfohlen). Allgemeine Anleitungen zur Migration finden Sie im BinaryFormatter-Migrationshandbuch.
Sicherheitswarnungen und Risiken
BinaryFormatter ist aus folgenden Gründen unsicher und veraltet:
- Sicherheitsanfälligkeiten bezüglich beliebiger Codeausführung: Angreifer können während der Deserialisierung bösartigen Code ausführen und Ihre Anwendung Remoteangriffen offenlegen.
- Denial of Service-Angriffe: Böswillige Zwischenablagedaten können übermäßigen Arbeitsspeicher oder CPU-Ressourcen verbrauchen, was Abstürze oder Instabilität verursacht.
- Informationsveröffentlichungsrisiken: Angreifer extrahieren möglicherweise vertrauliche Daten aus dem Arbeitsspeicher.
- Keine Sicherheitsgrenzen: Das Format ist grundsätzlich unsicher, und Konfigurationseinstellungen können es nicht schützen.
Aktivieren Sie diese Unterstützung nur als temporäre Brücke, während Sie Ihre Anwendung so aktualisieren, dass sie die neuen typsicheren APIs verwendet.
Ausführliche Sicherheitsrichtlinien und Konfigurationsschritte finden Sie in der Anleitung zu Sicherheitswarnungen und Risiken .
Implementierung von sicherheitsorientierten Typenauflösungen
Selbst bei aktiviertem BinaryFormatter müssen Sie Typauflöser implementieren, um die Deserialisierung auf explizit genehmigte Typen zu beschränken. Befolgen Sie die folgenden Richtlinien:
- Verwenden Sie explizite Zulassungslisten. Ablehnen eines Typs, der nicht explizit genehmigt wurde.
- Typnamen überprüfen. Stellen Sie sicher, dass Typnamen exakt den erwarteten Werten entsprechen.
- Beschränken Sie sich auf wesentliche Typen. Schließen Sie nur Typen ein, die für die Funktionalität der Zwischenablage erforderlich sind.
- Ausnahmen für unbekannte Typen auslösen. Nicht autorisierte Typen eindeutig ablehnen.
- Regelmäßig überprüfen. Prüfen und aktualisieren Sie die Erlaubt-Liste nach Bedarf.
Vollständige Implementierungsbeispiele und Codebeispiele finden Sie in der Anleitung zum Implementieren sicherheitsorientierter Typenlöser .
Mit KI Clipboard-Code migrieren
Das Migrieren von Zwischenablagevorgängen von .NET 8 zu .NET 10 umfasst systematische Codeänderungen in mehreren Dateien und Klassen. KI-Tools wie GitHub Copilot können Dazu beitragen, Ihre Migration zu beschleunigen, indem legacymuster identifiziert, moderne Ersetzungen vorgeschlagen und Testszenarien erstellt werden. Anstatt Ihre Codebasis manuell zu durchsuchen und jeden Zwischenablagevorgang einzeln zu konvertieren, können Sie KI verwenden, um sich wiederholende Aufgaben zu bearbeiten und sich dabei auf die Überprüfung von Ergebnissen und die Behandlung von Randfällen zu konzentrieren.
Die folgenden Abschnitte zeigen spezifische Eingabeaufforderungsstrategien für verschiedene Aspekte der Zwischenablagemigration, von der Suche nach problematischen Codemustern bis hin zum Erstellen robuster JSON-serialisierbarer Typen und umfassender Testsammlungen.
Verwendung von KI zur Identifizierung von veralteten Zwischenablagemustern
Verwenden Sie Copilot, um Ihre Codebasis zu scannen und Zwischenablagevorgänge zu finden, die eine Migration benötigen. Auf diese Weise können Sie den Umfang der erforderlichen Änderungen verstehen, bevor Sie die eigentliche Migration starten.
Find all clipboard operations in my codebase that use GetData(), SetData() with custom objects, DataObject.GetData(), or IDataObject.GetData(). Show me the file paths and line numbers where these patterns occur.
Copilot wird von KI unterstützt, so dass Überraschungen und Fehler möglich sind. Weitere Informationen finden Sie in den häufig gestellten Fragen zur allgemeinen Verwendung von Copilot.
KI verwenden, um GetData() in TryGetData<T>() zu konvertieren.
Verwenden Sie Copilot, um veraltete GetData() Aufrufe in das neue typsichere TryGetData<T>() Muster zu konvertieren. Diese Konvertierung umfasst eine ordnungsgemäße Fehlerbehandlung und beseitigt unsichere Umwandlungen.
Convert this GetData() clipboard code to use the new TryGetData<T>() method with proper error handling:
[paste your existing GetData() code here]
Make sure to eliminate casting and add appropriate error handling for when the data isn't available.
Copilot wird von KI unterstützt, so dass Überraschungen und Fehler möglich sind. Weitere Informationen finden Sie in den häufig gestellten Fragen zur allgemeinen Verwendung von Copilot.
Verwenden Sie KI, um SetData() nach SetDataAsJson<T>() zu migrieren.
Verwenden Sie Copilot, um benutzerdefinierte Objektspeicher aus der veralteten SetData() Methode in den neuen SetDataAsJson<T>() Ansatz zu konvertieren. Dadurch wird sichergestellt, dass Ihre benutzerdefinierten Objekte ordnungsgemäß in die Zwischenablage serialisiert werden.
Take this SetData() clipboard code that stores custom objects:
[paste your existing SetData() code here]
Convert it to use SetDataAsJson<T>() and make the custom types JSON-serializable. Add any necessary System.Text.Json attributes if the types have complex properties.
Copilot wird von KI unterstützt, so dass Überraschungen und Fehler möglich sind. Weitere Informationen finden Sie in den häufig gestellten Fragen zur allgemeinen Verwendung von Copilot.
Verwenden von KI zum Erstellen von JSON-serialisierbaren Datenmodellen
Verwenden Sie Copilot, um benutzerdefinierte Typen zu entwerfen, die nahtlos mit SetDataAsJson<T>() und TryGetData<T>(). Dies schließt das Hinzufügen geeigneter Attribute für Eigenschaften ein, die eine spezielle Behandlung erfordern.
Create a JSON-serializable version of this class for clipboard operations:
[paste your existing class definition here]
Make it work with System.Text.Json, add JsonIgnore for sensitive properties, JsonInclude for private fields that should serialize, and JsonPropertyName for any properties that need different names in JSON.
Copilot wird von KI unterstützt, so dass Überraschungen und Fehler möglich sind. Weitere Informationen finden Sie in den häufig gestellten Fragen zur allgemeinen Verwendung von Copilot.
Verwenden Sie KI, um typsichere Wrapper-Methoden zu generieren
Verwenden Sie Copilot, um Wrappermethoden zu erstellen, die die neuen Zwischenablage-APIs kapseln und saubere Schnittstellen für die spezifischen Datentypen Ihrer Anwendung bereitstellen.
Create a type-safe clipboard wrapper class that provides methods for storing and retrieving these custom types:
[list your custom types here]
Use SetDataAsJson<T>() and TryGetData<T>() internally, include proper error handling, and add methods like SavePersonToClipboard() and TryGetPersonFromClipboard().
Copilot wird von KI unterstützt, so dass Überraschungen und Fehler möglich sind. Weitere Informationen finden Sie in den häufig gestellten Fragen zur allgemeinen Verwendung von Copilot.
Verwenden von KI zum Erstellen umfassender Tests
Verwenden Sie Copilot, um Testsuiten zu generieren, die überprüfen, ob die Migration der Zwischenablage ordnungsgemäß funktioniert, einschließlich Roundtrip-Serialisierungstests und Fehlerbehandlungsszenarien.
Generate comprehensive unit tests for this clipboard code:
[paste your migrated clipboard code here]
Include tests for successful round-trip serialization, handling of null values, error cases when data isn't available, and verification that the migrated code produces the same results as the original for valid scenarios.
Copilot wird von KI unterstützt, so dass Überraschungen und Fehler möglich sind. Weitere Informationen finden Sie in den häufig gestellten Fragen zur allgemeinen Verwendung von Copilot.
Verwenden von KI zum Überprüfen von Migrationsergebnissen
Verwenden Sie Copilot, um Ihren migrierten Code zu überprüfen und potenzielle Probleme oder Bereiche zu identifizieren, in denen die Migration möglicherweise nicht abgeschlossen ist.
Review this migrated clipboard code for potential issues:
[paste your migrated code here]
Check for: missing error handling, types that might not serialize properly to JSON, performance concerns with large objects, security issues, and any remaining uses of obsolete methods.
Copilot wird von KI unterstützt, so dass Überraschungen und Fehler möglich sind. Weitere Informationen finden Sie in den häufig gestellten Fragen zur allgemeinen Verwendung von Copilot.
Verwandte Inhalte
.NET Desktop feedback