# Upgrade to a new version

> Reference: All changes of the OPC UA .NET SDK that affect existing code when you upgrade to a newer version, filtered by from and to version.

> This content was machine translated and may contain errors. [Read in German](https://www.traeger.de/docs/development/opcua/upgrade)

This page lists all changes that can affect existing code when you upgrade to a newer version of the OPC UA .NET SDK: changed interfaces and behavior, renamings, and new requirements. Select the version you use today and the version you upgrade to. The list then shows the changes in between, in the order in which they were added.

The entries come from the [Version history](https://www.traeger.de/en/docs/development/opcua/version-history). The version number above each section leads to the complete release notes of that version, including new features and fixes.

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

- Changed (1.5.5.0): Moved the `Identity` and `ImpersonationContext` classes from the `Opc.UaFx.Server` to the `Opc.UaFx` namespace.
- Changed (1.5.6.7): The `OpcValueLabel` is now no longer defined as a struct; instead it is now a class.

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

- Changed (1.6.5.2): Removed implicit interpretation of a numeric node identifier encoded as a string.

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

- Changed (2.2.2.0): Simplified `OpcValue.ToString` implementation to just provide `null` for null references or the `Value.ToString()`.

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

- Changed (2.3.0.0): The SDK no longer supports Windows-based authentication using the WinLogon API for OPC UA server authentication.
- Changed (2.3.0.0): Application certificates are now created using SHA256 (the default defined by the Foundation). This does not influence any running code. This change will only have an effect when a new certificate is generated.
- Attention (2.3.1.0): Starting with this version, a reference to the NuGet package `Portable.BouncyCastle` (at least version 1.8.1.3) or the `BouncyCastle.Crypto` assembly (at least version 1.8.1.146) is required.
- Attention (2.3.1.0): Using a server address with the scheme `https` requires references to the NuGet packages `Microsoft.AspNetCore.Server.Kestrel` (1.1.3) and `Microsoft.AspNetCore.Server.Kestrel.Https` (1.1.3).
- Changed (2.3.2.0): `OpcVariableNode` defined as an abstract base class.
- Changed (2.3.2.0): Removed multiple local Foundation node references to reduce memory usage.

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

- Changed (2.5.0.0): Corrected misspelled members.
- Changed (2.5.0.0): Streamlined API through additional descriptive parts in class and delegate names. In general, changed the naming of `Data` to `DataSet`, `DataItem` to `DataSetItem` and `EventRaise` to `Event`.
- Changed (2.5.0.0): `OpcNodeId.ToString` now formats by default using the `OpcNodeIdFormat.Foundation` format.
- Changed (2.5.0.0): Order of subscription events from MonitoredItem → Client → Subscription to MonitoredItem → Subscription → Client, to ensure a more logical event order using bubbling.
- Changed (2.5.0.0): Renamed `OpcMonitoredItem.ReceivedDataChange` to `OpcMonitoredItem.DataChangeReceived`.
- Changed (2.5.0.0): Renamed `OpcMonitoredItem.ReceivedEventRaise` to `OpcMonitoredItem.EventRaiseReceived`.
- Renamed (2.5.0.0): `OpcSubscribeEventRaise` -&gt; `OpcSubscribeEvent`
- Renamed (2.5.0.0): `OpcDataChangeEventArgs` -&gt; `OpcDataChangeReceivedEventArgs`
- Renamed (2.5.0.0): `OpcDataChangeEventHandler` -&gt; `OpcDataChangeReceivedEventHandler`
- Renamed (2.5.0.0): `OpcEventRaiseEventArgs` -&gt; `OpcEventReceivedEventArgs`
- Renamed (2.5.0.0): `OpcEventRaiseEventHandler` -&gt; `OpcEventReceivedEventHandler`
- Renamed (2.5.0.0): `OpcNotificationEventArgs` -&gt; `OpcNotificationReceivedEventArgs`
- Renamed (2.5.0.0): `OpcNotificationEventHandler` -&gt; `OpcNotificationReceivedEventHandler`
- Renamed (2.5.0.0): `OpcDataChangeCallback` -&gt; `OpcDataChangeReceivedCallback`
- Renamed (2.5.0.0): `OpcEventRaiseCallback` -&gt; `OpcEventReceivedCallback`
- Renamed (2.5.0.0): `IOpcNotificationData` -&gt; `IOpcNotificationDataSet`
- Renamed (2.5.0.0): `OpcNotificationData` -&gt; `OpcNotificationDataSet`
- Renamed (2.5.0.0): `OpcNotificationDataCollection` -&gt; `OpcNotificationDataSetCollection`
- Renamed (2.5.0.0): `OpcNotificationDataReadOnlyCollection` -&gt; `OpcNotificationDataSetReadOnlyCollection`
- Renamed (2.5.0.0): `OpcNotificationDataItem` -&gt; `OpcNotificationDataSetItem`
- Renamed (2.5.0.0): `OpcNotificationDataItemCollection` -&gt; `OpcNotificationDataSetItemCollection`
- Renamed (2.5.0.0): `OpcNotificationDataItemReadOnlyCollection` -&gt; `OpcNotificationDataSetItemReadOnlyCollection`
- Renamed (2.5.0.0): `OpcDataChange` -&gt; `OpcDataChangeSet`
- Renamed (2.5.0.0): `OpcDataChangeItem` -&gt; `OpcDataChangeSetItem`
- Renamed (2.5.0.0): `OpcEventRaise` -&gt; `OpcEventDataSet`
- Renamed (2.5.0.0): `OpcEventRaiseItem` -&gt; `OpcEventDataSetItem`
- Renamed (2.5.0.0): `OpcMonitoredItem`
  - `.EventRaiseReceived` -&gt; `EventReceived`
  - `.LastEventRaise` -&gt; `LastEvent`
  - `.OnEventRaiseReceived` -&gt; `OnEventReceived`
- Renamed (2.5.0.0): `OpcSubscription`
  - `.EventRaiseReceived` -&gt; `EventReceived`
  - `.ReceivedEventRaiseCallback` -&gt; `ReceivedEventCallback`
  - `.OnEventRaiseReceived` -&gt; `OnEventReceived`
- Renamed (2.5.0.0): `OpcClient`
  - `.EventRaiseReceived` -&gt; `EventReceived`
  - `.OnEventRaiseReceived` -&gt; `OnEventReceived`
  - `.SubscribeEventRaise` -&gt; `SubscribeEvent`
- Changed (2.5.0.1): Downgraded sample projects to C# language version 6.0 to ensure that the samples will compile in older versions of Visual Studio.
- Changed (2.5.1.0): Changed `IsNodeAccessible(..., IOpcNode node)` to `IsNodeAccessible(..., IOpcNodeInfo node)`.
- Changed (2.5.4.0): `OpcNode.BeforeApplyChanges` and `OpcNode.AfterApplyChanges` are now only raised if changes are pending (see `OpcNode.HasPendingChanges`).
- Changed (2.5.5.0): Changed default `MinimumCertificateKeySize` from 2048 to 1024 to support lower key sizes used by older certificates.
- Changed (2.5.5.0): When changing the application certificate of a client or server instance using the `Certificate` property, the store path type of the application certificate store changes to `System`. To use the store path type `Directory`, you have to change the store path type manually and have to ensure that the certificate can be found in the application certificate store after changing the `Certificate` property.
- Changed (2.5.7.0): The application certificate is no longer stored in `.\CertificateStores\Trusted`, now it is stored (by default) in `.\CertificateStores\App` to improve startup performance when searching for the application certificate.
- Changed (2.5.7.0): Changed use of `LinkTime` to `LastWriteTime` of the assembly when determining `OpcServerInfo` from an assembly.

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

- Changed (2.6.0.0): Removed `OpcClientTransport` class (replaced by new `OpcTransport` class).
- Changed (2.6.0.0): Removed `OpcServerTransport` class (replaced by new `OpcTransport` class).
- Changed (2.6.0.0): The default server information provided by `OpcServerBase` now prefers a predefined `ApplicationName`.
- Changed (2.6.0.0): `OpcSecurityPolicyCollection` no longer provides a constructor with an `OpcServerBase` instance. The corresponding `Owner` property has been removed as well.

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

- Changed (2.7.0.0): Removed `OpcServerIdentity.Password` property, because there is no need to publish the internally stored password information and it is not a good practice to provide references to an array through properties.
- Changed (2.7.0.0): Removed `OpcTransformUserPasswordDelegate` delegate.
- Changed (2.7.0.0): Replaced `OpcUserNameAcl.PasswordTransform` with virtual `Matches` and `TransformPassword` methods in `OpcServerIdentity`.
- Changed (2.7.3.0): Reviewed implementation of `OpcMonitoredItem` and `OpcSubscription`: Changed some `int`-based properties to use `long` as the property type to support underlying `uint` properties used by the foundation stack in a `CLSCompliant` way.
- Changed (2.7.4.0): Changed some `int`-based properties in `OpcMonitoredItem`, `OpcServiceCounter`, `OpcSessionDiagnostics` and `OpcServerDiagnostics` to `long` as their property type to assure CLS compliance while accessing the unsigned API of the foundation stack.
- Changed (2.7.5.0): `OpcMonitoredItem.AutoFlushCache` has been replaced with the new `OpcMonitoredItem.QueueMode` property to better express the mechanism used when the notification data item queue of a MonitoredItem overflows.

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

- Changed (2.8.0.0): `OpcDataTypeAttribute` is now applicable on classes and structures.
- Changed (2.8.0.0): Unified `OpcNodeManager.NamespaceIndexes` and `OpcNodeManager.NamespaceUris` into new `OpcNodeManager.Namespaces`.
- Changed (2.8.0.0): Renamed `IOpcReadOnlyDataStore` to `IOpcReadOnlyNodeDataStore`.
- Changed (2.8.0.0): `IOpcNamespaceResolver` methods `Uri Resolve(int namespaceIndex)` and `int Resolve(Uri namespaceUri)` are now obsolete.
- Changed (2.8.1.0): `OpcAutomatism.UseDynamic` property default value is now `false`. Change its value or the `OpcClient.UseDynamic` to `true` to enable use of `OpcDataObject`.
- Changed (2.8.1.2): Adjusted `iconUrl` and `licenseUrl` information in NuGet packages upon their deprecation.
- Changed (2.8.2.0): Explicitly encoded information known as the `EncodingMask` of a structured data type is now handled using the new `Opc.UaFx.Bit` type instead of `System.Boolean`.
- Changed (2.8.3.0): Reviewed `OpcClient.State` changes to detect a lost connection to the server.
- Changed (2.8.3.0): `OpcClient.State` now changes automatically only to `Disconnected` (during a running request) if `ReconnectTimeout` is greater than zero (reconnection is manually handled).

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

- Changed (2.9.0.0): License codes used prior to version 2.9 no longer work. Customers will receive new license keys working in all frameworks supported.
- Changed (2.9.0.0): `OpcAttributeWriteAccess` is now based on `UInt32`.
- Changed (2.9.0.0): The default value of `OpcAutomatism.AlwaysParseStringIdentifiers` is now `false`. As a result, the value is no longer parsed automatically when the constructor `OpcNodeId(string)` is called. For more details, see `OpcAutomatism.AlwaysParseStringIdentifiers`.
- Changed (2.9.0.0): [Client SDK] Moved the `OpcBrowseNode` class from namespace `Opc.UaFx.Client` to namespace `Opc.UaFx`.
- Changed (2.9.0.0): [Client SDK] Moved the `OpcBrowseNodeDegree` enumeration from namespace `Opc.UaFx.Client` to namespace `Opc.UaFx`.
- Changed (2.9.0.0): [Client SDK] `IOpcBrowseService` and `OpcBrowseRequest` now use the classes `OpcViewDescription` and `OpcBrowseNode` instead of the Foundation classes `ViewDescription` and `BrowseDescription`.
- Changed (2.9.0.0): Moved `OpcReadOnlyNamespaceCollection` from namespace `Opc.UaFx.Server` to namespace `Opc.UaFx`.
- Changed (2.9.0.0): Changed the default value of the DataType attribute of `OpcDataTypeDictionaryNode` from Byte to ByteString to match the definition of the specification.
- Changed (2.9.0.0): Renamed `Description` property of `IOpcDataTypeInfo`, `OpcDataTypeInfo` and `OpcDataFieldInfo` to `Documentation` to match the definition of the OPC UA specification.
- Changed (2.9.0.0): `OpcEncoding.All(...)` now constructs the `OpcEncoding.Id` using the default BrowseNames for the different encoding types.
- Changed (2.9.0.0): `OpcNamespace.ToString()` now always returns a string which just represents the `OpcNamespace.Value` and `OpcNamespace.Index` (if not zero).
- Changed (2.9.0.0): `OpcNodeSet.GetDataTypeSystem()` now provides an `OpcDataTypeSystem` instance which uses the typical BrowseName for the type of encoding used by the type system.
- Changed (2.9.0.0): Removed method `IOpcTypeProvider.GetType(OpcEncoding)`, because encoding information only applies to data types.
- Changed (2.9.0.0): `OpcTypeCategory.EventType` and `OpcTypeCategory.ReferenceType` have been removed.

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

- Changed (2.10.0.0): `OpcNode.OnAfterApplyChanges` and `OpcNode.OnBeforeApplyChanges` use `OpcNodeChangesEventArgs` instead of `EventArgs`.
- Changed (2.10.0.0): `OpcNode.AfterApplyChanges` and `OpcNode.BeforeApplyChanges` pass `OpcNodeChangesEventArgs` instead of `EventArgs` to event handlers.

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

- Changed (2.11.0.0): `OpcSession.Close` closes the session and invalidates the session-related identifier.
- Changed (2.11.0.0): `OpcClient` methods validate the connection state using an `OpcException` (with `BadServerNotConnected`) instead of using an `InvalidOperationException`.
- Changed (2.11.0.0): Default `QueueSize` of `OpcMonitoredItem` created using `OpcClient.SubscribeEvent`(s) from `int.MaxValue` to `uint.MaxValue` to enforce that the server uses the maximum queue size supported for event notifications (which was initially intended with the wrong `int.MaxValue`).
- Changed (2.11.0.0): Renamed `OpcMonitoredItemStatus.DataItemQueueSize` to `QueueSize` to match the naming used in `OpcMonitoredItem` (which defines the requested size while the status gives the revised size).
- Changed (2.11.0.0): Returned type of `OpcMonitoredItemStatus.Id` from `Int32` to `Int64` to cover the underlying non-CLS compliant `UInt32` of the Foundation's stack.
- Changed (2.11.0.0): Adopted recently reviewed API of `OpcMonitoredItem` to `OpcMonitoredItemStatus` and reworked `OpcMonitoredItemStatus.AutoFlushCache` to `QueueMode` (as in `OpcMonitoredItem`).
- Changed (2.11.1.0): The constructor of `OpcCertificateJudgementEventArgs` no longer verifies if the specified certificates are a null reference (Nothing in Visual Basic), because some servers might supply no certificate data for endpoints with the policy `None` (mode and algorithm).
- Changed (2.11.3.0): Used data type in `OpcNode.Read/WriteDescriptionCallback` property from `String` to `OpcText`.
- Changed (2.11.3.0): `OpcDataChangeDataSetItem.ClientID` from `Int32` to `Int64` to match the used type in `OpcMonitoredItem.ClientID`.

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

- Changed (2.12.0.0): The `OpcNamespace.Default` namespace now provides the default value and URI used to identify the Foundation's default namespace.
- Changed (2.12.0.0): Removed obsolete methods from `IOpcNamespaceResolver` and all its implementations in `OpcClient`, `OpcServer`, `OpcContext` and `OpcNodeManager`.
- Changed (2.12.0.0): `OpcClient.State` no longer transitions (using the reconnect mechanism activated by default) when calling, for example, `ReadNode` while the `OpcClient` is about to re-establish a broken connection.
- Changed (2.12.0.0): In case of a broken connection, the `OpcClient` tries (by default) to re-establish the connection and re-use the previously used session. If this works, the `OpcClient` will raise the `Reconnected` event as before. If the client has been forced to create a new session (for example, upon timeout of the previous session), the `OpcClient` will now raise the `Connected` event instead of the `Reconnected` event to provide a way to distinguish these conditions in user code.
- Changed (2.12.0.0): Comparison in `OpcNodeId` and `OpcNamespace` to provide results typically used by .NET APIs when comparing to a null reference (this differs from the implementation used by the Foundation).
- Changed (2.12.1.0): Bidirectional references between DataTypeDescription, DataTypeEncoding and DataType nodes are now unidirectional (using default export options).

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

- Changed (2.14.0.0): Removed duplicate references to `DataTypeNodes` when using the `OpcAddressSpace` class to describe the nodes of the server.

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

- Changed (2.18.0.0): Format of ByteString from Base64 encoding to hex (`X2`) encoded / formatted strings, which matches the Foundation's binary encoded representation of a `ByteString`.
- Changed (2.18.2.0): `OpcNodeId` now matches the OPC UA specification and compares node identifiers and namespaces case-sensitively.
- Changed (2.18.3.0): `OpcClassicDiscoveryClient` now uses `OpcException` to represent all stack related exceptions.

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

- Breaking (2.19.0.0): Clients and servers since version 2.17.0.0 do not access or provide file nodes according to the OPC UA specification. They use a byte array instead of ByteString to read and write file contents. This issue has been fixed in this version.
- Breaking (2.19.0.0): `OpcFileReadMethodNode.FileReadCallback` and `OpcFileReadMethodNode.FileReadExCallback` now return a ByteString instead of an array of bytes.
- Breaking (2.19.0.0): `OpcFileWriteMethodNode.FileWriteCallback` and `OpcFileWriteMethodNode.FileWriteExCallback` now accept a ByteString for the data parameter instead of an array of bytes.
- Changed (2.19.0.0): Parameter of `OpcFilterOperand.OfType` from `value : object` to `typeId : OpcNodeId` to assure that an `OfType` operand is evaluated as expected (that is, using an `OpcNodeId`).
- Breaking (2.19.0.0): Regression issue using `OpcFileNode` access using Read and Write operations after enforcing the Foundation's stack to use ByteString for ByteString and `Byte[]` for `Byte[]` instead of using ByteString for `Byte[]`.
- Breaking (2.19.1.0): **Possibly breaking:** `IOpcReadOnlyNodeDataStore` now requires the implementation of `IOpcNamespaceResolver` as well.
- Changed (2.19.2.0): Removed unnecessary new lines in the string representation of `OpcException` instances.

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

- Changed (2.20.0.0): `OpcInstanceNode` now determines its `DefaultTypeDefinitionId` using the node type used to create the instance node.
- Changed (2.20.0.0): `OpcMemberOrigins` now defines an additional enum member `Method` for method origins.

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

- Changed (2.24.0.0): The `OpcNodeAccessToken.IndexRange` is now obsolete, use new `OpcNodeAccessToken.Range` property instead.
- Changed (2.24.0.0): The property type of `OpcReadVariableValueContext(<T>).Range` has been changed from `Ua.NumericRange` to `OpcRange`.
- Changed (2.24.0.0): The property type of `OpcWriteVariableValueContext(<T>).Range` has been changed from `Ua.NumericRange` to `OpcRange`.
- Changed (2.24.0.0): The property type of `OpcReadPropertyValueContext(<T>).Range` has been changed from `Ua.NumericRange` to `OpcRange`.
- Changed (2.24.0.0): The property type of `OpcWritePropertyValueContext(<T>).Range` has been changed from `Ua.NumericRange` to `OpcRange`.

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

- Changed (2.25.0.0): Default size of (auto) encoding mask from one bit to 32 bit to improve usability of the by default expected 32 bit encoding mask.

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

- Changed (2.28.0.0): Disabling `OpcAutomatism.UseDynamicTypeRegistration` resulted in a deferred dynamic type registration at the time a custom data type is manually registered.

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

- Changed (2.29.0.0): `OpcNode.AddNotifier` is no longer supported on other types than `OpcObjectNodes` and their subclasses.

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

- Changed (2.30.0.0): The behavior of starting and stopping an OPC Classic UA Wrapper Server is now more deterministic, as each `OpcClient` uses a dedicated wrapper server, which is now also stopped when the `OpcClient` disconnects.
- Changed (2.30.0.0): The method `OpcCertificateIdentity.Matches()` is now virtual to enable custom identity comparison.
- Changed (2.30.0.0): The `OpcEvent.EventId` property now provides the underlying ByteString instead of a byte-array (before the ByteString was introduced).

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

- Changed (2.31.0.0): Updated `Newtonsoft.Json` dependency to version 13.0.3, to fix a vulnerability.
- Changed (2.31.0.0): The UA Wrapper Server for OPC Classic connections will now always generate a new application certificate, instead of trying to load one from the client's certificate store.
- Changed (2.31.0.0): When no port is specified on an `opc.com:` URL, the port for the classic wrapper server is no longer derived from the `classID` and `progID`, but instead a free dynamic port number is determined. This facilitates using multiple `OpcClients` with the same `opc.com:` URL at the same time.

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

- Changed (2.33.0.0): `OpcContext.Empty.SessionId` no longer provides a null reference (Nothing in Visual Basic). Instead it provides `OpcNodeId.Null`.
- Changed (2.33.0.0): Changed access modifiers of `OpcNodeManager.AddNode(...)` and `OpcNodeManager.RemoveNode(...)` methods from `protected` to `public` for improved usability.
- Changed (2.33.0.0): Evaluation of `OpcVariableNodeInfo.IsArray` now uses the ValueRank value instead of the ArrayDimensions to decide whether the Value attribute provides an array.

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

- Changed (2.41.0.0): User authentication in the `OpcServer` is now done only once during `ActivateSession`, instead of doing it for each request separately.
- Changed (2.41.1.0): Updated `Microsoft.AspNetCore.Server.Kestrel.Core` dependency to version 2.1.25, to fix a vulnerability.

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

- Changed (2.42.0.0): `OpcArgument.ArrayDimensions` and `OpcArgumentInfo.ArrayDimensions` now support null references (Nothing in Visual Basic) when enabled via `OpcAutomatism.UseNullInsteadOfEmptyArrays`. This means whenever a server provides a value of `null` for the `ArrayDimensions` this property will now return a null reference (Nothing in Visual Basic) as well.
- Changed (2.42.4.0): Updated `Portable.BouncyCastle` dependency to version 1.9.0, to fix a vulnerability.

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

- Changed (2.50.0.0): When `OpcClientSecurity.UseOnlySecureEndpoints` is set to `true`, the `OpcClient` now only selects endpoints with a `SignAndEncrypt` mode, and no longer selects ones with a `Sign` mode, because the latter does not provide confidentiality. To use the previous behavior of selecting endpoints with a `Sign` or `SignAndEncrypt` policy, set `client.Security.EndpointPolicy` to one with that mode, and set `OpcClient.Security.AutoUpgradeEndpointPolicy` to `true`. Alternatively, to select the "best" endpoint offered by the server, set `OpcClient.Security.UseHighLevelEndpoint` to `true` (but note that this does not provide security).
- Changed (2.50.0.0): When creating an event filter with `OpcEventFilterFactory.Select()`, the type identifier of the `BaseEventType` is now used by default in the simple attribute operands (as it was before version 2.32.0.0), to ensure that when specifying multiple event types that may have fields with the same name, all fields can be received. To use the previous behavior of specifying the actual event type identifier in the simple attribute operands, specify `OpcEventFieldSelectOptions.UseExplicitEventTypeIds` in `OpcEventFilterFactory.Select()`.
- Changed (2.50.4.0): Wrong `DefaultReferenceTypeId` Organizes of `OpcFolderNode` and adopted use of HasComponent instead. This change addresses CTT compliance.
- Changed (2.50.4.0): `ServerDiagnostics` no longer provides children and any explicit read/write operations on the child nodes using their NodeId result in `BadOutOfService`. This behavior applies for disabled `ServerDiagnostics` and addresses CTT compliance.
- Changed (2.50.5.0): Reworked request validation to validate first the contents of the request and then validate if the operation requested is granted. In addition, any diagnostics (including null references) are provided only if requested. This addresses CTT compliance.
- Changed (2.50.6.0): Moved `Model` property and all other `OpcNodeModel` related API from `OpcInstanceNode` to `OpcNode` to ensure correct node initialization.
- Changed (2.50.7.0): Improved CTT compliance regarding `OpcNode` default initialization and conditionally removed defaults for the Description attribute and for the `SymbolicName` property. To enable the previous behavior, enable the corresponding properties in `OpcAutomatism`.

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

- Changed (2.51.0.0): When using .NET Framework, version 4.7.2 or higher is now required.
- Changed (2.51.0.0): New parameters have been added to the method `IOpcNodeHistoryProvider.ReadHistory()` to support streaming of history values, instead of buffering all values in memory. In particular, the implementation now needs to return the values in reversed order when parameter `timeFlowsBackward` is `true`.

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

- Changed (2.54.0.0): Enhanced certificate validation especially for application instance certificates to support compliant validation of basic constraint extensions. This is required for CTT compliance.
- Changed (2.54.0.0): By default, the listener socket now uses an exclusive address when binding to the port. This behavior can be controlled with the new `OpcServerBinding.UseExclusiveAddress` property.

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

- Changed (2.55.0.0): The initial value of the `OpcConditionNode.IsRetained` property and its subtypes (`OpcAcknowledgeableConditionNode` and `OpcAlarmConditionNode`) including the traversal subtypes might be different starting with this version. This ensures the correct initial value according to the condition type's specific state machine. To understand the different conditions see OPC UA Part 9. In addition the documentation of the new `OpcConditionRetainPolicy` enumeration provides additional details. However the specific condition type uses by default the corresponding policy to provide compliant initial values. To override that you can use the value `OpcConditionRetainPolicy.Manual` for the `OpcConditionNode.IsRetainedPolicy` property to gain full control of the `IsRetained` property.

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

- Breaking (2.58.0.0): Introduced `OpcRawObject`, which represents a value of a structure the SDK cannot decode (an unknown data type or a field without a fixed ValueRank) with its encoding and encoded body, and `OpcData.Encode` to encode a structure as an `OpcRawObject`. Code that expected an array of bytes or an `XmlElement` for a value of an unknown structure now receives an `OpcRawObject`; its `RawData` holds what was returned before.
- Breaking (2.58.0.0): Introduced the attributes `RolePermissions`, `UserRolePermissions`, `AccessRestrictions`, and `AccessLevelEx` in `OpcAttribute` and `OpcAttributes`, the member `DataTypeDefinition` of `OpcAttributes`, and the types `OpcRolePermission` and `OpcPermissions`. Reading the DataTypeDefinition attribute now yields an `OpcDataTypeInfo` instead of a `StructureDefinition` or `EnumDefinition` of the stack, and reading RolePermissions or UserRolePermissions yields an array of `OpcRolePermission` instead of `RolePermissionType`.
- Breaking (2.58.0.0): Removed the `CertificateFactory` of the stack from the public API of the package, since the SDK does not provide CA signing or CRL generation. Code that uses `CertificateFactory` no longer compiles.
- Breaking (2.58.0.0): `OpcSecurityAlgorithm.Auto` and the default endpoints of the discovery server and of the OPC Classic wrapper server use `Basic256Sha256` instead of the deprecated `Basic256` (`Sign`) and `Basic128Rsa15` (`SignAndEncrypt`). A client using `Auto` no longer connects to a server that offers only the deprecated policies.
- Changed (2.58.0.0): The certificate the SDK creates for an `OpcServer` also names the fully qualified name of the machine, so that clients that connect by that name accept it. An existing certificate remains unchanged.
- Breaking (2.58.0.0): `OpcServer` reports audit events only while `OpcServerSecurity.IsAuditingEnabled` is `true`, and only to clients connected over `SignAndEncrypt` or HTTPS with a user in the SecurityAdmin role, as defined by OPC UA. A server reports session audit events only after `IsAuditingEnabled` has been set to `true`.
- Breaking (2.58.0.0): `State`, `StateChanged`, and `BreakDetected` of `OpcClient` follow a lost connection detected by a failing service call (for example `BadConnectionClosed` or `BadSessionIdInvalid`) at once instead of with the next keep-alive, and a recreated session reconnects to a restarted server within one interval. Code that relied on the state changing only with the keep-alive now sees the change earlier.
- Breaking (2.58.0.0): The data type system of OPC UA provides all predefined data types (for example `Integer`, `UInteger`, `Enumeration`, or `Image`), each data type states its supertype as `BaseType`, and fields of data types derived from a built-in type (for example `Duration`, `UtcTime`, or `LocaleId`) are decoded. Built-in types and the structures of OPC UA now state their supertype as `BaseType` instead of none, and a field of a type derived from `ByteString` yields a `ByteString` instead of an array of bytes.
- Changed (2.58.0.0): `OpcServer` no longer traces a connection reset by a client as an error, neither during a read nor when it closes the socket.
- Breaking (2.58.0.0): `OpcClient.ReconnectTimeout` and `DefaultReconnectTimeout` are obsolete; use `ReconnectInterval` and `DefaultReconnectInterval` instead. Code that uses them receives a compiler warning, and a compiler error with `TreatWarningsAsErrors`.
- Breaking (2.58.0.0): The single-node history services `OpcClient.ReadNodeHistoryProcessed`, `ReadNodeHistoryAtTime`, and `ReadNodeHistoryModified` throw an `OpcException` with the status code of the server (for example `BadAggregateNotSupported`) for a node the server rejected, and return an empty result for a node the server accepted without values. Before, a `KeyNotFoundException` was thrown in both cases. Code that catches the `KeyNotFoundException` must catch the `OpcException` instead.
- Breaking (2.58.0.0): `OpcDiscoveryClient` (`DiscoverEndpoints`, `DiscoverServers`, and its constructors) throws an `OpcException` stating the reason (for example `BadSecureChannelClosed`) when the server cannot be reached, closes the channel during the handshake, or the discovery URL uses an unsupported scheme. The history navigators of `OpcClient.ReadNodeHistory` and `ReadEventHistory` throw an `OpcException` stating `BadCommunicationError` when a page was not finished within the maximum number of requests. Before, the `ServiceResultException` of the stack was thrown. Code that catches the `ServiceResultException` must catch the `OpcException` instead.
- Breaking (2.58.0.0): `OpcViewDescription.Default` is now a `static readonly` field, so that the default view cannot be replaced. Code that assigns `OpcViewDescription.Default` no longer compiles. Code compiled against an older version that reads `OpcViewDescription.Default` must be recompiled, because the property has become a field.
- Breaking (2.58.0.0): Issue with `OpcServer`, where a start changed the `ServerConfiguration` of the application, so that a restart offered anonymous access although only the `OpcUserNameAcl` was enabled. The server now works with a copy of the configuration. Code that reads `Configuration.ServerConfiguration` after the start sees the values it set itself instead of the policies in use.
- Breaking (2.58.0.0): Issue with reading processed history (for example `OpcClient.ReadNodeHistoryProcessed`), which requested both timestamps, so that a server could reject the request with `BadTimestampsToReturnInvalid`. The issue existed since version 1.5.11.0. The processed values no longer carry a server timestamp.
- Breaking (2.58.0.0): Issue with a structure described in a data type dictionary whose field refers to a data type known by its DataTypeDefinition only, which the client could not resolve. The issue existed since version 2.40.0.0. The `Name` and `XmlName` of such a data type now state the namespace of its node instead of the namespace of OPC UA.

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

- Breaking (2.59.0.0): Replaced the outdated dependency `Portable.BouncyCastle` (version 1.9.0) with `BouncyCastle.Cryptography` (version 2.7.0), whose assembly is named `BouncyCastle.Cryptography.dll` instead of `BouncyCastle.Crypto.dll`. `CertificateFactoryRandomGenerator` additionally provides `AddSeedMaterial(ReadOnlySpan<byte>)` and `NextBytes(Span<byte>)`, which the `IRandomGenerator` of `BouncyCastle.Cryptography` declares for .NET 6 and later. Applications that deploy the assemblies themselves must deploy `BouncyCastle.Cryptography.dll` instead of `BouncyCastle.Crypto.dll`. Applications that reference `Portable.BouncyCastle` themselves and use its types must change to `BouncyCastle.Cryptography`, since both packages provide the same types.
- Changed (2.59.0.0): Removed the dependency on `System.Management`.
- Breaking (2.59.0.0): The operators `<`, `<=`, `>`, `>=`, and `==` of `OpcFilterOperand` throw an `ArgumentNullException` for a left operand that is `null`, and the constructors of `OpcContentFilterElement` throw an `ArgumentNullException` for operands that are `null`. Before, a `NullReferenceException` was thrown. Code that catches the `NullReferenceException` must catch the `ArgumentNullException` instead.
- Breaking (2.59.0.0): Removed the class `OpcContentFilterElementFactory`, which had no public members. Code that names the type no longer compiles; an instance of the type could never be obtained.
- Breaking (2.59.0.0): `EndpointDescriptionExtensions.SetEndpointPolicy` throws an `ArgumentNullException` for an endpoint policy that is `null`, and the indexer of `OpcSecurityPolicyCollection` throws an `ArgumentNullException` when `null` is set. Before, `SetEndpointPolicy` threw a `NullReferenceException` and the indexer stored an entry without a policy. Code that catches the `NullReferenceException` must catch the `ArgumentNullException` instead, and code that sets `null` using the indexer now fails.
- Breaking (2.59.0.0): The `CertificateRequested` event of `OpcServer` and `OpcClient` also occurs when the application certificate exists but is not valid, with the reason `Invalid`, `UseNotAllowed`, `Revoked`, `TimeInvalid`, `IssuerUseNotAllowed`, `IssuerRevoked`, or `IssuerTimeInvalid` (for example `TimeInvalid` for an expired certificate). The certificate is never replaced automatically (`AutoCreateCertificate` of the event data is `false`); unless the handler provides an alternative certificate, it remains in use and a trace entry is written. Before, such a certificate was used without notice. The event now also occurs when a server starts or a client connects with an invalid application certificate, so handlers that handle each reason like a missing certificate are called in this case too.
- Breaking (2.59.0.0): Removed `OpcEventContext`, which the SDK never created or returned. Code that references `OpcEventContext` no longer compiles.
- Breaking (2.59.0.0): `ExtensionObjectExtensions.To<T>` throws an `ArgumentNullException` instead of a `NullReferenceException` for an extension object that is `null`, and the `Children` of `OpcAddObjectTypeNode` and `OpcAddVariableTypeNode` throw an `ArgumentNullException` instead of a `NullReferenceException` when a command that is `null` is added or set. Code that catches the `NullReferenceException` must catch the `ArgumentNullException` instead.
- Changed (2.59.0.0): A custom `IOpcNodeHistoryProvider` should also return the value directly before and the value directly after the requested time range, so that the server can interpolate values when the history is read at specific times or processed. Otherwise such reads still result in `BadNoData`.
- Breaking (2.59.0.0): `OpcNodeHistory<T>` uses -1 (unlimited) as its default capacity instead of 0, with which each call to `Add` failed. A capacity of 0 or less than -1 is now rejected with an `ArgumentOutOfRangeException`, also by the constructors of `OpcNodeHistorian`. Code that passes a capacity of 0 (for example `new OpcNodeHistory<T>(0, values)`) now fails with an `ArgumentOutOfRangeException`.
- Breaking (2.59.0.0): `OpcNodeHistorian.ModifiedHistory` is an `OpcModifiedNodeHistory` instead of an `OpcNodeHistory<OpcModifiedHistoryValue>`. Code that uses the property as an `OpcNodeHistory<OpcModifiedHistoryValue>` must be changed: `GetValues(DateTime)` replaces the indexer by timestamp, while `RemoveAt(DateTime)`, `Replace`, and the `Replaced` event are no longer available. Code compiled against a previous version must be recompiled.
- Breaking (2.59.0.0): Reading (for example with `OpcClient.ReadNodeHistoryModified`) and deleting (for example with `OpcClient.DeleteNodeHistoryModified`) the modified history of an `OpcNodeHistorian` refer to the timestamps of the values instead of the modification times. Several modifications of a value are returned from the most recent to the oldest one, also when reading backward. Code that reads or deletes the modified history using a time range of modification times now receives or deletes other values.
- Breaking (2.59.0.0): `OpcClient.BrowseNode(OpcBrowseNode)` and `OpcClient.BrowseNodes` throw an `ArgumentNullException` for a command that is `null`. Before, a `NullReferenceException` was thrown. Code that catches the `NullReferenceException` must catch the `ArgumentNullException` instead.
- Breaking (2.59.0.0): `OpcClient.CallFunc` throws an `InvalidCastException` if the first output argument is `null` and the result type is a non-nullable value type. Before, a `NullReferenceException` was thrown. Code that catches the `NullReferenceException` must catch the `InvalidCastException` instead.
- Breaking (2.59.0.0): `OpcClient.CallMethods` throws an `ArgumentNullException` for a command that is `null`. Before, such a command was skipped, so that the results of the following commands were returned at the index of the previous command, and a call of commands that are all `null` failed with an `OpcException` stating `BadNothingToDo`. Code that passes a command that is `null` now fails instead of receiving shifted results.
- Breaking (2.59.0.0): The single-command overloads `OpcClient.CallMethod(OpcCallMethod)`, `ReadNodeHistory(..., OpcReadNodeHistory)`, `CreateNodeHistory`, `ReplaceNodeHistory`, `UpdateNodeHistory`, `DeleteNodeHistory`, `DeleteNodeHistoryAtTime`, and `DeleteNodeHistoryModified` throw an `ArgumentNullException` with the `ParamName` `command` for a command that is `null`. Before, the `ParamName` stated `commands.Item`, and `CallMethod(OpcCallMethod)` failed with an `OpcException` stating `BadNothingToDo`. Code that catches the `OpcException` of `CallMethod(OpcCallMethod)` for a command that is `null` must catch the `ArgumentNullException` instead.
- Breaking (2.59.0.0): The `OpcServer` constructors that take a sequence of nodes throw an `ArgumentNullException` for a node that is `null`. Before, `OpcServer.Start()` failed with an `OpcException`. The exception now occurs when the server is constructed and is an `ArgumentNullException` instead of an `OpcException`.
- Breaking (2.59.0.0): `OpcNode.ReadAttributeValueCore` and `OpcNode.WriteAttributeValueCore` throw an `ArgumentNullException` for a value that is `null`. Before, a `NullReferenceException` was thrown. A derived class that catches the `NullReferenceException` must catch the `ArgumentNullException` instead.
- Breaking (2.59.0.0): The service requests built from commands (for example `OpcCallMethodsRequest`, `OpcReadNodesRequest`, or `OpcWriteNodesRequest`) throw an `ArgumentNullException` for a command that is `null`. Before, such a command was skipped, so that the results of the following commands were assigned to the wrong command. Code that passes a command that is `null` now fails instead of receiving shifted results.
- Breaking (2.59.0.0): `OpcClient.CreateSubscription` throws an `OpcException` stating `BadServerNotConnected` when the client has not been connected or has been disconnected. Before, a `NullReferenceException` was thrown. Code that catches the `NullReferenceException` must catch the `OpcException` instead.
- Breaking (2.59.0.0): `OpcEventFilterFactory.Select` throws an `ArgumentNullException` for operands that are `null`. Before, a `NullReferenceException` was thrown while the client was connected. Code that catches the `NullReferenceException` must catch the `ArgumentNullException` instead.
- Breaking (2.59.0.0): `OpcEventFilterConstrainedFactory.Where` combines the specified constraint with the constraint of the factory using a logical AND, like a single `Where` with both constraints combined using the `&` operator. Before, the elements of the specified constraint were only appended, so that the root element of the filter was still the first constraint and element operands of the appended constraint referred to wrong elements. An event filter built using chained `Where` calls now restricts the events by all constraints, so that a MonitoredItem may receive fewer events than before.
- Breaking (2.59.0.0): `OpcClientApplication.Exit` disconnects the client also in the states `Connecting`, `Reconnecting`, and `Reconnected` (the state the client takes after a reconnect with the same session); while the client connects, `Exit` waits until connecting has completed. In a non-interactive environment, `Exit` also ends `Run` if the client has already been disconnected, for example because reconnecting failed. Before, `Exit` did nothing in these states, so that the client stayed connected or kept reconnecting and `Run` did not return in a non-interactive environment (for example a service did not stop). The events `Exiting` and `Exited` are now raised in the states `Connecting`, `Reconnecting`, and `Reconnected` as well.
- Breaking (2.59.0.0): The constructors of `OpcClientApplication`, `OpcServerApplication`, and `OpcServerServiceApplication` check their arguments before the application is registered for the current thread. Before, a constructor that threw an `ArgumentNullException` left the failed instance registered, so that `OpcApplication.Current` returned it and the next constructor on the same thread threw an `InvalidOperationException` until the instance was garbage collected. After a failed construction, `OpcApplication.Current` now returns `null` instead of the failed instance.
- Changed (2.59.0.0): An application that has been garbage collected without a call of `Exit` no longer prevents the creation of the next application on the same thread. Before, the next constructor threw an `ArgumentException`.
- Changed (2.59.0.0): Applications can be created and exited on several threads at the same time. Before, this could corrupt the registration, so that `OpcApplication.Current` returned the application of another thread or an exception was thrown.
- Breaking (2.59.0.0): `OpcServerApplication.Exit` stops the server also in the state `Suspended`. Before, `Exit` did nothing in this state, so that the server stayed suspended and `Run` did not return in a non-interactive environment. The events `Exiting` and `Exited` are now raised in this state as well.
- Changed (2.59.0.0): `OpcNodeManager.SyncRoot`, `GetNode(string)`, and `IsNodeReadyToPublish` throw an `InvalidOperationException` when the server using the node manager has not yet been started, like the other members of the node manager that require a started server. Before, a `NullReferenceException` was thrown.
- Changed (2.59.0.0): `OpcClient.BrowseNode` and `BrowseNodes` use `OpcBrowseNode.IncludeSubtypes` once it has been set, as the Browse service does. A command without the value set follows the subtypes of its reference types as before.
- Breaking (2.59.0.0): The HTTPS endpoints of `OpcServer` let the operating system choose the TLS versions instead of offering TLS 1.0, 1.1, and 1.2. Clients that only support TLS 1.0 or 1.1 can no longer connect over HTTPS where the operating system has disabled these versions.
- Breaking (2.59.0.0): Issue with `OpcFilterOperand.Between`, which passed the operands in the order lower bound, operand, upper bound, so that, for example, `a.Between(1, 5)` determined whether 1 is between `a` and 5 instead of whether `a` is between 1 and 5. The operands are now passed in the order defined by OPC UA. Code that compensated for the issue by calling `Between` on the lower bound (for example `lower.Between(a, upper)`) now determines whether the lower bound is between `a` and the upper bound and must be changed to `a.Between(lower, upper)`.
- Breaking (2.59.0.0): Issue with `OpcHistoryValue.Create(OpcValue)`, which created a history value sharing the data of the specified value, so that setting the value of one of them changed the data of the other, while its `Value` property still returned the previous value. The history value now uses a copy of the data. Code that changes an `OpcValue` after passing it to `Create`, or a history value created by `Create`, no longer changes the data of the other value.
- Breaking (2.59.0.0): Issue with `OpcSecurityPolicyCollection.CopyTo`, which copied each policy from the specified array index on to the same index of the array, so that the policies before that index were missing, and which failed with an `ArgumentOutOfRangeException` for an empty array. The method now copies all policies to the array starting at the specified index, like `List<T>.CopyTo`, and throws an `ArgumentException` if the array is too small. Code that passes an array index greater than zero receives all policies starting at that index instead of a part of them at their own index, and code that passes an array that is too small for all policies receives an `ArgumentException`.
- Breaking (2.59.0.0): Issue with the `CertificateRequested` event of `OpcServer` and `OpcClient`, where a certificate provided using `AlternativeCertificate` of the event data was not used: a server without an application certificate failed to start ("Server does not have an instance certificate assigned"), and otherwise the certificate of the application store remained in use. The provided certificate is now used, also on later starts and connects; it must contain its private key. Handlers that set `AlternativeCertificate` to another certificate now change the certificate the application uses.
- Breaking (2.59.0.0): Issue with `OpcStruct`, where creating the data type of a structure with an array field whose data type is unknown failed with a `NullReferenceException`. An `InvalidOperationException` that names the data type, the field, and the structure is now thrown. Code that catches the `NullReferenceException` in this case does not catch the `InvalidOperationException`.
- Breaking (2.59.0.0): Issue with `OpcEnum`, where fields defined without a value got the value 0 if another field was defined with a value other than 0, and where the specified `OpcEnumField` instances were changed. Like in C#, a field defined without a value now follows the value of the field before it (`A, B, C = 5, D` results in 0, 1, 5, 6), and the specified instances remain unchanged. Enumerations with fields defined without a value next to fields defined with a value, and enumerations whose fields are all defined with the value 0, get other values; the `Value` of an `OpcEnumField` specified without a value remains 0, and `GetFields` returns copies.
- Breaking (2.59.0.0): Issue with `OpcServer`, where a request of the services AddNodes, AddReferences, DeleteNodes, DeleteReferences, or Call that contained a command with a null identifier was rejected as a whole (`BadNothingToDo`, for AddNodes, DeleteNodes, and DeleteReferences `BadUnexpectedError`). The other commands are now executed, and the command with the null identifier has the status defined by OPC UA (`BadParentNodeIdInvalid`, `BadNodeIdInvalid`, `BadSourceNodeIdInvalid`, `BadTargetNodeIdInvalid`, `BadReferenceTypeIdInvalid`, or `BadMethodInvalid`). The issue existed since version 2.7.0.0, for Call since version 2.50.5.0. Such a request is no longer rejected, so that `RequestValidating` is raised with a good result, the request is processed, and it is not counted in `RejectedRequestsCount` of the server diagnostics. Server applications that relied on the rejection must handle commands with a null identifier themselves.
