Fields
Word fields are small instructions inside a document, such as { DATE }, { DOCPROPERTY Company }, { = SUM(ABOVE) } or { IF … }, each with a cached result. DocWright.Dom.Fields finds them, evaluates them with values you supply, and rewrites them.
Find the fields in a document
using DocWright.Dom.Fields;
foreach (FieldRegion field in document.FindFields())
{
Console.WriteLine($"{field.Instruction.Name,-12} support: {FieldKindInfo.GetSupport(field.Instruction.Kind),-10} cached: {field.CachedResult}");
}
FindFields() on a document covers the body, headers, footers, footnotes and endnotes. It returns top-level fields; a field nested inside another is available through NestedFields. FindFields(FieldKind.MergeField) limits the search to one kind.
Update them
using System.Globalization;
using DocWright.Dom.Fields;
var handlers = new FieldHandlerRegistry();
handlers.Add(new TicketFieldHandler());
var options = new FieldUpdateOptions
{
Culture = CultureInfo.GetCultureInfo("en-NZ"),
Clock = new DateTimeOffset(2026, 10, 1, 9, 0, 0, TimeSpan.Zero), // never read from the machine
Handlers = handlers,
};
options.DocumentProperties["Company"] = "Riverbend Health Trust";
options.DocumentVariables["Region"] = "Waikato";
FieldUpdateResult result = document.UpdateFields(options);
Console.WriteLine($"{result.FieldsUpdated} updated, {result.FieldsSkipped} skipped, "
+ $"{result.FieldsInError} in error, of {result.FieldsFound}");
Console.WriteLine(document.GetText().TrimEnd());
Output (both steps)
DOCPROPERTY support: Evaluated cached: [company]
DATE support: Evaluated cached: [date]
DOCVARIABLE support: Evaluated cached: [region]
= support: Evaluated cached: [total]
TICKET support: Unrecognized cached: [ticket]
5 updated, 0 skipped, 0 in error, of 5
Prepared for: Riverbend Health Trust
Date: 1 October 2026
Region: Waikato
Total with tax: 1,437.50
Action: #4711: Replace fire extinguishers
1437.5
!Zero Divide
Two rules govern updates:
- Nothing comes from the machine. The date, user name, file name, document properties and variables all come from
FieldUpdateOptions. With noClock, aDATEfield keeps its cached value rather than showing today, so output is reproducible. - A field that can't be evaluated keeps its cached result and reports a diagnostic. It is never blanked.
Which fields are evaluated
| Evaluated | Computed during layout | Kept as-is |
|---|---|---|
IF, COMPARE, = formulas, MERGEFIELD and the merge family, SET, REF, DOCPROPERTY, DOCVARIABLE, STYLEREF, QUOTE, SYMBOL, date and document-property fields |
PAGE, NUMPAGES, SECTIONPAGES, PAGEREF, SEQ |
TOC, INDEX, HYPERLINK, INCLUDETEXT and interactive fields, which are parsed and preserved |
FieldKindInfo.GetSupport(kind) tells you which applies to a field. Nothing is fetched: INCLUDETEXT, INCLUDEPICTURE, LINK and DDE name external files or URLs, and DocWright never follows them (diagnostic DXP5003). A field that makes the server fetch a URL is a security hole.
Add your own field
Implement IFieldHandler and register it. Later registrations win, so you can also override a built-in field:
using DocWright.Dom.Fields;
/// <summary>Evaluates a custom { TICKET id } field from your own data.</summary>
internal sealed class TicketFieldHandler : IFieldHandler
{
private static readonly Dictionary<string, string> Titles = new()
{
["4711"] = "Replace fire extinguishers",
};
public IReadOnlyList<string> FieldNames => ["TICKET"];
public bool TryEvaluate(FieldEvaluationContext context, out string? result)
{
FieldArgument? id = context.Instruction.Arguments.FirstOrDefault();
if (id is null)
{
result = FieldErrors.Syntax("TICKET"); // shows Word's own error text
return true;
}
result = Titles.TryGetValue(id.Text, out string? title) ? $"#{id.Text}: {title}" : $"#{id.Text}";
return true; // false keeps the cached result
}
}
Return false from TryEvaluate to decline and keep the cached result. FieldErrors produces Word's own error texts, such as !Syntax Error and !Zero Divide.
Rewrite a field by hand
A FieldRegion offers four operations:
| Method | Result |
|---|---|
SetResult(text) |
New result text; the field stays. |
ReplaceWithText(text) |
The field is removed and plain text stays. |
Unwrap() |
The field is removed and its current result stays. |
Delete() |
The whole field, including its result, is removed. |
Formulas
The = field's expression engine is available directly:
using System.Globalization;
using DocWright.Dom.Fields;
var context = new FieldFormulaContext { Culture = CultureInfo.InvariantCulture };
Console.WriteLine(FieldFormula.Evaluate("1250 * 1.15", context));
Console.WriteLine(FieldFormula.Evaluate("10 / 0", context));
Errors come back as Word's result strings, such as !Syntax Error, rather than as exceptions, because that is what the document would show. Table references such as SUM(ABOVE) follow Word's actual cell-selection rules.