Troubleshooting and Best Practices
This page helps you move from a working prototype to a stable reporting workflow.
It covers the options that change engine behavior, common failure patterns, and practical guidance for performance and template safety.
Most reporting issues come from a small set of causes: the wrong data shape, a mismatched tag pair, a missing member, or template logic that is too complex to debug comfortably.
Example Debugging Scenario
Template:
Traveler: <<[booking.PrimaryTraveler]>>
Seat: <<[booking.SeatNumber]>>Data object:
public sealed class Booking
{
public string PrimaryTraveler { get; set; } = string.Empty;
}Expected behavior:
Without AllowMissingMembers:
- report generation throws because SeatNumber is not available
With AllowMissingMembers:
- Traveler: Avery Chen
- Seat:Useful ReportBuilderOptions
ReportBuilderOptions gives you control over common runtime behaviors:
ReportBuilderOptions options = new ReportBuilderOptions
{
AllowMissingMembers = true,
InlineErrorMessages = true,
RemoveEmptyParagraphs = true,
RespectJpegExifOrientation = true,
UpdateFieldsSyntaxAware = true
};
options.KnownTypes.Add(typeof(BookingMath));
ReportBuilder.BuildReport(
"Template.docx",
"Output.docx",
booking,
"booking",
options);| Option | When to use it |
|---|---|
AllowMissingMembers |
Templates may reference optional fields that are not always present. |
InlineErrorMessages |
You want syntax errors written into the output document during template debugging. |
RemoveEmptyParagraphs |
Processed tags leave unwanted blank lines behind. |
RespectJpegExifOrientation |
JPEG images from cameras or phones need orientation correction. |
UpdateFieldsSyntaxAware |
The output document contains fields that should be updated after report generation. |
KnownTypes |
A template must access explicitly allowed static types or perform type-related operations. |
Common Problems
The following table describes the symptoms and possible causes of common problems:
| Symptom | Likely cause | What to check |
|---|---|---|
| A tag prints nothing | The expression resolved to null or the data source name does not match. |
Verify the bound source name and property path. |
| A repeated block appears only once | The source is not a collection or the foreach range is misplaced. |
Check the collection expression and the opening and closing tags. |
| Blank lines remain after generation | Tags were removed but the surrounding paragraphs stayed. | Use RemoveEmptyParagraphs or selective ! tags. |
| A template throws on missing members | The model shape differs between runs. | Enable AllowMissingMembers if null is acceptable. |
| Nested regions fail unexpectedly | A closing tag matches the wrong opening tag. | Add headers such as #segments and #bags. |
Diagnostics During Template Development
When you are still refining a template, InlineErrorMessages can shorten the feedback loop because errors appear inside the generated document instead of stopping generation with an exception.
That is useful for template authors, but it should not replace normal exception handling in application code.
Performance Tips
- Prefer prepared view models over deep graphs that require heavy traversal in every tag
- Keep repeated expressions short inside large
foreachregions - Precompute expensive aggregates in application code
- Reuse template files and data-shaping code paths instead of building many near-duplicate templates
- Register only the helper types you actually need through
KnownTypes
Security Considerations
Templates are not just text fragments. They contain executable expressions, so treat template input as code-like content.
- Do not accept unreviewed templates from untrusted users in the same way you would accept plain text content
- Keep
KnownTypesnarrow so templates can access only approved helper types - Avoid exposing sensitive application objects directly if the template does not need them
- Prefer flattened report models over rich domain objects with broad method surfaces
- Review helper methods used from templates for side effects and data exposure
Recommended Workflow
- Start with a tiny template that proves the data binding path
- Add one loop or one conditional region at a time
- Turn on inline error messages while shaping the template
- Move repeated calculations into the data model before the template becomes hard to read