C# / .NET · recipe
Write a value to an OPC UA server in C#
Read the node's DataType, build a Variant of that exact type, and inspect the per-operation status code in the response. A write returns a collection of status codes, not an exception, so silence is not success.
| Stack | OPCFoundation/UA-.NETStandard |
|---|---|
| Version | 1.5.378.156 stable, 2.0.0-preview.2 |
The code
// umati is read-only. Run the reference server locally instead:
// dotnet run --project Applications/ConsoleReferenceServer
var nodeId = new NodeId("MyVariable", (ushort)nsIndex);
// read the declared DataType first - do not guess
var dtValue = session.ReadValue(nodeId, Attributes.DataType);
Console.WriteLine($"declared DataType: {dtValue.Value}");
var toWrite = new WriteValueCollection
{
new WriteValue
{
NodeId = nodeId,
AttributeId = Attributes.Value,
Value = new DataValue(new Variant((double)42.5)),
},
};
session.Write(null, toWrite, out StatusCodeCollection results, out _);
foreach (var sc in results)
Console.WriteLine(StatusCode.IsGood(sc)
? "write accepted"
: $"write rejected: {sc}");
// always read back in a test - some servers accept and discard
Console.WriteLine($"read back: {session.ReadValue(nodeId).Value}");
What it prints
declared DataType: i=11
write accepted
read back: 42.5
Notes
- Write returns a StatusCodeCollection with one entry per operation. Check every entry, a batch can partially succeed.
- The Variant type must match the node's DataType. Casting to double explicitly, as above, avoids C# inferring int.
- Read AccessLevel before writing rather than diagnosing the refusal afterwards.
- Read back in tests. A Good write status does not prove the server kept the value.
What breaks first
The write is rejected with a type mismatch despite a sensible-looking value
Read the DataType attribute and construct the Variant with the matching CLR type. Int16, Int32 and Int64 are distinct, and a scalar is not a one-element array.
BadTypeMismatchRead the DataType attribute and construct the Variant with the matching CLR type. Int16, Int32 and Int64 are distinct, and a scalar is not a one-element array.
Other recipes in this stack
Concepts on this page
Last verified 7 September 2026 against OPC UA 1.05.07. OPC UA Connect is an educational resource and is not affiliated with the OPC Foundation.