Reference
Upgrade to a new version
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.
Reference
Upgrade to a new version
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. The version number above each section leads to the complete release notes of that version, including new features and fixes.
195 changes
1.5
- Moved the
IdentityandImpersonationContextclasses from theOpc.UaFx.Serverto theOpc.UaFxnamespace. - The
OpcValueLabelis now no longer defined as a struct; instead it is now a class.
1.6
- Removed implicit interpretation of a numeric node identifier encoded as a string.
2.2
- Simplified
OpcValue.ToStringimplementation to just providenullfor null references or theValue.ToString().
2.3
- The SDK no longer supports Windows-based authentication using the WinLogon API for OPC UA server authentication.
- 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.
- Starting with this version, a reference to the NuGet package
Portable.BouncyCastle(at least version 1.8.1.3) or theBouncyCastle.Cryptoassembly (at least version 1.8.1.146) is required. - Using a server address with the scheme
httpsrequires references to the NuGet packagesMicrosoft.AspNetCore.Server.Kestrel(1.1.3) andMicrosoft.AspNetCore.Server.Kestrel.Https(1.1.3). OpcVariableNodedefined as an abstract base class.- Removed multiple local Foundation node references to reduce memory usage.
2.5
- Corrected misspelled members.
- Streamlined API through additional descriptive parts in class and delegate names. In general, changed the naming of
DatatoDataSet,DataItemtoDataSetItemandEventRaisetoEvent. OpcNodeId.ToStringnow formats by default using theOpcNodeIdFormat.Foundationformat.- Order of subscription events from MonitoredItem → Client → Subscription to MonitoredItem → Subscription → Client, to ensure a more logical event order using bubbling.
- Renamed
OpcMonitoredItem.ReceivedDataChangetoOpcMonitoredItem.DataChangeReceived. - Renamed
OpcMonitoredItem.ReceivedEventRaisetoOpcMonitoredItem.EventRaiseReceived. OpcSubscribeEventRaise->OpcSubscribeEventOpcDataChangeEventArgs->OpcDataChangeReceivedEventArgsOpcDataChangeEventHandler->OpcDataChangeReceivedEventHandlerOpcEventRaiseEventArgs->OpcEventReceivedEventArgsOpcEventRaiseEventHandler->OpcEventReceivedEventHandlerOpcNotificationEventArgs->OpcNotificationReceivedEventArgsOpcNotificationEventHandler->OpcNotificationReceivedEventHandlerOpcDataChangeCallback->OpcDataChangeReceivedCallbackOpcEventRaiseCallback->OpcEventReceivedCallbackIOpcNotificationData->IOpcNotificationDataSetOpcNotificationData->OpcNotificationDataSetOpcNotificationDataCollection->OpcNotificationDataSetCollectionOpcNotificationDataReadOnlyCollection->OpcNotificationDataSetReadOnlyCollectionOpcNotificationDataItem->OpcNotificationDataSetItemOpcNotificationDataItemCollection->OpcNotificationDataSetItemCollectionOpcNotificationDataItemReadOnlyCollection->OpcNotificationDataSetItemReadOnlyCollectionOpcDataChange->OpcDataChangeSetOpcDataChangeItem->OpcDataChangeSetItemOpcEventRaise->OpcEventDataSetOpcEventRaiseItem->OpcEventDataSetItemOpcMonitoredItem.EventRaiseReceived->EventReceived.LastEventRaise->LastEvent.OnEventRaiseReceived->OnEventReceived
OpcSubscription.EventRaiseReceived->EventReceived.ReceivedEventRaiseCallback->ReceivedEventCallback.OnEventRaiseReceived->OnEventReceived
OpcClient.EventRaiseReceived->EventReceived.OnEventRaiseReceived->OnEventReceived.SubscribeEventRaise->SubscribeEvent
- Downgraded sample projects to C# language version 6.0 to ensure that the samples will compile in older versions of Visual Studio.
- Changed
IsNodeAccessible(..., IOpcNode node)toIsNodeAccessible(..., IOpcNodeInfo node). OpcNode.BeforeApplyChangesandOpcNode.AfterApplyChangesare now only raised if changes are pending (seeOpcNode.HasPendingChanges).- Changed default
MinimumCertificateKeySizefrom 2048 to 1024 to support lower key sizes used by older certificates. - When changing the application certificate of a client or server instance using the
Certificateproperty, the store path type of the application certificate store changes toSystem. To use the store path typeDirectory, 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 theCertificateproperty. - The application certificate is no longer stored in
.\CertificateStores\Trusted, now it is stored (by default) in.\CertificateStores\Appto improve startup performance when searching for the application certificate. - Changed use of
LinkTimetoLastWriteTimeof the assembly when determiningOpcServerInfofrom an assembly.
2.6
- Removed
OpcClientTransportclass (replaced by newOpcTransportclass). - Removed
OpcServerTransportclass (replaced by newOpcTransportclass). - The default server information provided by
OpcServerBasenow prefers a predefinedApplicationName. OpcSecurityPolicyCollectionno longer provides a constructor with anOpcServerBaseinstance. The correspondingOwnerproperty has been removed as well.
2.7
- Removed
OpcServerIdentity.Passwordproperty, 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. - Removed
OpcTransformUserPasswordDelegatedelegate. - Replaced
OpcUserNameAcl.PasswordTransformwith virtualMatchesandTransformPasswordmethods inOpcServerIdentity. - Reviewed implementation of
OpcMonitoredItemandOpcSubscription: Changed someint-based properties to uselongas the property type to support underlyinguintproperties used by the foundation stack in aCLSCompliantway. - Changed some
int-based properties inOpcMonitoredItem,OpcServiceCounter,OpcSessionDiagnosticsandOpcServerDiagnosticstolongas their property type to assure CLS compliance while accessing the unsigned API of the foundation stack. OpcMonitoredItem.AutoFlushCachehas been replaced with the newOpcMonitoredItem.QueueModeproperty to better express the mechanism used when the notification data item queue of a MonitoredItem overflows.
2.8
OpcDataTypeAttributeis now applicable on classes and structures.- Unified
OpcNodeManager.NamespaceIndexesandOpcNodeManager.NamespaceUrisinto newOpcNodeManager.Namespaces. - Renamed
IOpcReadOnlyDataStoretoIOpcReadOnlyNodeDataStore. IOpcNamespaceResolvermethodsUri Resolve(int namespaceIndex)andint Resolve(Uri namespaceUri)are now obsolete.OpcAutomatism.UseDynamicproperty default value is nowfalse. Change its value or theOpcClient.UseDynamictotrueto enable use ofOpcDataObject.- Adjusted
iconUrlandlicenseUrlinformation in NuGet packages upon their deprecation. - Explicitly encoded information known as the
EncodingMaskof a structured data type is now handled using the newOpc.UaFx.Bittype instead ofSystem.Boolean. - Reviewed
OpcClient.Statechanges to detect a lost connection to the server. OpcClient.Statenow changes automatically only toDisconnected(during a running request) ifReconnectTimeoutis greater than zero (reconnection is manually handled).
2.9
- License codes used prior to version 2.9 no longer work. Customers will receive new license keys working in all frameworks supported.
OpcAttributeWriteAccessis now based onUInt32.- The default value of
OpcAutomatism.AlwaysParseStringIdentifiersis nowfalse. As a result, the value is no longer parsed automatically when the constructorOpcNodeId(string)is called. For more details, seeOpcAutomatism.AlwaysParseStringIdentifiers. - [Client SDK] Moved the
OpcBrowseNodeclass from namespaceOpc.UaFx.Clientto namespaceOpc.UaFx. - [Client SDK] Moved the
OpcBrowseNodeDegreeenumeration from namespaceOpc.UaFx.Clientto namespaceOpc.UaFx. - [Client SDK]
IOpcBrowseServiceandOpcBrowseRequestnow use the classesOpcViewDescriptionandOpcBrowseNodeinstead of the Foundation classesViewDescriptionandBrowseDescription. - Moved
OpcReadOnlyNamespaceCollectionfrom namespaceOpc.UaFx.Serverto namespaceOpc.UaFx. - Changed the default value of the DataType attribute of
OpcDataTypeDictionaryNodefrom Byte to ByteString to match the definition of the specification. - Renamed
Descriptionproperty ofIOpcDataTypeInfo,OpcDataTypeInfoandOpcDataFieldInfotoDocumentationto match the definition of the OPC UA specification. OpcEncoding.All(...)now constructs theOpcEncoding.Idusing the default BrowseNames for the different encoding types.OpcNamespace.ToString()now always returns a string which just represents theOpcNamespace.ValueandOpcNamespace.Index(if not zero).OpcNodeSet.GetDataTypeSystem()now provides anOpcDataTypeSysteminstance which uses the typical BrowseName for the type of encoding used by the type system.- Removed method
IOpcTypeProvider.GetType(OpcEncoding), because encoding information only applies to data types. OpcTypeCategory.EventTypeandOpcTypeCategory.ReferenceTypehave been removed.
2.10
OpcNode.OnAfterApplyChangesandOpcNode.OnBeforeApplyChangesuseOpcNodeChangesEventArgsinstead ofEventArgs.OpcNode.AfterApplyChangesandOpcNode.BeforeApplyChangespassOpcNodeChangesEventArgsinstead ofEventArgsto event handlers.
2.11
OpcSession.Closecloses the session and invalidates the session-related identifier.OpcClientmethods validate the connection state using anOpcException(withBadServerNotConnected) instead of using anInvalidOperationException.- Default
QueueSizeofOpcMonitoredItemcreated usingOpcClient.SubscribeEvent(s) fromint.MaxValuetouint.MaxValueto enforce that the server uses the maximum queue size supported for event notifications (which was initially intended with the wrongint.MaxValue). - Renamed
OpcMonitoredItemStatus.DataItemQueueSizetoQueueSizeto match the naming used inOpcMonitoredItem(which defines the requested size while the status gives the revised size). - Returned type of
OpcMonitoredItemStatus.IdfromInt32toInt64to cover the underlying non-CLS compliantUInt32of the Foundation's stack. - Adopted recently reviewed API of
OpcMonitoredItemtoOpcMonitoredItemStatusand reworkedOpcMonitoredItemStatus.AutoFlushCachetoQueueMode(as inOpcMonitoredItem). - The constructor of
OpcCertificateJudgementEventArgsno 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 policyNone(mode and algorithm). - Used data type in
OpcNode.Read/WriteDescriptionCallbackproperty fromStringtoOpcText. OpcDataChangeDataSetItem.ClientIDfromInt32toInt64to match the used type inOpcMonitoredItem.ClientID.
2.12
- The
OpcNamespace.Defaultnamespace now provides the default value and URI used to identify the Foundation's default namespace. - Removed obsolete methods from
IOpcNamespaceResolverand all its implementations inOpcClient,OpcServer,OpcContextandOpcNodeManager. OpcClient.Stateno longer transitions (using the reconnect mechanism activated by default) when calling, for example,ReadNodewhile theOpcClientis about to re-establish a broken connection.- In case of a broken connection, the
OpcClienttries (by default) to re-establish the connection and re-use the previously used session. If this works, theOpcClientwill raise theReconnectedevent as before. If the client has been forced to create a new session (for example, upon timeout of the previous session), theOpcClientwill now raise theConnectedevent instead of theReconnectedevent to provide a way to distinguish these conditions in user code. - Comparison in
OpcNodeIdandOpcNamespaceto provide results typically used by .NET APIs when comparing to a null reference (this differs from the implementation used by the Foundation). - Bidirectional references between DataTypeDescription, DataTypeEncoding and DataType nodes are now unidirectional (using default export options).
2.14
- Removed duplicate references to
DataTypeNodeswhen using theOpcAddressSpaceclass to describe the nodes of the server.
2.18
- Format of ByteString from Base64 encoding to hex (
X2) encoded / formatted strings, which matches the Foundation's binary encoded representation of aByteString. OpcNodeIdnow matches the OPC UA specification and compares node identifiers and namespaces case-sensitively.OpcClassicDiscoveryClientnow usesOpcExceptionto represent all stack related exceptions.
2.19
- 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.
OpcFileReadMethodNode.FileReadCallbackandOpcFileReadMethodNode.FileReadExCallbacknow return a ByteString instead of an array of bytes.OpcFileWriteMethodNode.FileWriteCallbackandOpcFileWriteMethodNode.FileWriteExCallbacknow accept a ByteString for the data parameter instead of an array of bytes.- Parameter of
OpcFilterOperand.OfTypefromvalue : objecttotypeId : OpcNodeIdto assure that anOfTypeoperand is evaluated as expected (that is, using anOpcNodeId). - Regression issue using
OpcFileNodeaccess using Read and Write operations after enforcing the Foundation's stack to use ByteString for ByteString andByte[]forByte[]instead of using ByteString forByte[]. - Possibly breaking:
IOpcReadOnlyNodeDataStorenow requires the implementation ofIOpcNamespaceResolveras well. - Removed unnecessary new lines in the string representation of
OpcExceptioninstances.
2.20
OpcInstanceNodenow determines itsDefaultTypeDefinitionIdusing the node type used to create the instance node.OpcMemberOriginsnow defines an additional enum memberMethodfor method origins.
2.24
- The
OpcNodeAccessToken.IndexRangeis now obsolete, use newOpcNodeAccessToken.Rangeproperty instead. - The property type of
OpcReadVariableValueContext(<T>).Rangehas been changed fromUa.NumericRangetoOpcRange. - The property type of
OpcWriteVariableValueContext(<T>).Rangehas been changed fromUa.NumericRangetoOpcRange. - The property type of
OpcReadPropertyValueContext(<T>).Rangehas been changed fromUa.NumericRangetoOpcRange. - The property type of
OpcWritePropertyValueContext(<T>).Rangehas been changed fromUa.NumericRangetoOpcRange.
2.25
- 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
- Disabling
OpcAutomatism.UseDynamicTypeRegistrationresulted in a deferred dynamic type registration at the time a custom data type is manually registered.
2.29
OpcNode.AddNotifieris no longer supported on other types thanOpcObjectNodesand their subclasses.
2.30
- The behavior of starting and stopping an OPC Classic UA Wrapper Server is now more deterministic, as each
OpcClientuses a dedicated wrapper server, which is now also stopped when theOpcClientdisconnects. - The method
OpcCertificateIdentity.Matches()is now virtual to enable custom identity comparison. - The
OpcEvent.EventIdproperty now provides the underlying ByteString instead of a byte-array (before the ByteString was introduced).
2.31
- Updated
Newtonsoft.Jsondependency to version 13.0.3, to fix a vulnerability. - 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.
- When no port is specified on an
opc.com:URL, the port for the classic wrapper server is no longer derived from theclassIDandprogID, but instead a free dynamic port number is determined. This facilitates using multipleOpcClientswith the sameopc.com:URL at the same time.
2.33
OpcContext.Empty.SessionIdno longer provides a null reference (Nothing in Visual Basic). Instead it providesOpcNodeId.Null.- Changed access modifiers of
OpcNodeManager.AddNode(...)andOpcNodeManager.RemoveNode(...)methods fromprotectedtopublicfor improved usability. - Evaluation of
OpcVariableNodeInfo.IsArraynow uses the ValueRank value instead of the ArrayDimensions to decide whether the Value attribute provides an array.
2.41
- User authentication in the
OpcServeris now done only once duringActivateSession, instead of doing it for each request separately. - Updated
Microsoft.AspNetCore.Server.Kestrel.Coredependency to version 2.1.25, to fix a vulnerability.
2.42
OpcArgument.ArrayDimensionsandOpcArgumentInfo.ArrayDimensionsnow support null references (Nothing in Visual Basic) when enabled viaOpcAutomatism.UseNullInsteadOfEmptyArrays. This means whenever a server provides a value ofnullfor theArrayDimensionsthis property will now return a null reference (Nothing in Visual Basic) as well.- Updated
Portable.BouncyCastledependency to version 1.9.0, to fix a vulnerability.
2.50
- When
OpcClientSecurity.UseOnlySecureEndpointsis set totrue, theOpcClientnow only selects endpoints with aSignAndEncryptmode, and no longer selects ones with aSignmode, because the latter does not provide confidentiality. To use the previous behavior of selecting endpoints with aSignorSignAndEncryptpolicy, setclient.Security.EndpointPolicyto one with that mode, and setOpcClient.Security.AutoUpgradeEndpointPolicytotrue. Alternatively, to select the "best" endpoint offered by the server, setOpcClient.Security.UseHighLevelEndpointtotrue(but note that this does not provide security). - When creating an event filter with
OpcEventFilterFactory.Select(), the type identifier of theBaseEventTypeis 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, specifyOpcEventFieldSelectOptions.UseExplicitEventTypeIdsinOpcEventFilterFactory.Select(). - Wrong
DefaultReferenceTypeIdOrganizes ofOpcFolderNodeand adopted use of HasComponent instead. This change addresses CTT compliance. ServerDiagnosticsno longer provides children and any explicit read/write operations on the child nodes using their NodeId result inBadOutOfService. This behavior applies for disabledServerDiagnosticsand addresses CTT compliance.- 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.
- Moved
Modelproperty and all otherOpcNodeModelrelated API fromOpcInstanceNodetoOpcNodeto ensure correct node initialization. - Improved CTT compliance regarding
OpcNodedefault initialization and conditionally removed defaults for the Description attribute and for theSymbolicNameproperty. To enable the previous behavior, enable the corresponding properties inOpcAutomatism.
2.51
- When using .NET Framework, version 4.7.2 or higher is now required.
- 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 parametertimeFlowsBackwardistrue.
2.54
- Enhanced certificate validation especially for application instance certificates to support compliant validation of basic constraint extensions. This is required for CTT compliance.
- By default, the listener socket now uses an exclusive address when binding to the port. This behavior can be controlled with the new
OpcServerBinding.UseExclusiveAddressproperty.
2.55
- The initial value of the
OpcConditionNode.IsRetainedproperty and its subtypes (OpcAcknowledgeableConditionNodeandOpcAlarmConditionNode) 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 newOpcConditionRetainPolicyenumeration 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 valueOpcConditionRetainPolicy.Manualfor theOpcConditionNode.IsRetainedPolicyproperty to gain full control of theIsRetainedproperty.
2.58
- 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, andOpcData.Encodeto encode a structure as anOpcRawObject. Code that expected an array of bytes or anXmlElementfor a value of an unknown structure now receives anOpcRawObject; itsRawDataholds what was returned before. - Introduced the attributes
RolePermissions,UserRolePermissions,AccessRestrictions, andAccessLevelExinOpcAttributeandOpcAttributes, the memberDataTypeDefinitionofOpcAttributes, and the typesOpcRolePermissionandOpcPermissions. Reading the DataTypeDefinition attribute now yields anOpcDataTypeInfoinstead of aStructureDefinitionorEnumDefinitionof the stack, and reading RolePermissions or UserRolePermissions yields an array ofOpcRolePermissioninstead ofRolePermissionType. - Removed the
CertificateFactoryof the stack from the public API of the package, since the SDK does not provide CA signing or CRL generation. Code that usesCertificateFactoryno longer compiles. OpcSecurityAlgorithm.Autoand the default endpoints of the discovery server and of the OPC Classic wrapper server useBasic256Sha256instead of the deprecatedBasic256(Sign) andBasic128Rsa15(SignAndEncrypt). A client usingAutono longer connects to a server that offers only the deprecated policies.- The certificate the SDK creates for an
OpcServeralso names the fully qualified name of the machine, so that clients that connect by that name accept it. An existing certificate remains unchanged. OpcServerreports audit events only whileOpcServerSecurity.IsAuditingEnabledistrue, and only to clients connected overSignAndEncryptor HTTPS with a user in the SecurityAdmin role, as defined by OPC UA. A server reports session audit events only afterIsAuditingEnabledhas been set totrue.State,StateChanged, andBreakDetectedofOpcClientfollow a lost connection detected by a failing service call (for exampleBadConnectionClosedorBadSessionIdInvalid) 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.- The data type system of OPC UA provides all predefined data types (for example
Integer,UInteger,Enumeration, orImage), each data type states its supertype asBaseType, and fields of data types derived from a built-in type (for exampleDuration,UtcTime, orLocaleId) are decoded. Built-in types and the structures of OPC UA now state their supertype asBaseTypeinstead of none, and a field of a type derived fromByteStringyields aByteStringinstead of an array of bytes. OpcServerno longer traces a connection reset by a client as an error, neither during a read nor when it closes the socket.OpcClient.ReconnectTimeoutandDefaultReconnectTimeoutare obsolete; useReconnectIntervalandDefaultReconnectIntervalinstead. Code that uses them receives a compiler warning, and a compiler error withTreatWarningsAsErrors.- The single-node history services
OpcClient.ReadNodeHistoryProcessed,ReadNodeHistoryAtTime, andReadNodeHistoryModifiedthrow anOpcExceptionwith the status code of the server (for exampleBadAggregateNotSupported) for a node the server rejected, and return an empty result for a node the server accepted without values. Before, aKeyNotFoundExceptionwas thrown in both cases. Code that catches theKeyNotFoundExceptionmust catch theOpcExceptioninstead. OpcDiscoveryClient(DiscoverEndpoints,DiscoverServers, and its constructors) throws anOpcExceptionstating the reason (for exampleBadSecureChannelClosed) when the server cannot be reached, closes the channel during the handshake, or the discovery URL uses an unsupported scheme. The history navigators ofOpcClient.ReadNodeHistoryandReadEventHistorythrow anOpcExceptionstatingBadCommunicationErrorwhen a page was not finished within the maximum number of requests. Before, theServiceResultExceptionof the stack was thrown. Code that catches theServiceResultExceptionmust catch theOpcExceptioninstead.OpcViewDescription.Defaultis now astatic readonlyfield, so that the default view cannot be replaced. Code that assignsOpcViewDescription.Defaultno longer compiles. Code compiled against an older version that readsOpcViewDescription.Defaultmust be recompiled, because the property has become a field.- Issue with
OpcServer, where a start changed theServerConfigurationof the application, so that a restart offered anonymous access although only theOpcUserNameAclwas enabled. The server now works with a copy of the configuration. Code that readsConfiguration.ServerConfigurationafter the start sees the values it set itself instead of the policies in use. - Issue with reading processed history (for example
OpcClient.ReadNodeHistoryProcessed), which requested both timestamps, so that a server could reject the request withBadTimestampsToReturnInvalid. The issue existed since version 1.5.11.0. The processed values no longer carry a server timestamp. - 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
NameandXmlNameof such a data type now state the namespace of its node instead of the namespace of OPC UA.
2.59
- Replaced the outdated dependency
Portable.BouncyCastle(version 1.9.0) withBouncyCastle.Cryptography(version 2.7.0), whose assembly is namedBouncyCastle.Cryptography.dllinstead ofBouncyCastle.Crypto.dll.CertificateFactoryRandomGeneratoradditionally providesAddSeedMaterial(ReadOnlySpan<byte>)andNextBytes(Span<byte>), which theIRandomGeneratorofBouncyCastle.Cryptographydeclares for .NET 6 and later. Applications that deploy the assemblies themselves must deployBouncyCastle.Cryptography.dllinstead ofBouncyCastle.Crypto.dll. Applications that referencePortable.BouncyCastlethemselves and use its types must change toBouncyCastle.Cryptography, since both packages provide the same types. - Removed the dependency on
System.Management. - The operators
<,<=,>,>=, and==ofOpcFilterOperandthrow anArgumentNullExceptionfor a left operand that isnull, and the constructors ofOpcContentFilterElementthrow anArgumentNullExceptionfor operands that arenull. Before, aNullReferenceExceptionwas thrown. Code that catches theNullReferenceExceptionmust catch theArgumentNullExceptioninstead. - 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. EndpointDescriptionExtensions.SetEndpointPolicythrows anArgumentNullExceptionfor an endpoint policy that isnull, and the indexer ofOpcSecurityPolicyCollectionthrows anArgumentNullExceptionwhennullis set. Before,SetEndpointPolicythrew aNullReferenceExceptionand the indexer stored an entry without a policy. Code that catches theNullReferenceExceptionmust catch theArgumentNullExceptioninstead, and code that setsnullusing the indexer now fails.- The
CertificateRequestedevent ofOpcServerandOpcClientalso occurs when the application certificate exists but is not valid, with the reasonInvalid,UseNotAllowed,Revoked,TimeInvalid,IssuerUseNotAllowed,IssuerRevoked, orIssuerTimeInvalid(for exampleTimeInvalidfor an expired certificate). The certificate is never replaced automatically (AutoCreateCertificateof the event data isfalse); 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. - Removed
OpcEventContext, which the SDK never created or returned. Code that referencesOpcEventContextno longer compiles. ExtensionObjectExtensions.To<T>throws anArgumentNullExceptioninstead of aNullReferenceExceptionfor an extension object that isnull, and theChildrenofOpcAddObjectTypeNodeandOpcAddVariableTypeNodethrow anArgumentNullExceptioninstead of aNullReferenceExceptionwhen a command that isnullis added or set. Code that catches theNullReferenceExceptionmust catch theArgumentNullExceptioninstead.- A custom
IOpcNodeHistoryProvidershould 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 inBadNoData. OpcNodeHistory<T>uses -1 (unlimited) as its default capacity instead of 0, with which each call toAddfailed. A capacity of 0 or less than -1 is now rejected with anArgumentOutOfRangeException, also by the constructors ofOpcNodeHistorian. Code that passes a capacity of 0 (for examplenew OpcNodeHistory<T>(0, values)) now fails with anArgumentOutOfRangeException.OpcNodeHistorian.ModifiedHistoryis anOpcModifiedNodeHistoryinstead of anOpcNodeHistory<OpcModifiedHistoryValue>. Code that uses the property as anOpcNodeHistory<OpcModifiedHistoryValue>must be changed:GetValues(DateTime)replaces the indexer by timestamp, whileRemoveAt(DateTime),Replace, and theReplacedevent are no longer available. Code compiled against a previous version must be recompiled.- Reading (for example with
OpcClient.ReadNodeHistoryModified) and deleting (for example withOpcClient.DeleteNodeHistoryModified) the modified history of anOpcNodeHistorianrefer 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. OpcClient.BrowseNode(OpcBrowseNode)andOpcClient.BrowseNodesthrow anArgumentNullExceptionfor a command that isnull. Before, aNullReferenceExceptionwas thrown. Code that catches theNullReferenceExceptionmust catch theArgumentNullExceptioninstead.OpcClient.CallFuncthrows anInvalidCastExceptionif the first output argument isnulland the result type is a non-nullable value type. Before, aNullReferenceExceptionwas thrown. Code that catches theNullReferenceExceptionmust catch theInvalidCastExceptioninstead.OpcClient.CallMethodsthrows anArgumentNullExceptionfor a command that isnull. 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 allnullfailed with anOpcExceptionstatingBadNothingToDo. Code that passes a command that isnullnow fails instead of receiving shifted results.- The single-command overloads
OpcClient.CallMethod(OpcCallMethod),ReadNodeHistory(..., OpcReadNodeHistory),CreateNodeHistory,ReplaceNodeHistory,UpdateNodeHistory,DeleteNodeHistory,DeleteNodeHistoryAtTime, andDeleteNodeHistoryModifiedthrow anArgumentNullExceptionwith theParamNamecommandfor a command that isnull. Before, theParamNamestatedcommands.Item, andCallMethod(OpcCallMethod)failed with anOpcExceptionstatingBadNothingToDo. Code that catches theOpcExceptionofCallMethod(OpcCallMethod)for a command that isnullmust catch theArgumentNullExceptioninstead. - The
OpcServerconstructors that take a sequence of nodes throw anArgumentNullExceptionfor a node that isnull. Before,OpcServer.Start()failed with anOpcException. The exception now occurs when the server is constructed and is anArgumentNullExceptioninstead of anOpcException. OpcNode.ReadAttributeValueCoreandOpcNode.WriteAttributeValueCorethrow anArgumentNullExceptionfor a value that isnull. Before, aNullReferenceExceptionwas thrown. A derived class that catches theNullReferenceExceptionmust catch theArgumentNullExceptioninstead.- The service requests built from commands (for example
OpcCallMethodsRequest,OpcReadNodesRequest, orOpcWriteNodesRequest) throw anArgumentNullExceptionfor a command that isnull. 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 isnullnow fails instead of receiving shifted results. OpcClient.CreateSubscriptionthrows anOpcExceptionstatingBadServerNotConnectedwhen the client has not been connected or has been disconnected. Before, aNullReferenceExceptionwas thrown. Code that catches theNullReferenceExceptionmust catch theOpcExceptioninstead.OpcEventFilterFactory.Selectthrows anArgumentNullExceptionfor operands that arenull. Before, aNullReferenceExceptionwas thrown while the client was connected. Code that catches theNullReferenceExceptionmust catch theArgumentNullExceptioninstead.OpcEventFilterConstrainedFactory.Wherecombines the specified constraint with the constraint of the factory using a logical AND, like a singleWherewith 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 chainedWherecalls now restricts the events by all constraints, so that a MonitoredItem may receive fewer events than before.OpcClientApplication.Exitdisconnects the client also in the statesConnecting,Reconnecting, andReconnected(the state the client takes after a reconnect with the same session); while the client connects,Exitwaits until connecting has completed. In a non-interactive environment,Exitalso endsRunif the client has already been disconnected, for example because reconnecting failed. Before,Exitdid nothing in these states, so that the client stayed connected or kept reconnecting andRundid not return in a non-interactive environment (for example a service did not stop). The eventsExitingandExitedare now raised in the statesConnecting,Reconnecting, andReconnectedas well.- The constructors of
OpcClientApplication,OpcServerApplication, andOpcServerServiceApplicationcheck their arguments before the application is registered for the current thread. Before, a constructor that threw anArgumentNullExceptionleft the failed instance registered, so thatOpcApplication.Currentreturned it and the next constructor on the same thread threw anInvalidOperationExceptionuntil the instance was garbage collected. After a failed construction,OpcApplication.Currentnow returnsnullinstead of the failed instance. - An application that has been garbage collected without a call of
Exitno longer prevents the creation of the next application on the same thread. Before, the next constructor threw anArgumentException. - Applications can be created and exited on several threads at the same time. Before, this could corrupt the registration, so that
OpcApplication.Currentreturned the application of another thread or an exception was thrown. OpcServerApplication.Exitstops the server also in the stateSuspended. Before,Exitdid nothing in this state, so that the server stayed suspended andRundid not return in a non-interactive environment. The eventsExitingandExitedare now raised in this state as well.OpcNodeManager.SyncRoot,GetNode(string), andIsNodeReadyToPublishthrow anInvalidOperationExceptionwhen 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, aNullReferenceExceptionwas thrown.OpcClient.BrowseNodeandBrowseNodesuseOpcBrowseNode.IncludeSubtypesonce it has been set, as the Browse service does. A command without the value set follows the subtypes of its reference types as before.- The HTTPS endpoints of
OpcServerlet 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. - 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 betweenaand 5 instead of whetherais between 1 and 5. The operands are now passed in the order defined by OPC UA. Code that compensated for the issue by callingBetweenon the lower bound (for examplelower.Between(a, upper)) now determines whether the lower bound is betweenaand the upper bound and must be changed toa.Between(lower, upper). - 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 itsValueproperty still returned the previous value. The history value now uses a copy of the data. Code that changes anOpcValueafter passing it toCreate, or a history value created byCreate, no longer changes the data of the other value. - 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 anArgumentOutOfRangeExceptionfor an empty array. The method now copies all policies to the array starting at the specified index, likeList<T>.CopyTo, and throws anArgumentExceptionif 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 anArgumentException. - Issue with the
CertificateRequestedevent ofOpcServerandOpcClient, where a certificate provided usingAlternativeCertificateof 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 setAlternativeCertificateto another certificate now change the certificate the application uses. - Issue with
OpcStruct, where creating the data type of a structure with an array field whose data type is unknown failed with aNullReferenceException. AnInvalidOperationExceptionthat names the data type, the field, and the structure is now thrown. Code that catches theNullReferenceExceptionin this case does not catch theInvalidOperationException. - 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 specifiedOpcEnumFieldinstances were changed. Like in C#, a field defined without a value now follows the value of the field before it (A, B, C = 5, Dresults 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; theValueof anOpcEnumFieldspecified without a value remains 0, andGetFieldsreturns copies. - 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 DeleteReferencesBadUnexpectedError). 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, orBadMethodInvalid). 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 thatRequestValidatingis raised with a good result, the request is processed, and it is not counted inRejectedRequestsCountof the server diagnostics. Server applications that relied on the rejection must handle commands with a null identifier themselves.

