TaJson lets you use a ViewModel as a declarative template to create JSON from model objects or import JSON into them; use it when you need a mapping and transformation layer between an external JSON contract and your model.
How TaJson works
TaJson uses the columns and nestings in a ViewModel as the shape of the JSON document.
- A ViewModel column becomes a JSON property.
- A ViewModel multi-nesting becomes a JSON array.
- Column and nesting names provide the JSON names; expressions determine the model values that are read or written.
- You can create a dedicated, lightweight ViewModel containing only the fields that belong in an import or export contract.
For example, a template with columns named author_name and title can map an external JSON property named author_name to a differently named model attribute through the column expression. See MergeTaJson for a mapping example.
TaJson differs from JsonToObject. JsonToObject imports matching JSON directly into newly created model objects. TaJson always uses a ViewModel as its template, so you can choose fields, rename fields through ViewModel columns, and control the hierarchy used for both output and input.
Choose the operation
| Goal | Operation | Result |
|---|---|---|
| Create JSON from an existing object hierarchy | AsTaJson | Returns JSON shaped by the ViewModel. |
| Update fields represented in incoming JSON | MergeTaJson | Imports JSON using the ViewModel mapping. The operation returns a log string. |
| Make the object hierarchy match incoming JSON | ApplyTaJson | Imports JSON using the ViewModel mapping and removes objects missing from JSON when processing multi-associations. The operation returns a log string. |
Create JSON from objects
Use AsTaJson on the object you want to export and provide the ViewModel template. The ViewModel defines which attributes and associations are included.
For example, an object can be serialized with a template ViewModel using an expression in this form:
vCurrent_Article.AsTaJson(Articles1.ViewModels.ArticlesJsonTemplate, false)
Create the template ViewModel with the columns and multi-nestings required by the receiving JSON contract. Keep the template separate from a user-facing ViewModel when the API contract needs a different field set or names.
Return custom JSON from a REST endpoint
When a ViewModel is exposed as a REST endpoint, MDriven normally serializes the ViewModel using its default format. To return TaJson output as the complete response body:
- Add a ViewModel column named exactly
RawJson. - Set the column expression to an
AsTaJsoncall. - MDriven uses the returned string as the entire HTTP response body.
See AsTaJson for this REST response pattern.
Control JSON output with tagged values
Set these tagged values to true on a ViewModel multi-nesting when the standard array-of-objects output does not match the external contract.
| Tagged value | Use it when | Result |
|---|---|---|
TaJsonTreatListAsDynamicProperties
|
Property names are known only at runtime. | TaJson reads Name and Value properties from each object in the nesting and emits them as properties on the containing JSON object.
|
TaJsonTreatListAsValues
|
The contract requires an array of scalar values rather than an array of objects. | TaJson emits the first column of each nesting row as an array value. |
Dynamic properties
Use TaJsonTreatListAsDynamicProperties for a nesting whose items have string columns named Name and Value. This lets your model represent arbitrary JSON properties that were not known when you designed the ViewModel.
For example, a nesting containing these rows:
| Name | Value |
|---|---|
priority
|
high
|
region
|
north
|
can produce:
{
"priority": "high",
"region": "north"
}
The same setting also supports import. When an incoming JSON property does not match a ViewModel column at that level, TaJson checks for a multi-nesting tagged with TaJsonTreatListAsDynamicProperties=true. If it finds one, it imports unmatched properties as Name/Value pairs into that nesting.
This is useful when an external service sends extension properties that can vary between messages.
Arrays of values
Without TaJsonTreatListAsValues, a nesting with columns Code and Description produces an array of JSON objects:
{
"someList": [
{ "Code": "A", "Description": "First" },
{ "Code": "B", "Description": "Second" }
]
}
With TaJsonTreatListAsValues=true, TaJson uses the first column only. If Code is the first column, the output becomes:
{
"someList": ["A", "B"]
}
Place the intended value column first in the nesting. Other columns in that nesting are not represented by this array-of-values output.
Insert preformatted JSON
Set the RawJSon tagged value to true when an AsTaJson column contains JSON text that must be inserted as JSON rather than quoted as a string.
For example, if a column evaluates to:
{"enabled":true}
normal string serialization would produce a quoted value. With RawJSon=true, the text is inserted as a JSON object. The value must be valid JSON.
Import JSON into objects
Use MergeTaJson or ApplyTaJson with a target root object and a ViewModel that describes the incoming hierarchy. Give the root object to the ViewModel; TaJson then updates the hierarchy below that root by matching JSON attributes and associations to ViewModel columns and nestings.
- Create a dedicated import ViewModel or confirm that the existing ViewModel contains the required columns and nestings.
- Ensure the root object is available to that ViewModel.
- Call
MergeTaJsonfor a merge-style update, orApplyTaJsonwhen missing items in multi-associations must be removed. - Store or inspect the returned log string when diagnosing an import.
Object creation, lookup, and cleanup hooks
TaJson recognizes these ViewModel action and variable conventions during import:
| Convention | Purpose |
|---|---|
<ViewModelColumn>_AddNew action
|
Creates an object needed for the ViewModel association named <ViewModelColumn>. The action must return the created object and must add that object to the association. If the action is absent, TaJson uses type information to create an object.
|
Delete action in a nesting
|
Used when TaJson needs to delete an object that is absent from the incoming data and merge mode is not in effect. |
vImportKey:string variable
|
Updated before object creation. Use it in an _AddNew action to find an existing object instead of creating a duplicate.
|
CleanUpAction action on the root ViewModel class
|
Called after the import finishes. Prepare it as a column for action in the ViewModel Editor. |
For example, if the JSON contains an Invoices array, an Invoices_AddNew action can use vImportKey to locate the invoice identified by the incoming key, return it, and ensure it belongs to the Invoices association.
Scale imports for large data sets
The default import behavior loads objects in many-associations so TaJson can match incoming keys against existing objects. That can consume excessive time and memory when an association contains millions of objects.
To limit the objects loaded for a many-association:
- Add an action named
<ViewModelColumn>_Lookup, where<ViewModelColumn>is the association column in the ViewModel. - Add a variable that holds the collection of objects that may be updated, for example
vclient_invoices. - Use that variable as the expression for the many-association.
- In the lookup action, use
vImportKey. TaJson supplies a comma-separated list of keys from the JSON. - Load only the objects for those keys and add them to the collection variable. The current implementation example uses OCL PS/ExecutePS for this lookup.
- When the lookup action finishes, TaJson continues with its normal import processing.
With ApplyTaJson, take special care: ApplyTaJson removes existing objects that are not found in the JSON. Any objects that must be retained or evaluated for deletion need to be present in the collection you supply.
Split very large, deep documents
A deeply nested document can require TaJson to resolve and set a very large number of single links and leaf objects in one operation. For example, 1,000 Details, each with 1,000 Deep1 objects, each with 1,000 Deep2 objects, represents up to 1,000,000,000 objects to process.
Split this work into smaller passes by adding a ViewModel column named exactly RawJSon (case-sensitive) in the nesting where processing should stop.
When MergeTaJson or ApplyTaJson finds that column, it stores the JSON text for the current level and below in the column as a string. You can then process each stored fragment later with another ViewModel and another import call.
For example, first import the top-level Details items and store each item's deep content in RawJSon. Then process a manageable group of Detail objects at a time, importing each stored JSON fragment with a ViewModel that starts at Deep1. This approach is suitable for background processing such as MDrivenServer server-side jobs, where each fragment can be handled as a separate unit of work.
Troubleshooting and gotchas
Check ReadOnly on import columns
When you add attributes to multi-nestings, the framework sets ReadOnly to true. That default is often appropriate for UI grid cells, but in TaJson it means the field is read-only during import as well.
Before testing an import, review the ReadOnly setting on every column that incoming JSON must update. Set it according to the import behavior you need.
Use valid JSON for raw insertion
The RawJSon=true tagged value bypasses normal string quoting. Invalid JSON in the value produces invalid output, so validate the generated fragment before using it in an external contract.
Do not use ApplyTaJson for an unintended partial list update
ApplyTaJson removes missing objects in multi-associations. If the source payload contains only a subset of the association, use MergeTaJson or ensure the ApplyTaJson input represents the intended complete set.
Create a model template from a sample payload
If you have an existing JSON or XML example, you can generate a starting model section for an import target. Right-click the class that should be the root and choose Add attributes, assoc. and classes from clipboard json or xml. Review and adapt the generated classes and then create the ViewModel template used by TaJson. For the full procedure, see Documentation:Using JSON or XML as class template.
