# Auf neue Version umsteigen

> Referenz: Alle Änderungen des OPC UA .NET SDK, die beim Umstieg auf eine neuere Version bestehenden Code betreffen, gefiltert nach Von- und Auf-Version.

Diese Seite listet alle Änderungen, die beim Umstieg auf eine neuere Version des OPC UA .NET SDK bestehenden Code betreffen können: geänderte Schnittstellen und geändertes Verhalten, Umbenennungen und neue Voraussetzungen. Wählen Sie die Version, die Sie heute einsetzen, und die Version, auf die Sie umsteigen. Die Liste zeigt dann die Änderungen dazwischen in der Reihenfolge, in der sie hinzugekommen sind.

Die Einträge stammen aus der [Versionshistorie](https://www.traeger.de/docs/development/opcua/version-history). Die Versionsnummer über jedem Abschnitt führt zu den vollständigen Release-Notizen der Version, einschließlich neuer Funktionen und Fehlerbehebungen.

### [1.5](https://www.traeger.de/docs/development/opcua/version-history#_1-5)

- Geändert (1.5.5.0): Die Klassen `Identity` und `ImpersonationContext` wurden vom Namespace `Opc.UaFx.Server` in den Namespace `Opc.UaFx` verschoben.
- Geändert (1.5.6.7): Das `OpcValueLabel` ist jetzt nicht mehr als Struktur, sondern als Klasse definiert.

### [1.6](https://www.traeger.de/docs/development/opcua/version-history#_1-6)

- Geändert (1.6.5.2): Implizite Interpretationen einer numerischen NodeId, die als String codiert ist, wurden entfernt.

### [2.2](https://www.traeger.de/docs/development/opcua/version-history#_2-2)

- Geändert (2.2.2.0): Die Implementierung von `OpcValue.ToString` wurde vereinfacht, sodass nur noch die Zeichenkette `null` für Null-Referenzen oder `Value.ToString()` geliefert wird.

### [2.3](https://www.traeger.de/docs/development/opcua/version-history#_2-3)

- Geändert (2.3.0.0): Das SDK unterstützt bei der Authentifizierung am OPC UA Server keine Windows-basierte Authentifizierung über die WinLogon-API mehr.
- Geändert (2.3.0.0): Anwendungszertifikate werden jetzt mit SHA256 erstellt (dem neuen Standardwert, den die Foundation vorschreibt). Das beeinflusst bestehende Anwendungen nicht. Die Änderung wirkt sich nur aus, wenn ein neues Zertifikat erstellt wird.
- Achtung (2.3.1.0): Ab dieser Version muss dem Projekt ein Verweis auf das NuGet-Paket `Portable.BouncyCastle` (mindestens Version 1.8.1.3) oder auf die Assembly `BouncyCastle.Crypto` (mindestens Version 1.8.1.146) hinzugefügt werden.
- Achtung (2.3.1.0): Wenn eine Serveradresse mit dem Schema `https` verwendet wird, muss dem Projekt ein Verweis auf die NuGet-Pakete `Microsoft.AspNetCore.Server.Kestrel` (1.1.3) und `Microsoft.AspNetCore.Server.Kestrel.Https` (1.1.3) hinzugefügt werden.
- Geändert (2.3.2.0): `OpcVariableNode` wurde als abstrakte Basisklasse festgelegt.
- Geändert (2.3.2.0): Mehrfache Node-Referenzen der Foundation wurden entfernt, um den Speicherbedarf zu senken.

### [2.5](https://www.traeger.de/docs/development/opcua/version-history#_2-5)

- Geändert (2.5.0.0): Falsch geschriebene Member wurden korrigiert.
- Geändert (2.5.0.0): Vereinheitlichte API durch weitere selbstbeschreibende Bestandteile in Klassen- und Delegatnamen. Die Bezeichnungen wurden von `Data` auf `DataSet`, von `DataItem` auf `DataSetItem` und von `EventRaise` auf `Event` geändert.
- Geändert (2.5.0.0): `OpcNodeId.ToString` formatiert die Informationen jetzt im Format `OpcNodeIdFormat.Foundation`.
- Geändert (2.5.0.0): Die Reihenfolge der Subscription-Ereignisse wurde von MonitoredItem → Client → Subscription zu MonitoredItem → Subscription → Client geändert, um eine logischere Abarbeitungsreihenfolge beim Event-Bubbling sicherzustellen.
- Geändert (2.5.0.0): `OpcMonitoredItem.ReceivedDataChange` wurde in `OpcMonitoredItem.DataChangeReceived` umbenannt.
- Geändert (2.5.0.0): `OpcMonitoredItem.ReceivedEventRaise` wurde in `OpcMonitoredItem.EventRaiseReceived` umbenannt.
- Umbenennung (2.5.0.0): `OpcSubscribeEventRaise` -&gt; `OpcSubscribeEvent`
- Umbenennung (2.5.0.0): `OpcDataChangeEventArgs` -&gt; `OpcDataChangeReceivedEventArgs`
- Umbenennung (2.5.0.0): `OpcDataChangeEventHandler` -&gt; `OpcDataChangeReceivedEventHandler`
- Umbenennung (2.5.0.0): `OpcEventRaiseEventArgs` -&gt; `OpcEventReceivedEventArgs`
- Umbenennung (2.5.0.0): `OpcEventRaiseEventHandler` -&gt; `OpcEventReceivedEventHandler`
- Umbenennung (2.5.0.0): `OpcNotificationEventArgs` -&gt; `OpcNotificationReceivedEventArgs`
- Umbenennung (2.5.0.0): `OpcNotificationEventHandler` -&gt; `OpcNotificationReceivedEventHandler`
- Umbenennung (2.5.0.0): `OpcDataChangeCallback` -&gt; `OpcDataChangeReceivedCallback`
- Umbenennung (2.5.0.0): `OpcEventRaiseCallback` -&gt; `OpcEventReceivedCallback`
- Umbenennung (2.5.0.0): `IOpcNotificationData` -&gt; `IOpcNotificationDataSet`
- Umbenennung (2.5.0.0): `OpcNotificationData` -&gt; `OpcNotificationDataSet`
- Umbenennung (2.5.0.0): `OpcNotificationDataCollection` -&gt; `OpcNotificationDataSetCollection`
- Umbenennung (2.5.0.0): `OpcNotificationDataReadOnlyCollection` -&gt; `OpcNotificationDataSetReadOnlyCollection`
- Umbenennung (2.5.0.0): `OpcNotificationDataItem` -&gt; `OpcNotificationDataSetItem`
- Umbenennung (2.5.0.0): `OpcNotificationDataItemCollection` -&gt; `OpcNotificationDataSetItemCollection`
- Umbenennung (2.5.0.0): `OpcNotificationDataItemReadOnlyCollection` -&gt; `OpcNotificationDataSetItemReadOnlyCollection`
- Umbenennung (2.5.0.0): `OpcDataChange` -&gt; `OpcDataChangeSet`
- Umbenennung (2.5.0.0): `OpcDataChangeItem` -&gt; `OpcDataChangeSetItem`
- Umbenennung (2.5.0.0): `OpcEventRaise` -&gt; `OpcEventDataSet`
- Umbenennung (2.5.0.0): `OpcEventRaiseItem` -&gt; `OpcEventDataSetItem`
- Umbenennung (2.5.0.0): `OpcMonitoredItem`
  - `.EventRaiseReceived` -&gt; `EventReceived`
  - `.LastEventRaise` -&gt; `LastEvent`
  - `.OnEventRaiseReceived` -&gt; `OnEventReceived`
- Umbenennung (2.5.0.0): `OpcSubscription`
  - `.EventRaiseReceived` -&gt; `EventReceived`
  - `.ReceivedEventRaiseCallback` -&gt; `ReceivedEventCallback`
  - `.OnEventRaiseReceived` -&gt; `OnEventReceived`
- Umbenennung (2.5.0.0): `OpcClient`
  - `.EventRaiseReceived` -&gt; `EventReceived`
  - `.OnEventRaiseReceived` -&gt; `OnEventReceived`
  - `.SubscribeEventRaise` -&gt; `SubscribeEvent`
- Geändert (2.5.0.1): Beispielprojekte wurden auf die C#-Sprachversion 6.0 zurückgestuft, um sicherzustellen, dass die Beispiele auch in älteren Versionen von Visual Studio kompilierbar sind.
- Geändert (2.5.1.0): `IsNodeAccessible(..., IOpcNode node)` wurde zu `IsNodeAccessible(..., IOpcNodeInfo node)` geändert.
- Geändert (2.5.4.0): `OpcNode.BeforeApplyChanges` und `OpcNode.AfterApplyChanges` werden nur noch ausgelöst, wenn Änderungen bestehen (siehe `OpcNode.HasPendingChanges`).
- Geändert (2.5.5.0): Standardwert von `MinimumCertificateKeySize` von 2048 auf 1024 geändert, um kleinere Schlüssellängen älterer Zertifikate zu unterstützen.
- Geändert (2.5.5.0): Wenn das Anwendungszertifikat einer Client- oder Serverinstanz über die Eigenschaft `Certificate` geändert wird, ändert sich der Store-Path-Type des Zertifikatspeichers für Anwendungszertifikate auf `System`. Um den Store-Path-Type `Directory` zu verwenden, ändern Sie ihn manuell. Stellen Sie außerdem nach der Änderung der Eigenschaft `Certificate` sicher, dass das Zertifikat im Zertifikatspeicher für Anwendungszertifikate enthalten ist.
- Geändert (2.5.7.0): Anwendungszertifikate werden nicht mehr unter `.\CertificateStores\Trusted`, sondern (standardmäßig) unter `.\CertificateStores\App` gespeichert, um beim Start der Anwendung die Suche nach dem Anwendungszertifikat zu beschleunigen.
- Geändert (2.5.7.0): Bei der Ermittlung der `OpcServerInfo` einer Assembly wird nicht mehr die `LinkTime`, sondern die `LastWriteTime` der Assembly verwendet.

### [2.6](https://www.traeger.de/docs/development/opcua/version-history#_2-6)

- Geändert (2.6.0.0): Die Klasse `OpcClientTransport` wurde entfernt (ersetzt durch die neue Klasse `OpcTransport`).
- Geändert (2.6.0.0): Die Klasse `OpcServerTransport` wurde entfernt (ersetzt durch die neue Klasse `OpcTransport`).
- Geändert (2.6.0.0): Die standardmäßig verwendeten Serverinformationen, die die `OpcServerBase` bereitstellt, bevorzugen einen vordefinierten `ApplicationName`.
- Geändert (2.6.0.0): `OpcSecurityPolicyCollection` stellt keinen Konstruktor mehr bereit, der eine Instanz von `OpcServerBase` erwartet. Die zugehörige Eigenschaft `Owner` wurde ebenfalls entfernt.

### [2.7](https://www.traeger.de/docs/development/opcua/version-history#_2-7)

- Geändert (2.7.0.0): Die Eigenschaft `OpcServerIdentity.Password` wurde entfernt, weil es keinen Grund gibt, das intern gespeicherte Passwort nach außen weiterzugeben. Außerdem ist es keine gute Praxis, einen Verweis auf ein Array über eine Eigenschaft bereitzustellen.
- Geändert (2.7.0.0): Der Delegat `OpcTransformUserPasswordDelegate` wurde entfernt.
- Geändert (2.7.0.0): `OpcUserNameAcl.PasswordTransform` wird durch die virtuellen Methoden `Matches` und `TransformPassword` in der Klasse `OpcServerIdentity` ersetzt.
- Geändert (2.7.3.0): Die Implementierung der Klassen `OpcMonitoredItem` und `OpcSubscription` wurde aktualisiert: Einige `int`-basierte Eigenschaften wurden auf `long` umgestellt, um die zugrunde liegenden `uint`-Eigenschaften des Foundation Stacks `CLSCompliant` anzubieten.
- Geändert (2.7.4.0): Einzelne Eigenschaften in den Klassen `OpcMonitoredItem`, `OpcServiceCounter`, `OpcSessionDiagnostics` und `OpcServerDiagnostics` liefern jetzt `long`- statt `int`-basierte Werte, um weiterhin die CLS-Konformität zu wahren, obwohl der Stack der Foundation vorzeichenlose Datentypen verwendet.
- Geändert (2.7.5.0): `OpcMonitoredItem.AutoFlushCache` wurde durch die neue Eigenschaft `OpcMonitoredItem.QueueMode` ersetzt, um den verwendeten Mechanismus beim Überlauf der Benachrichtigungsqueue klarer auszudrücken.

### [2.8](https://www.traeger.de/docs/development/opcua/version-history#_2-8)

- Geändert (2.8.0.0): `OpcDataTypeAttribute` ist jetzt auf Klassen und Strukturen anwendbar.
- Geändert (2.8.0.0): `OpcNodeManager.NamespaceIndexes` und `OpcNodeManager.NamespaceUris` wurden in der neuen Eigenschaft `OpcNodeManager.Namespaces` zusammengefasst.
- Geändert (2.8.0.0): `IOpcReadOnlyDataStore` wurde in `IOpcReadOnlyNodeDataStore` umbenannt.
- Geändert (2.8.0.0): Die Methoden `Uri Resolve(int namespaceIndex)` und `int Resolve(Uri namespaceUri)` von `IOpcNamespaceResolver` sind jetzt veraltet.
- Geändert (2.8.1.0): Die Eigenschaft `OpcAutomatism.UseDynamic` hat ab sofort den Standardwert `false`. Damit das `OpcDataObject` genutzt werden kann, muss diese Eigenschaft oder die Eigenschaft `OpcClient.UseDynamic` auf `true` gesetzt werden.
- Geändert (2.8.1.2): Angaben zu `iconUrl` und `licenseUrl` in NuGet-Paketen aufgrund ihrer Abkündigung angepasst.
- Geändert (2.8.2.0): Explizit kodierte Informationen, bekannt als `EncodingMask` eines strukturierten Datentyps, werden jetzt über den neu eingeführten Typ `Opc.UaFx.Bit` statt über `System.Boolean` abgebildet.
- Geändert (2.8.3.0): Überarbeitete Logik zur Änderung der Eigenschaft `OpcClient.State`, um den Verlust einer Verbindung zum Server besser feststellen zu können.
- Geändert (2.8.3.0): Die Eigenschaft `OpcClient.State` ändert sich jetzt (während einer laufenden Anfrage) nur noch dann automatisch auf den Wert `Disconnected`, wenn der `ReconnectTimeout` größer als 0 ist (die Wiederverbindungslogik implementieren Sie selbst).

### [2.9](https://www.traeger.de/docs/development/opcua/version-history#_2-9)

- Geändert (2.9.0.0): Lizenzschlüssel, die vor Version 2.9 ausgestellt wurden, funktionieren nicht mehr. Unsere Kunden erhalten entsprechend neue Lizenzschlüssel, die dann auch in allen Zielframeworks funktionieren.
- Geändert (2.9.0.0): `OpcAttributeWriteAccess` verwendet jetzt `UInt32` als Basistyp.
- Geändert (2.9.0.0): Der Standardwert der Eigenschaft `OpcAutomatism.AlwaysParseStringIdentifiers` ist jetzt `false`. Dadurch wird der Wert beim Aufruf des Konstruktors `OpcNodeId(string)` nicht mehr automatisch geparst. Weitere Details beschreibt `OpcAutomatism.AlwaysParseStringIdentifiers`.
- Geändert (2.9.0.0): [Client SDK] Die Klasse `OpcBrowseNode` wurde vom Namespace `Opc.UaFx.Client` in den Namespace `Opc.UaFx` verschoben.
- Geändert (2.9.0.0): [Client SDK] Die Enumeration `OpcBrowseNodeDegree` wurde vom Namespace `Opc.UaFx.Client` in den Namespace `Opc.UaFx` verschoben.
- Geändert (2.9.0.0): [Client SDK] `IOpcBrowseService` und `OpcBrowseRequest` verwenden jetzt die Klassen `OpcViewDescription` und `OpcBrowseNode` statt der Klassen `ViewDescription` und `BrowseDescription` der Foundation.
- Geändert (2.9.0.0): `OpcReadOnlyNamespaceCollection` wurde vom Namespace `Opc.UaFx.Server` in den Namespace `Opc.UaFx` verschoben.
- Geändert (2.9.0.0): Der Standardwert des Attributs DataType von `OpcDataTypeDictionaryNode` wurde von Byte auf ByteString geändert, um der Definition der Spezifikation zu entsprechen.
- Geändert (2.9.0.0): Die Eigenschaft `Description` wurde in `Documentation` umbenannt, um die Konformität zur Spezifikation sicherzustellen. Betroffen sind `IOpcDataTypeInfo`, `OpcDataTypeInfo` und `OpcDataFieldInfo`.
- Geändert (2.9.0.0): `OpcEncoding.All(...)` erzeugt jetzt die `OpcEncoding.Id` anhand des Standard-BrowseNames für die verschiedenen Encoding-Typen.
- Geändert (2.9.0.0): `OpcNamespace.ToString()` liefert ab sofort eine Zeichenkette, die ausschließlich `OpcNamespace.Value` und `OpcNamespace.Index` (falls nicht null) enthält.
- Geändert (2.9.0.0): `OpcNodeSet.GetDataTypeSystem()` liefert jetzt eine Instanz von `OpcDataTypeSystem`, die den typischen BrowseName der jeweiligen Kodierungsart (die das System repräsentiert) verwendet.
- Geändert (2.9.0.0): `IOpcTypeProvider.GetType(OpcEncoding)` wurde entfernt, weil Codierungsinformationen nur auf Datentypen zutreffen.
- Geändert (2.9.0.0): `OpcTypeCategory.EventType` und `OpcTypeCategory.ReferenceType` wurden entfernt.

### [2.10](https://www.traeger.de/docs/development/opcua/version-history#_2-10)

- Geändert (2.10.0.0): `OpcNode.OnAfterApplyChanges` und `OpcNode.OnBeforeApplyChanges` nutzen jetzt `OpcNodeChangesEventArgs` statt `EventArgs`.
- Geändert (2.10.0.0): `OpcNode.AfterApplyChanges` und `OpcNode.BeforeApplyChanges` übergeben jetzt `OpcNodeChangesEventArgs` statt `EventArgs` an Ereignishandler.

### [2.11](https://www.traeger.de/docs/development/opcua/version-history#_2-11)

- Geändert (2.11.0.0): Die Methode `OpcSession.Close` schließt ab sofort die Sitzung und macht den sitzungsbezogenen Identifier ungültig.
- Geändert (2.11.0.0): Methoden von `OpcClient` validieren ab sofort den Verbindungsstatus mit einer `OpcException` (mit `BadServerNotConnected`) statt einer `InvalidOperationException`.
- Geändert (2.11.0.0): Der Standardwert der Eigenschaft `QueueSize` der Instanz von `OpcMonitoredItem`, die über `OpcClient.SubscribeEvent`(s) erstellt wird, wurde von `int.MaxValue` auf `uint.MaxValue` geändert. So verwendet der Server für die Queue der Ereignisbenachrichtigungen die maximal unterstützte Größe. Das war auch das ursprüngliche Ziel des falschen Werts `int.MaxValue`.
- Geändert (2.11.0.0): Die Eigenschaft `OpcMonitoredItemStatus.DataItemQueueSize` wurde in `QueueSize` umbenannt, um der Benennung der entsprechenden Eigenschaft in der Klasse `OpcMonitoredItem` zu entsprechen. Diese repräsentiert die angeforderte Größe, die Eigenschaft in `OpcMonitoredItemStatus` die revidierte Größe.
- Geändert (2.11.0.0): Der Rückgabetyp der Eigenschaft `OpcMonitoredItemStatus.Id` wurde von `Int32` in `Int64` geändert, damit er den zugrunde liegenden, nicht CLS-konformen `UInt32` des Stacks der Foundation abbilden kann.
- Geändert (2.11.0.0): Die letzten API-Änderungen an `OpcMonitoredItem` wurden auf `OpcMonitoredItemStatus` übertragen: Die Eigenschaft `OpcMonitoredItemStatus.AutoFlushCache` wurde in `QueueMode` umbenannt (wie in der Klasse `OpcMonitoredItem`).
- Geändert (2.11.1.0): Der Konstruktor von `OpcCertificateJudgementEventArgs` prüft nicht mehr, ob eines der übergebenen Zertifikate eine Null-Referenz (Nothing in Visual Basic) ist, weil manche Server für Endpunkte mit der Policy `None` (Mode und Algorithm) keinerlei Zertifikatdaten verwenden.
- Geändert (2.11.3.0): Der Datentyp der Eigenschaften `OpcNode.Read/WriteDescriptionCallback` wurde von `String` auf `OpcText` geändert.
- Geändert (2.11.3.0): `OpcDataChangeDataSetItem.ClientID` von `Int32` in `Int64` geändert, um dem bei `OpcMonitoredItem.ClientID` verwendeten Typ zu entsprechen.

### [2.12](https://www.traeger.de/docs/development/opcua/version-history#_2-12)

- Geändert (2.12.0.0): Der Namespace `OpcNamespace.Default` stellt jetzt den zum Standard-Namespace gehörigen Wert sowie die URI bereit, unter der der Namespace der Foundation identifiziert werden kann.
- Geändert (2.12.0.0): Abgekündigte Methoden in `IOpcNamespaceResolver` sowie deren Implementierung in `OpcClient`, `OpcServer`, `OpcContext` und `OpcNodeManager` wurden entfernt.
- Geändert (2.12.0.0): Übergänge von `OpcClient.State` finden nicht mehr statt (bei Verwendung des standardmäßig aktivierten Reconnect-Mechanismus), wenn während eines Wiederverbindungsversuchs zum Beispiel `ReadNode` aufgerufen wird.
- Geändert (2.12.0.0): Bei einer unterbrochenen Verbindung versucht der `OpcClient` (standardmäßig), die Verbindung wiederherzustellen und dabei die zuvor verwendete Sitzung wiederzuverwenden. Wenn die vorherige Sitzung nach dem Wiederaufbau der Verbindung wiederverwendet werden kann, löst der `OpcClient` (wie bisher) das Ereignis `Reconnected` aus. Wenn der Client eine neue Sitzung erstellen muss (zum Beispiel, weil diese abgelaufen ist), löst der `OpcClient` jetzt das Ereignis `Connected` statt `Reconnected` aus. So lassen sich diese Situationen im Benutzercode unterscheiden.
- Geändert (2.12.0.0): Vergleiche von `OpcNodeId` und `OpcNamespace` mit Null-Verweisen verhalten sich jetzt wie bei jeder anderen typischen .NET-API (dieses Verhalten unterscheidet sich von dem des Stacks der Foundation).
- Geändert (2.12.1.0): Bidirektionale Verweise zwischen DataTypeDescription-, DataTypeEncoding- und DataType-Nodes werden jetzt unidirektional exportiert (mit den Standard-Exportoptionen).

### [2.14](https://www.traeger.de/docs/development/opcua/version-history#_2-14)

- Geändert (2.14.0.0): Doppelte Verweise auf `DataTypeNodes` bei Verwendung der Klasse `OpcAddressSpace` wurden entfernt.

### [2.18](https://www.traeger.de/docs/development/opcua/version-history#_2-18)

- Geändert (2.18.0.0): Das Format von ByteString wurde von Base64-basierter Kodierung in hexadezimale Formatierung (`X2`) geändert, um der binär kodierten Darstellung eines `ByteString` der Foundation zu entsprechen.
- Geändert (2.18.2.0): `OpcNodeId` vergleicht NodeIds jetzt gemäß der OPC-UA-Spezifikation unter Berücksichtigung der Groß- und Kleinschreibung von Identifier und Namespace.
- Geändert (2.18.3.0): `OpcClassicDiscoveryClient` verwendet jetzt die `OpcException`, um stackbezogene Ausnahmen bereitzustellen.

### [2.19](https://www.traeger.de/docs/development/opcua/version-history#_2-19)

- Bruch (2.19.0.0): Clients und Server seit Version 2.17.0.0 greifen nicht gemäß der OPC-UA-Spezifikation auf Datei-Nodes zu beziehungsweise stellen diese nicht spezifikationsgemäß bereit. Sie verwenden ein Byte-Array statt ByteString zum Lesen und Schreiben von Dateiinhalten. Dieser Fehler wurde in dieser Version korrigiert.
- Bruch (2.19.0.0): `OpcFileReadMethodNode.FileReadCallback` und `OpcFileReadMethodNode.FileReadExCallback` geben jetzt einen ByteString statt eines Byte-Arrays zurück.
- Bruch (2.19.0.0): `OpcFileWriteMethodNode.FileWriteCallback` und `OpcFileWriteMethodNode.FileWriteExCallback` akzeptieren jetzt einen ByteString für den Datenparameter statt eines Byte-Arrays.
- Geändert (2.19.0.0): Parameter von `OpcFilterOperand.OfType` von `value : object` in `typeId : OpcNodeId` geändert, um sicherzustellen, dass ein `OfType`-Operand wie erwartet ausgewertet wird (also mit einer `OpcNodeId`).
- Bruch (2.19.0.0): Regression beim Zugriff auf `OpcFileNode` mit Lese- und Schreiboperationen, nachdem der Foundation Stack die Verwendung von ByteString für ByteString und `Byte[]` für `Byte[]` erzwingt statt ByteString für `Byte[]`.
- Bruch (2.19.1.0): **Möglicher Bruch:** `IOpcReadOnlyNodeDataStore` erfordert jetzt auch die Implementierung von `IOpcNamespaceResolver`.
- Geändert (2.19.2.0): Unnötige Zeilenumbrüche in der String-Darstellung von Instanzen von `OpcException` wurden entfernt.

### [2.20](https://www.traeger.de/docs/development/opcua/version-history#_2-20)

- Geändert (2.20.0.0): `OpcInstanceNode` bestimmt jetzt seine `DefaultTypeDefinitionId` anhand des Node-Typs, der zum Erstellen des Instanz-Nodes verwendet wird.
- Geändert (2.20.0.0): `OpcMemberOrigins` definiert jetzt ein zusätzliches Enum-Member `Method` für Methoden.

### [2.24](https://www.traeger.de/docs/development/opcua/version-history#_2-24)

- Geändert (2.24.0.0): Die Eigenschaft `OpcNodeAccessToken.IndexRange` ist jetzt veraltet. Verwenden Sie stattdessen die neue Eigenschaft `OpcNodeAccessToken.Range`.
- Geändert (2.24.0.0): Der Typ der Eigenschaft `OpcReadVariableValueContext(<T>).Range` wurde von `Ua.NumericRange` in `OpcRange` geändert.
- Geändert (2.24.0.0): Der Typ der Eigenschaft `OpcWriteVariableValueContext(<T>).Range` wurde von `Ua.NumericRange` in `OpcRange` geändert.
- Geändert (2.24.0.0): Der Typ der Eigenschaft `OpcReadPropertyValueContext(<T>).Range` wurde von `Ua.NumericRange` in `OpcRange` geändert.
- Geändert (2.24.0.0): Der Typ der Eigenschaft `OpcWritePropertyValueContext(<T>).Range` wurde von `Ua.NumericRange` in `OpcRange` geändert.

### [2.25](https://www.traeger.de/docs/development/opcua/version-history#_2-25)

- Geändert (2.25.0.0): Standardgröße der (automatischen) Kodierungsmaske von einem Bit auf 32 Bit geändert, um die Verwendung der standardmäßig erwarteten 32-Bit-Kodierungsmaske zu vereinfachen.

### [2.28](https://www.traeger.de/docs/development/opcua/version-history#_2-28)

- Geändert (2.28.0.0): Die Deaktivierung von `OpcAutomatism.UseDynamicTypeRegistration` führte zu einer verzögerten dynamischen Typregistrierung, wenn ein benutzerdefinierter Datentyp manuell registriert wurde.

### [2.29](https://www.traeger.de/docs/development/opcua/version-history#_2-29)

- Geändert (2.29.0.0): `OpcNode.AddNotifier` wird bei anderen Typen als `OpcObjectNodes` und deren Unterklassen nicht mehr unterstützt.

### [2.30](https://www.traeger.de/docs/development/opcua/version-history#_2-30)

- Geändert (2.30.0.0): Das Verhalten beim Starten und Beenden eines OPC Classic UA Wrapper Servers ist jetzt deterministischer, da jeder `OpcClient` einen eigenen Wrapper Server verwendet, der jetzt auch gestoppt wird, wenn der `OpcClient` die Verbindung trennt.
- Geändert (2.30.0.0): Die Methode `OpcCertificateIdentity.Matches()` ist jetzt virtuell, um einen benutzerdefinierten Identitätsvergleich zu ermöglichen.
- Geändert (2.30.0.0): Die Eigenschaft `OpcEvent.EventId` liefert jetzt den zugrunde liegenden ByteString statt eines Byte-Arrays (wie vor der Einführung von ByteString).

### [2.31](https://www.traeger.de/docs/development/opcua/version-history#_2-31)

- Geändert (2.31.0.0): Abhängigkeit `Newtonsoft.Json` auf Version 13.0.3 aktualisiert, um eine Sicherheitslücke zu beheben.
- Geändert (2.31.0.0): Der UA Wrapper Server für OPC-Classic-Verbindungen generiert jetzt immer ein neues Anwendungszertifikat, statt zu versuchen, eines aus dem Zertifikatspeicher des Clients zu laden.
- Geändert (2.31.0.0): Wenn bei einer `opc.com:`-URL kein Port angegeben ist, wird der Port für den Classic Wrapper Server nicht mehr von `classID` und `progID` abgeleitet, sondern es wird eine freie dynamische Portnummer ermittelt. Das erleichtert die gleichzeitige Verwendung mehrerer `OpcClients` mit derselben `opc.com:`-URL.

### [2.33](https://www.traeger.de/docs/development/opcua/version-history#_2-33)

- Geändert (2.33.0.0): `OpcContext.Empty.SessionId` liefert keine Null-Referenz (Nothing in Visual Basic) mehr, sondern `OpcNodeId.Null`.
- Geändert (2.33.0.0): Die Zugriffsmodifizierer der Methoden `OpcNodeManager.AddNode(...)` und `OpcNodeManager.RemoveNode(...)` wurden von `protected` auf `public` geändert, um die Verwendung zu vereinfachen.
- Geändert (2.33.0.0): Die Auswertung von `OpcVariableNodeInfo.IsArray` verwendet jetzt den Wert von ValueRank statt ArrayDimensions, um zu entscheiden, ob das Attribut Value ein Array liefert.

### [2.41](https://www.traeger.de/docs/development/opcua/version-history#_2-41)

- Geändert (2.41.0.0): Die Benutzerauthentifizierung im `OpcServer` wird jetzt nur noch einmal während `ActivateSession` durchgeführt, statt für jede Anfrage einzeln.
- Geändert (2.41.1.0): Die Abhängigkeit `Microsoft.AspNetCore.Server.Kestrel.Core` wurde auf Version 2.1.25 aktualisiert, um eine Sicherheitslücke zu beheben.

### [2.42](https://www.traeger.de/docs/development/opcua/version-history#_2-42)

- Geändert (2.42.0.0): `OpcArgument.ArrayDimensions` und `OpcArgumentInfo.ArrayDimensions` unterstützen jetzt Null-Referenzen (Nothing in Visual Basic), wenn das über `OpcAutomatism.UseNullInsteadOfEmptyArrays` aktiviert ist. Wenn ein Server den Wert `null` für die `ArrayDimensions` angibt, gibt diese Eigenschaft jetzt also ebenfalls eine Null-Referenz (Nothing in Visual Basic) zurück.
- Geändert (2.42.4.0): Die Abhängigkeit `Portable.BouncyCastle` wurde auf Version 1.9.0 aktualisiert, um eine Sicherheitslücke zu beheben.

### [2.50](https://www.traeger.de/docs/development/opcua/version-history#_2-50)

- Geändert (2.50.0.0): Wenn `OpcClientSecurity.UseOnlySecureEndpoints` auf `true` gesetzt ist, wählt der `OpcClient` jetzt nur noch Endpunkte mit dem Modus `SignAndEncrypt` und nicht mehr solche mit dem Modus `Sign`, da Letzterer keine Vertraulichkeit bietet. Für das bisherige Verhalten (Endpunkte mit `Sign` oder `SignAndEncrypt`) setzen Sie `client.Security.EndpointPolicy` auf eine Policy mit diesem Modus und `OpcClient.Security.AutoUpgradeEndpointPolicy` auf `true`. Alternativ setzen Sie `OpcClient.Security.UseHighLevelEndpoint` auf `true`, um den „besten“ vom Server angebotenen Endpunkt zu wählen. Das bietet allerdings keine Sicherheit.
- Geändert (2.50.0.0): Beim Erstellen eines Ereignisfilters mit `OpcEventFilterFactory.Select()` wird in den einfachen Attributoperanden jetzt standardmäßig der Typbezeichner von `BaseEventType` verwendet (wie vor Version 2.32.0.0). So lassen sich bei mehreren Ereignistypen, die gleichnamige Felder haben können, alle Felder empfangen. Für das bisherige Verhalten, den tatsächlichen Ereignistyp in den einfachen Attributoperanden anzugeben, übergeben Sie `OpcEventFieldSelectOptions.UseExplicitEventTypeIds` an `OpcEventFilterFactory.Select()`.
- Geändert (2.50.4.0): Die `DefaultReferenceTypeId` von `OpcFolderNode` war fälschlich Organizes; stattdessen wird jetzt HasComponent verwendet. Diese Änderung dient der CTT-Konformität.
- Geändert (2.50.4.0): `ServerDiagnostics` liefert keine Kind-Nodes mehr, und jede explizite Lese- oder Schreiboperation auf die Kind-Nodes über ihre NodeId führt zu `BadOutOfService`. Dieses Verhalten gilt bei deaktivierter `ServerDiagnostics` und dient der CTT-Konformität.
- Geändert (2.50.5.0): Die Validierung von Anfragen wurde überarbeitet: Zuerst wird der Inhalt der Anfrage validiert, danach, ob die angeforderte Operation erlaubt ist. Außerdem werden Diagnoseinformationen (einschließlich Null-Referenzen) nur noch auf Anforderung geliefert. Das dient der CTT-Konformität.
- Geändert (2.50.6.0): Die Eigenschaft `Model` und die übrige API zu `OpcNodeModel` wurden von `OpcInstanceNode` nach `OpcNode` verschoben, um eine korrekte Initialisierung der Nodes sicherzustellen.
- Geändert (2.50.7.0): Verbesserte CTT-Konformität bei der Standardinitialisierung von `OpcNode`: Die Standardwerte für das Attribut Description und die Eigenschaft `SymbolicName` entfallen unter bestimmten Bedingungen. Für das bisherige Verhalten aktivieren Sie die entsprechenden Eigenschaften in `OpcAutomatism`.

### [2.51](https://www.traeger.de/docs/development/opcua/version-history#_2-51)

- Geändert (2.51.0.0): Bei Verwendung von .NET Framework ist jetzt Version 4.7.2 oder höher erforderlich.
- Geändert (2.51.0.0): Die Methode `IOpcNodeHistoryProvider.ReadHistory()` hat neue Parameter erhalten, um History-Werte zu streamen, statt alle Werte im Speicher zu puffern. Insbesondere muss die Implementierung die Werte jetzt in umgekehrter Reihenfolge zurückgeben, wenn der Parameter `timeFlowsBackward` den Wert `true` hat.

### [2.54](https://www.traeger.de/docs/development/opcua/version-history#_2-54)

- Geändert (2.54.0.0): Erweiterte Zertifikatvalidierung, insbesondere für Anwendungsinstanzzertifikate, mit konformer Validierung der Erweiterung Basic Constraints. Das ist für die CTT-Konformität erforderlich.
- Geändert (2.54.0.0): Der Listener-Socket verwendet beim Binden an den Port jetzt standardmäßig eine exklusive Adresse. Die neue Eigenschaft `OpcServerBinding.UseExclusiveAddress` steuert dieses Verhalten.

### [2.55](https://www.traeger.de/docs/development/opcua/version-history#_2-55)

- Geändert (2.55.0.0): Der Initialwert der Eigenschaft `OpcConditionNode.IsRetained` und ihrer Subtypen (`OpcAcknowledgeableConditionNode` und `OpcAlarmConditionNode`) einschließlich der davon abgeleiteten Subtypen kann ab dieser Version abweichen. So entspricht der Initialwert der Zustandsmaschine des jeweiligen Condition-Typs. Die einzelnen Conditions beschreibt OPC UA Part 9, weitere Details enthält die Dokumentation der neuen Enumeration `OpcConditionRetainPolicy`. Der jeweilige Condition-Typ verwendet standardmäßig die passende Policy, um konforme Initialwerte zu liefern. Um das zu überschreiben, setzen Sie die Eigenschaft `OpcConditionNode.IsRetainedPolicy` auf den Wert `OpcConditionRetainPolicy.Manual`. Damit erhalten Sie die volle Kontrolle über die Eigenschaft `IsRetained`.

### [2.58](https://www.traeger.de/docs/development/opcua/version-history#_2-58)

- Bruch (2.58.0.0): Neuer Typ `OpcRawObject`. Er stellt den Wert einer Struktur, die das SDK nicht dekodieren kann (ein unbekannter Datentyp oder ein Feld ohne festen ValueRank), mit seiner Kodierung und seinem kodierten Inhalt dar. `OpcData.Encode` kodiert eine Struktur als `OpcRawObject`. Code, der für den Wert einer unbekannten Struktur ein Byte-Array oder ein `XmlElement` erwartet hat, erhält jetzt ein `OpcRawObject`. Dessen `RawData` enthält, was bisher zurückgegeben wurde.
- Bruch (2.58.0.0): Neue Attribute `RolePermissions`, `UserRolePermissions`, `AccessRestrictions` und `AccessLevelEx` in `OpcAttribute` und `OpcAttributes`, das neue Member `DataTypeDefinition` von `OpcAttributes` sowie die neuen Typen `OpcRolePermission` und `OpcPermissions`. Das Lesen des Attributs DataTypeDefinition liefert jetzt ein `OpcDataTypeInfo` statt einer `StructureDefinition` oder `EnumDefinition` des Stacks. Das Lesen von RolePermissions oder UserRolePermissions liefert ein Array von `OpcRolePermission` statt `RolePermissionType`.
- Bruch (2.58.0.0): Die `CertificateFactory` des Stacks ist nicht mehr Teil der öffentlichen API des Pakets, weil das SDK weder das Signieren durch eine Zertifizierungsstelle (CA) noch das Erzeugen von Sperrlisten (CRL) anbietet. Code, der `CertificateFactory` verwendet, lässt sich nicht mehr kompilieren.
- Bruch (2.58.0.0): `OpcSecurityAlgorithm.Auto` sowie die Standardendpunkte des Discovery-Servers und des OPC-Classic-Wrapper-Servers verwenden `Basic256Sha256` statt der veralteten Policies `Basic256` (`Sign`) und `Basic128Rsa15` (`SignAndEncrypt`). Ein Client mit `Auto` verbindet sich nicht mehr mit einem Server, der nur die veralteten Policies anbietet.
- Geändert (2.58.0.0): Das Zertifikat, das das SDK für einen `OpcServer` erstellt, nennt auch den vollqualifizierten Namen des Rechners. So akzeptieren es Clients, die sich über diesen Namen verbinden. Ein vorhandenes Zertifikat bleibt unverändert.
- Bruch (2.58.0.0): Der `OpcServer` meldet Audit-Ereignisse nur noch, solange `OpcServerSecurity.IsAuditingEnabled` den Wert `true` hat. Er meldet sie nur an Clients, die über `SignAndEncrypt` oder HTTPS mit einem Benutzer in der Rolle SecurityAdmin verbunden sind, wie OPC UA es festlegt. Audit-Ereignisse zu Sitzungen meldet ein Server erst, nachdem `IsAuditingEnabled` auf `true` gesetzt wurde.
- Bruch (2.58.0.0): `State`, `StateChanged` und `BreakDetected` des `OpcClient` folgen einem Verbindungsverlust, den ein fehlschlagender Dienstaufruf erkennt (zum Beispiel `BadConnectionClosed` oder `BadSessionIdInvalid`), sofort statt erst mit dem nächsten Keep-Alive. Eine neu erstellte Sitzung verbindet sich innerhalb eines Intervalls wieder mit einem neu gestarteten Server. Code, der sich darauf verlassen hat, dass sich der Zustand nur mit dem Keep-Alive ändert, sieht die Änderung jetzt früher.
- Bruch (2.58.0.0): Das Datentypsystem von OPC UA enthält jetzt alle vordefinierten Datentypen (zum Beispiel `Integer`, `UInteger`, `Enumeration` oder `Image`). Jeder Datentyp nennt seinen Supertyp als `BaseType`. Felder von Datentypen, die von einem eingebauten Typ abgeleitet sind (zum Beispiel `Duration`, `UtcTime` oder `LocaleId`), werden jetzt dekodiert. Eingebaute Typen und die Strukturen von OPC UA nennen ihren Supertyp jetzt als `BaseType`, bisher nannten sie keinen. Ein Feld eines von `ByteString` abgeleiteten Typs liefert ein `ByteString` statt eines Byte-Arrays.
- Geändert (2.58.0.0): Der `OpcServer` meldet eine Verbindung, die ein Client zurückgesetzt hat, im Trace nicht mehr als Fehler, weder beim Lesen noch beim Schließen des Sockets.
- Bruch (2.58.0.0): `OpcClient.ReconnectTimeout` und `DefaultReconnectTimeout` sind als veraltet (obsolete) gekennzeichnet. Verwenden Sie stattdessen `ReconnectInterval` und `DefaultReconnectInterval`. Code, der sie verwendet, erhält eine Compiler-Warnung und mit `TreatWarningsAsErrors` einen Compiler-Fehler.
- Bruch (2.58.0.0): Die Historiendienste für einzelne Nodes `OpcClient.ReadNodeHistoryProcessed`, `ReadNodeHistoryAtTime` und `ReadNodeHistoryModified` lösen für einen Node, den der Server abgelehnt hat, eine `OpcException` mit dem Statuscode des Servers aus (zum Beispiel `BadAggregateNotSupported`). Für einen Node, den der Server ohne Werte akzeptiert hat, liefern sie ein leeres Ergebnis. Bisher wurde in beiden Fällen eine `KeyNotFoundException` ausgelöst. Code, der die `KeyNotFoundException` abfängt, muss jetzt die `OpcException` abfangen.
- Bruch (2.58.0.0): `OpcDiscoveryClient` (`DiscoverEndpoints`, `DiscoverServers` und seine Konstruktoren) löst eine `OpcException` mit dem Grund aus (zum Beispiel `BadSecureChannelClosed`), wenn der Server nicht erreichbar ist, den Kanal während des Handshakes schließt oder die Discovery-URL ein nicht unterstütztes Schema verwendet. Die Navigatoren der Historie von `OpcClient.ReadNodeHistory` und `ReadEventHistory` lösen eine `OpcException` mit `BadCommunicationError` aus, wenn eine Seite nicht innerhalb der maximalen Anzahl von Anfragen abgeschlossen wurde. Bisher wurde die `ServiceResultException` des Stacks ausgelöst. Code, der die `ServiceResultException` abfängt, muss jetzt die `OpcException` abfangen.
- Bruch (2.58.0.0): `OpcViewDescription.Default` ist jetzt ein statisches, schreibgeschütztes Feld (`static readonly`), damit sich die Standard-View nicht ersetzen lässt. Code, der `OpcViewDescription.Default` einen Wert zuweist, lässt sich nicht mehr kompilieren. Code, der gegen eine ältere Version kompiliert wurde und `OpcViewDescription.Default` liest, muss neu kompiliert werden, weil aus der Eigenschaft ein Feld geworden ist.
- Bruch (2.58.0.0): Problem mit dem `OpcServer`, bei dem ein Start die `ServerConfiguration` der Anwendung veränderte. Dadurch bot ein Neustart anonymen Zugriff an, obwohl nur die `OpcUserNameAcl` aktiviert war. Der Server arbeitet jetzt mit einer Kopie der Konfiguration. Code, der `Configuration.ServerConfiguration` nach dem Start liest, sieht die Werte, die er selbst gesetzt hat, statt der verwendeten Policies.
- Bruch (2.58.0.0): Problem beim Lesen der verarbeiteten Historie (zum Beispiel mit `OpcClient.ReadNodeHistoryProcessed`), das beide Zeitstempel anforderte. Dadurch konnte ein Server die Anfrage mit `BadTimestampsToReturnInvalid` ablehnen. Das Problem bestand seit Version 1.5.11.0. Die verarbeiteten Werte tragen keinen Server-Zeitstempel mehr.
- Bruch (2.58.0.0): Problem mit einer Struktur aus einem Data Type Dictionary, deren Feld auf einen Datentyp verweist, der nur über seine DataTypeDefinition bekannt ist. Der Client konnte eine solche Struktur nicht auflösen. Das Problem bestand seit Version 2.40.0.0. `Name` und `XmlName` eines solchen Datentyps nennen jetzt den Namespace seines Nodes statt des Namespace von OPC UA.

### [2.59](https://www.traeger.de/docs/development/opcua/version-history#_2-59)

- Bruch (2.59.0.0): Die veraltete Abhängigkeit `Portable.BouncyCastle` (Version 1.9.0) ist durch `BouncyCastle.Cryptography` (Version 2.7.0) ersetzt. Deren Assembly heißt `BouncyCastle.Cryptography.dll` statt `BouncyCastle.Crypto.dll`. `CertificateFactoryRandomGenerator` bietet zusätzlich `AddSeedMaterial(ReadOnlySpan<byte>)` und `NextBytes(Span<byte>)`, die der `IRandomGenerator` von `BouncyCastle.Cryptography` ab .NET 6 deklariert. Anwendungen, die die Assemblies selbst verteilen, müssen `BouncyCastle.Cryptography.dll` statt `BouncyCastle.Crypto.dll` verteilen. Anwendungen, die `Portable.BouncyCastle` selbst referenzieren und dessen Typen verwenden, müssen auf `BouncyCastle.Cryptography` umstellen, weil beide Pakete dieselben Typen enthalten.
- Geändert (2.59.0.0): Die Abhängigkeit von `System.Management` entfällt.
- Bruch (2.59.0.0): Die Operatoren `<`, `<=`, `>`, `>=` und `==` von `OpcFilterOperand` lösen eine `ArgumentNullException` aus, wenn der linke Operand `null` ist. Die Konstruktoren von `OpcContentFilterElement` lösen eine `ArgumentNullException` für Operanden aus, die `null` sind. Bisher wurde eine `NullReferenceException` ausgelöst. Code, der die `NullReferenceException` abfängt, muss jetzt die `ArgumentNullException` abfangen.
- Bruch (2.59.0.0): Die Klasse `OpcContentFilterElementFactory`, die keine öffentlichen Member hatte, entfällt. Code, der den Typ nennt, lässt sich nicht mehr kompilieren. Eine Instanz des Typs ließ sich nie erhalten.
- Bruch (2.59.0.0): `EndpointDescriptionExtensions.SetEndpointPolicy` löst eine `ArgumentNullException` aus, wenn die Endpunkt-Policy `null` ist. Der Indexer von `OpcSecurityPolicyCollection` löst eine `ArgumentNullException` aus, wenn ihm `null` zugewiesen wird. Bisher löste `SetEndpointPolicy` eine `NullReferenceException` aus, und der Indexer speicherte einen Eintrag ohne Policy. Code, der die `NullReferenceException` abfängt, muss jetzt die `ArgumentNullException` abfangen. Code, der über den Indexer `null` zuweist, schlägt jetzt fehl.
- Bruch (2.59.0.0): Das Ereignis `CertificateRequested` von `OpcServer` und `OpcClient` tritt auch ein, wenn das Anwendungszertifikat vorhanden, aber ungültig ist, mit dem Grund `Invalid`, `UseNotAllowed`, `Revoked`, `TimeInvalid`, `IssuerUseNotAllowed`, `IssuerRevoked` oder `IssuerTimeInvalid` (zum Beispiel `TimeInvalid` bei einem abgelaufenen Zertifikat). Das Zertifikat wird nie automatisch ersetzt (`AutoCreateCertificate` der Ereignisdaten ist `false`). Stellt der Handler kein alternatives Zertifikat bereit, bleibt es in Gebrauch, und ein Trace-Eintrag wird geschrieben. Bisher wurde ein solches Zertifikat ohne Hinweis verwendet. Das Ereignis tritt jetzt auch ein, wenn ein Server mit einem ungültigen Anwendungszertifikat startet oder ein Client sich damit verbindet. Handler, die jeden Grund wie ein fehlendes Zertifikat behandeln, werden also auch in diesem Fall aufgerufen.
- Bruch (2.59.0.0): `OpcEventContext` entfällt; das SDK hat diesen Typ nie erstellt oder zurückgegeben. Code, der `OpcEventContext` verwendet, lässt sich nicht mehr kompilieren.
- Bruch (2.59.0.0): `ExtensionObjectExtensions.To<T>` löst für ein Extension Object, das `null` ist, eine `ArgumentNullException` statt einer `NullReferenceException` aus. `Children` von `OpcAddObjectTypeNode` und `OpcAddVariableTypeNode` lösen eine `ArgumentNullException` statt einer `NullReferenceException` aus, wenn ein Command hinzugefügt oder zugewiesen wird, der `null` ist. Code, der die `NullReferenceException` abfängt, muss jetzt die `ArgumentNullException` abfangen.
- Geändert (2.59.0.0): Ein eigener `IOpcNodeHistoryProvider` sollte auch den Wert direkt vor und den Wert direkt nach dem angeforderten Zeitraum liefern, damit der Server Werte interpolieren kann, wenn die Historie zu bestimmten Zeitpunkten oder verarbeitet gelesen wird. Andernfalls ergeben solche Lesevorgänge weiterhin `BadNoData`.
- Bruch (2.59.0.0): `OpcNodeHistory<T>` verwendet als Standardkapazität -1 (unbegrenzt) statt 0. Mit 0 schlug jeder Aufruf von `Add` fehl. Eine Kapazität von 0 oder kleiner als -1 wird jetzt mit einer `ArgumentOutOfRangeException` abgelehnt, auch von den Konstruktoren von `OpcNodeHistorian`. Code, der die Kapazität 0 übergibt (zum Beispiel `new OpcNodeHistory<T>(0, values)`), schlägt jetzt mit einer `ArgumentOutOfRangeException` fehl.
- Bruch (2.59.0.0): `OpcNodeHistorian.ModifiedHistory` ist ein `OpcModifiedNodeHistory` statt eines `OpcNodeHistory<OpcModifiedHistoryValue>`. Code, der die Eigenschaft als `OpcNodeHistory<OpcModifiedHistoryValue>` verwendet, muss angepasst werden: `GetValues(DateTime)` ersetzt den Indexer nach Zeitstempel, `RemoveAt(DateTime)`, `Replace` und das Ereignis `Replaced` gibt es nicht mehr. Code, der gegen eine ältere Version kompiliert wurde, muss neu kompiliert werden.
- Bruch (2.59.0.0): Das Lesen (zum Beispiel mit `OpcClient.ReadNodeHistoryModified`) und das Löschen (zum Beispiel mit `OpcClient.DeleteNodeHistoryModified`) der geänderten Historie eines `OpcNodeHistorian` beziehen sich auf die Zeitstempel der Werte statt auf die Änderungszeitpunkte. Mehrere Änderungen eines Werts kommen in der Reihenfolge von der neuesten zur ältesten, auch beim Rückwärtslesen. Code, der die geänderte Historie über einen Zeitraum von Änderungszeitpunkten liest oder löscht, erhält oder löscht jetzt andere Werte.
- Bruch (2.59.0.0): `OpcClient.BrowseNode(OpcBrowseNode)` und `OpcClient.BrowseNodes` lösen für einen Command, der `null` ist, eine `ArgumentNullException` aus. Bisher wurde eine `NullReferenceException` ausgelöst. Code, der die `NullReferenceException` abfängt, muss jetzt die `ArgumentNullException` abfangen.
- Bruch (2.59.0.0): `OpcClient.CallFunc` löst eine `InvalidCastException` aus, wenn das erste Ausgabeargument `null` ist und der Ergebnistyp ein Werttyp ist, der nicht `null` sein kann. Bisher wurde eine `NullReferenceException` ausgelöst. Code, der die `NullReferenceException` abfängt, muss jetzt die `InvalidCastException` abfangen.
- Bruch (2.59.0.0): `OpcClient.CallMethods` löst für einen Command, der `null` ist, eine `ArgumentNullException` aus. Bisher wurde ein solcher Command übersprungen, sodass die Ergebnisse der folgenden Commands am Index des vorherigen Commands zurückgegeben wurden. Ein Aufruf, bei dem alle Commands `null` waren, schlug mit einer `OpcException` mit `BadNothingToDo` fehl. Code, der einen Command übergibt, der `null` ist, schlägt jetzt fehl, statt verschobene Ergebnisse zu erhalten.
- Bruch (2.59.0.0): Die Überladungen für einen einzelnen Command `OpcClient.CallMethod(OpcCallMethod)`, `ReadNodeHistory(..., OpcReadNodeHistory)`, `CreateNodeHistory`, `ReplaceNodeHistory`, `UpdateNodeHistory`, `DeleteNodeHistory`, `DeleteNodeHistoryAtTime` und `DeleteNodeHistoryModified` lösen für einen Command, der `null` ist, eine `ArgumentNullException` mit dem `ParamName` `command` aus. Bisher lautete der `ParamName` `commands.Item`, und `CallMethod(OpcCallMethod)` schlug mit einer `OpcException` mit `BadNothingToDo` fehl. Code, der für einen Command, der `null` ist, die `OpcException` von `CallMethod(OpcCallMethod)` abfängt, muss jetzt die `ArgumentNullException` abfangen.
- Bruch (2.59.0.0): Die Konstruktoren von `OpcServer`, die eine Folge von Nodes übernehmen, lösen für einen Node, der `null` ist, eine `ArgumentNullException` aus. Bisher schlug `OpcServer.Start()` mit einer `OpcException` fehl. Die Ausnahme tritt jetzt beim Erstellen des Servers auf und ist eine `ArgumentNullException` statt einer `OpcException`.
- Bruch (2.59.0.0): `OpcNode.ReadAttributeValueCore` und `OpcNode.WriteAttributeValueCore` lösen für einen Wert, der `null` ist, eine `ArgumentNullException` aus. Bisher wurde eine `NullReferenceException` ausgelöst. Eine abgeleitete Klasse, die die `NullReferenceException` abfängt, muss jetzt die `ArgumentNullException` abfangen.
- Bruch (2.59.0.0): Die aus Commands erstellten Dienstanfragen (zum Beispiel `OpcCallMethodsRequest`, `OpcReadNodesRequest` oder `OpcWriteNodesRequest`) lösen für einen Command, der `null` ist, eine `ArgumentNullException` aus. Bisher wurde ein solcher Command übersprungen, sodass die Ergebnisse der folgenden Commands dem falschen Command zugeordnet wurden. Code, der einen Command übergibt, der `null` ist, schlägt jetzt fehl, statt verschobene Ergebnisse zu erhalten.
- Bruch (2.59.0.0): `OpcClient.CreateSubscription` löst eine `OpcException` mit `BadServerNotConnected` aus, wenn der Client nicht verbunden oder bereits getrennt wurde. Bisher wurde eine `NullReferenceException` ausgelöst. Code, der die `NullReferenceException` abfängt, muss jetzt die `OpcException` abfangen.
- Bruch (2.59.0.0): `OpcEventFilterFactory.Select` löst für Operanden, die `null` sind, eine `ArgumentNullException` aus. Bisher wurde eine `NullReferenceException` ausgelöst, während der Client verbunden war. Code, der die `NullReferenceException` abfängt, muss jetzt die `ArgumentNullException` abfangen.
- Bruch (2.59.0.0): `OpcEventFilterConstrainedFactory.Where` verknüpft die angegebene Bedingung mit der Bedingung der Factory durch ein logisches UND, wie ein einzelnes `Where` mit beiden Bedingungen, verknüpft durch den Operator `&`. Bisher wurden die Elemente der angegebenen Bedingung nur angehängt. Dadurch blieb die erste Bedingung das Wurzelelement des Filters, und Element-Operanden der angehängten Bedingung verwiesen auf falsche Elemente. Ein Ereignisfilter aus verketteten Aufrufen von `Where` schränkt die Ereignisse jetzt nach allen Bedingungen ein, sodass ein MonitoredItem möglicherweise weniger Ereignisse erhält als bisher.
- Bruch (2.59.0.0): `OpcClientApplication.Exit` trennt den Client auch in den Zuständen `Connecting`, `Reconnecting` und `Reconnected` (der Zustand, den der Client nach einer Wiederverbindung mit derselben Sitzung annimmt). Während sich der Client verbindet, wartet `Exit`, bis der Verbindungsaufbau abgeschlossen ist. In einer nicht interaktiven Umgebung beendet `Exit` auch `Run`, wenn der Client bereits getrennt ist, zum Beispiel weil die Wiederverbindung fehlgeschlagen ist. Bisher tat `Exit` in diesen Zuständen nichts: Der Client blieb verbunden oder versuchte weiter, sich wieder zu verbinden, und `Run` kehrte in einer nicht interaktiven Umgebung nicht zurück (zum Beispiel wurde ein Dienst nicht beendet). Die Ereignisse `Exiting` und `Exited` treten jetzt auch in den Zuständen `Connecting`, `Reconnecting` und `Reconnected` ein.
- Bruch (2.59.0.0): Die Konstruktoren von `OpcClientApplication`, `OpcServerApplication` und `OpcServerServiceApplication` prüfen ihre Argumente, bevor die Anwendung für den aktuellen Thread registriert wird. Bisher blieb nach einem Konstruktor, der eine `ArgumentNullException` auslöste, die fehlgeschlagene Instanz registriert: `OpcApplication.Current` lieferte sie, und der nächste Konstruktor im selben Thread löste eine `InvalidOperationException` aus, bis die Garbage Collection die Instanz freigegeben hatte. Nach einem fehlgeschlagenen Erstellen liefert `OpcApplication.Current` jetzt `null` statt der fehlgeschlagenen Instanz.
- Geändert (2.59.0.0): Eine Anwendung, die ohne Aufruf von `Exit` von der Garbage Collection freigegeben wurde, verhindert nicht mehr, dass im selben Thread die nächste Anwendung erstellt wird. Bisher löste der nächste Konstruktor eine `ArgumentException` aus.
- Geändert (2.59.0.0): Anwendungen lassen sich gleichzeitig in mehreren Threads erstellen und beenden. Bisher konnte das die Registrierung beschädigen, sodass `OpcApplication.Current` die Anwendung eines anderen Threads lieferte oder eine Ausnahme ausgelöst wurde.
- Bruch (2.59.0.0): `OpcServerApplication.Exit` stoppt den Server auch im Zustand `Suspended`. Bisher tat `Exit` in diesem Zustand nichts, sodass der Server angehalten blieb und `Run` in einer nicht interaktiven Umgebung nicht zurückkehrte. Die Ereignisse `Exiting` und `Exited` treten jetzt auch in diesem Zustand ein.
- Geändert (2.59.0.0): `OpcNodeManager.SyncRoot`, `GetNode(string)` und `IsNodeReadyToPublish` lösen eine `InvalidOperationException` aus, solange der Server, der den Node-Manager verwendet, noch nicht gestartet ist, wie die anderen Member des Node-Managers, die einen gestarteten Server voraussetzen. Bisher wurde eine `NullReferenceException` ausgelöst.
- Geändert (2.59.0.0): `OpcClient.BrowseNode` und `BrowseNodes` verwenden `OpcBrowseNode.IncludeSubtypes`, sobald die Eigenschaft gesetzt ist, wie der Dienst Browse. Ein Command, bei dem der Wert nicht gesetzt ist, folgt wie bisher den Subtypen seiner Referenztypen.
- Bruch (2.59.0.0): Die HTTPS-Endpunkte des `OpcServer` überlassen die Wahl der TLS-Versionen dem Betriebssystem, statt TLS 1.0, 1.1 und 1.2 anzubieten. Clients, die nur TLS 1.0 oder 1.1 unterstützen, können sich nicht mehr über HTTPS verbinden, wenn das Betriebssystem diese Versionen deaktiviert hat.
- Bruch (2.59.0.0): Problem mit `OpcFilterOperand.Between`, das die Operanden in der Reihenfolge untere Grenze, Operand, obere Grenze übergab. Dadurch prüfte zum Beispiel `a.Between(1, 5)`, ob 1 zwischen `a` und 5 liegt, statt ob `a` zwischen 1 und 5 liegt. Die Operanden werden jetzt in der Reihenfolge übergeben, die OPC UA festlegt. Code, der das Problem ausgeglichen hat, indem er `Between` auf der unteren Grenze aufruft (zum Beispiel `lower.Between(a, upper)`), prüft jetzt, ob die untere Grenze zwischen `a` und der oberen Grenze liegt, und muss auf `a.Between(lower, upper)` umgestellt werden.
- Bruch (2.59.0.0): Problem mit `OpcHistoryValue.Create(OpcValue)`, das einen Historienwert erstellte, der die Daten des angegebenen Werts teilte. Wurde der Wert eines der beiden gesetzt, änderten sich die Daten des anderen, während dessen Eigenschaft `Value` weiterhin den vorherigen Wert lieferte. Der Historienwert verwendet jetzt eine Kopie der Daten. Code, der einen `OpcValue` nach der Übergabe an `Create` ändert oder einen mit `Create` erstellten Historienwert ändert, ändert die Daten des jeweils anderen Werts nicht mehr.
- Bruch (2.59.0.0): Problem mit `OpcSecurityPolicyCollection.CopyTo`, das jede Policy ab dem angegebenen Array-Index an denselben Index des Arrays kopierte, sodass die Policies vor diesem Index fehlten. Bei einem leeren Array schlug die Methode mit einer `ArgumentOutOfRangeException` fehl. Die Methode kopiert jetzt alle Policies ab dem angegebenen Index in das Array, wie `List<T>.CopyTo`, und löst eine `ArgumentException` aus, wenn das Array zu klein ist. Code, der einen Array-Index größer als null übergibt, erhält alle Policies ab diesem Index statt eines Teils davon an ihrem eigenen Index. Code, der ein Array übergibt, das für alle Policies zu klein ist, erhält eine `ArgumentException`.
- Bruch (2.59.0.0): Problem mit dem Ereignis `CertificateRequested` von `OpcServer` und `OpcClient`, bei dem ein über `AlternativeCertificate` der Ereignisdaten bereitgestelltes Zertifikat nicht verwendet wurde: Ein Server ohne Anwendungszertifikat startete nicht („Server does not have an instance certificate assigned“), andernfalls blieb das Zertifikat des Anwendungsspeichers in Gebrauch. Das bereitgestellte Zertifikat wird jetzt verwendet, auch bei späteren Starts und Verbindungen; es muss seinen privaten Schlüssel enthalten. Handler, die `AlternativeCertificate` auf ein anderes Zertifikat setzen, ändern jetzt das Zertifikat, das die Anwendung verwendet.
- Bruch (2.59.0.0): Problem mit `OpcStruct`, bei dem das Erstellen des Datentyps einer Struktur mit einem Array-Feld, dessen Datentyp unbekannt ist, mit einer `NullReferenceException` fehlschlug. Jetzt wird eine `InvalidOperationException` ausgelöst, die den Datentyp, das Feld und die Struktur nennt. Code, der in diesem Fall die `NullReferenceException` abfängt, fängt die `InvalidOperationException` nicht ab.
- Bruch (2.59.0.0): Problem mit `OpcEnum`: Felder ohne Wert erhielten den Wert 0, wenn ein anderes Feld mit einem Wert ungleich 0 definiert war, und die angegebenen Instanzen von `OpcEnumField` wurden verändert. Wie in C# folgt ein Feld ohne Wert jetzt dem Wert des vorherigen Felds (`A, B, C = 5, D` ergibt 0, 1, 5, 6), und die angegebenen Instanzen bleiben unverändert. Enumerationen mit Feldern ohne Wert neben Feldern mit Wert sowie Enumerationen, deren Felder alle mit dem Wert 0 definiert sind, erhalten andere Werte. `Value` eines ohne Wert angegebenen `OpcEnumField` bleibt 0, und `GetFields` liefert Kopien.
- Bruch (2.59.0.0): Problem mit dem `OpcServer`, bei dem eine Anfrage der Dienste AddNodes, AddReferences, DeleteNodes, DeleteReferences oder Call, die einen Command mit einem Null-Bezeichner enthielt, als Ganzes abgelehnt wurde (`BadNothingToDo`, bei AddNodes, DeleteNodes und DeleteReferences `BadUnexpectedError`). Die übrigen Commands werden jetzt ausgeführt, und der Command mit dem Null-Bezeichner erhält den Status, den OPC UA festlegt (`BadParentNodeIdInvalid`, `BadNodeIdInvalid`, `BadSourceNodeIdInvalid`, `BadTargetNodeIdInvalid`, `BadReferenceTypeIdInvalid` oder `BadMethodInvalid`). Das Problem bestand seit Version 2.7.0.0, bei Call seit Version 2.50.5.0. Eine solche Anfrage wird nicht mehr abgelehnt: `RequestValidating` tritt mit einem guten Ergebnis ein, die Anfrage wird verarbeitet und nicht in `RejectedRequestsCount` der Serverdiagnose gezählt. Serveranwendungen, die sich auf die Ablehnung verlassen haben, müssen Commands mit einem Null-Bezeichner selbst behandeln.
