C# / .NET · recipe

Read a value from an OPC UA server in C#

ReadValue returns a DataValue carrying the value, the status code and both timestamps. Use StatusCode.IsGood before trusting the number, and resolve namespace indexes from URIs rather than hardcoding them.

StackOPCFoundation/UA-.NETStandard
Version1.5.378.156 stable, 2.0.0-preview.2

The code

// resolve the namespace index from its URI - never hardcode it
int nsIndex = session.NamespaceUris.GetIndex("http://opcfoundation.org/UA/MachineTool/");
Console.WriteLine($"MachineTool namespace index: {nsIndex}");

DataValue dv = session.ReadValue(new NodeId(2258));   // Server CurrentTime

Console.WriteLine($"value           : {dv.Value}");
Console.WriteLine($"status          : {dv.StatusCode}");
Console.WriteLine($"good?           : {StatusCode.IsGood(dv.StatusCode)}");
Console.WriteLine($"source timestamp: {dv.SourceTimestamp:O}");
Console.WriteLine($"server timestamp: {dv.ServerTimestamp:O}");

// batch reads: one round trip for many nodes
var toRead = new ReadValueIdCollection
{
    new ReadValueId { NodeId = new NodeId(2258), AttributeId = Attributes.Value },
    new ReadValueId { NodeId = new NodeId(2259), AttributeId = Attributes.Value },
};
session.Read(null, 0, TimestampsToReturn.Both, toRead, out var results, out _);
foreach (var r in results) Console.WriteLine($"  {r.Value} [{r.StatusCode}]");

What it prints

MachineTool namespace index: 4
value           : 08/09/2026 03:44:59
status          : Good
good?           : True
source timestamp: 2026-09-08T03:44:59.3210000Z
server timestamp: 2026-09-08T03:44:59.3210000Z
  08/09/2026 03:44:59 [Good]
  Running [Good]

Notes

  • StatusCode.IsGood is the check to make. An Uncertain status still has a value attached, and averaging it silently corrupts a KPI.
  • session.NamespaceUris.GetIndex(uri) is the habit that stops a client breaking after a PLC program download shifts the indexes.
  • Batch with a ReadValueIdCollection. One request for two hundred nodes is dramatically cheaper, up to the server's operation limit.
  • Attributes.Value is one of many. DataType, AccessLevel and EURange are all readable the same way, and you need them before writing or applying a percent deadband.

What breaks first

A read that worked yesterday now returns an unknown node BadNodeIdUnknown
Resolve namespace indexes at runtime from the namespace URI, and store URI plus identifier in configuration rather than the index.

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.

Free download
OPC UA Troubleshooting & Integration Checklist
The field-tested checklist engineers use to diagnose certificates, ports and namespace problems fast, plus a Python (asyncua) client template.
Get the free checklist →
Free, no course, no login