🚀 Welcome to MDriven Learn –  MDriven is now on Discord!  Don’t miss the latest Release Notes.
Getting safe–limited–meta information from a Turnkey app
This page was created by Alexandra on 2018-10-28. Last edited by Wikiadmin on 2026-07-29.

You can build a custom or native client for an MDriven Turnkey application by discovering its permitted menu, opening a selected ViewModel, consuming its server stream, and rendering the view from limited UI metadata.

MDriven Turnkey exposes metadata that tells a client what it may present: menu groups, global actions, view names, suggested control types, placement, labels, and available actions. It does not expose sensitive implementation details. The server remains responsible for authentication, access control, the data slice, and execution of actions. See Training:Information security for the security model.

What a client needs

A client that renders a Turnkey application needs four kinds of information:

Information Endpoint or operation What the client uses it for
Main-menu metadata /MDriven/GlobalActionsMeta Discover menu groups and global actions without hard-coding available views.
Opened view identity /api/open Open a selected main-menu action and obtain the server identity of the ViewModel instance.
View state and commands /api/ServerStream Build and keep current the data hierarchy and available action state for the opened ViewModel.
UI definition /MDriven/ViewMeta?view=... Render the ViewModel using suggested controls, labels, and layout positions.

Replace https://your-site in the examples with the base URL of your Turnkey application.

Discover the main menu

Request the global-action metadata:

https://your-site/MDriven/GlobalActionsMeta?targetgroup=

The response is XML containing menugroups and actions. A menu-group entry provides its name and sort key:

<menugroup Name="File" Sortkey="001"/>

An action entry describes an item that your client can show:

<action MenuGroup="Views"
        MenuGroupSortKey="004"
        DividerGroupTag=""
        DividerGroupTagSortKey=""
        Name="ShowAllCars"
        Presentation="Show All Cars"
        BringUpViewModel="AllCars"
        ExecuteFrameworkRuntimeAction="None"/>

In this example, display Show All Cars in the Views menu. Selecting it opens the AllCars ViewModel.

Build the menu in the designed order

Use the metadata rather than a hard-coded menu so that additions and changes in the model can be discovered by the client.

  1. Group actions by MenuGroup.
  2. Sort menu groups alphanumerically by MenuGroupSortKey.
  3. Within a group, sort actions alphanumerically by DividerGroupTagSortKey.
  4. Insert a divider between items whose DividerGroupTag values differ.
  5. Use Presentation as the text shown to the user.

An action is either a framework runtime action or navigation:

Action type Metadata indicator Client behavior
Framework runtime action ExecuteFrameworkRuntimeAction contains a value such as Save, Undo, Redo, or Refresh. Invoke the corresponding Turnkey operation for the selected action.
Navigation action BringUpViewModel is set, for example AllCars. Open the menu action, then retrieve the resulting ViewModel state and UI definition.

Filter the menu for an audience

If the application serves different audiences, include the target-group name in the request:

https://your-site/MDriven/GlobalActionsMeta?targetgroup=TargetGroupName

A target group is a specialized use of the access-group concept. The client should treat this response as the menu it is allowed to offer for that target group. Access control is still enforced on the server; a client must not treat menu metadata as authorization to bypass server rules.

Open a menu action

When the user selects a navigation action, open it by identifying both the main menu and the action name:

https://your-site/api/open?VMClassId=MAINMENU;ShowAllCars&ResetServerApp=false

In this example, ShowAllCars is the action name from GlobalActionsMeta. The response has two parts separated by ¤:

943a7840-796e-4370-bd37-d407ffa48aa9¤$null$;AllCars
Returned part Meaning Example
Before ¤ The server identity of the opened ViewModel instance. Use it as VMId when reading the server stream. 943a7840-796e-4370-bd37-d407ffa48aa9
After ¤ The ViewModel class identifier. $null$;AllCars

The server checks authentication and any access-group requirements when the action is opened.

Read and maintain the ViewModel state

Use the returned server identity to read the ViewModel's message stream. Start at cursor 0 for a newly opened UI:

https://your-site/api/ServerStream?VMId=943a7840-796e-4370-bd37-d407ffa48aa9&cursor=0

The response is JSON containing server update commands. For example, action commands describe actions available in the current ViewModel state:

{
  "VMClassName": "AllCars",
  "Action": "CreateCar",
  "Enable": true,
  "Presentation": "Create Car",
  "GroupHeader": "Car",
  "CType": "ServerUpdateCommand_Action"
}

Collection-update commands build the data hierarchy defined in the ViewModel Editor in MDriven Designer. For example, an UpdateCollection command with Attribute set to AllCar adds an item to that collection.

Continue from the cursor

The final message in a response is an application-information command:

{
  "SuggestCallbackInSecs": 0,
  "MNo": 7,
  "CType": "ServerUpdateCommand_AppInfo"
}

Use this object to continue the stream:

  1. Read the final ServerUpdateCommand_AppInfo object.
  2. Store its MNo value as the next cursor. In the example, the next cursor is 7.
  3. Wait the number of seconds in SuggestCallbackInSecs.
  4. Request ServerStream again using the stored cursor.

When SuggestCallbackInSecs is 0, call back immediately because the server may have more messages to deliver. Apply each received command in message order so that the client's state remains aligned with the server's ViewModel state.

Get the UI definition

The server stream provides state; it does not by itself tell a custom client which widgets and layout to use. Request per-view UI metadata using the view name discovered from the menu metadata:

https://your-site/MDriven/ViewMeta?view=AllCars

The response is XML. It contains suggested control types, control names, labels, layout positions, and spans. For example:

<root RowHeight="20" ColWidth="50">
  <control type="grid" owner="AllCars" name="AllCar"
           root="vCurrent_AllCars" label="All Car"
           labelspan="1" colspan="3" rowspan="5"
           x="0" y="0" nesting="AllCar">
    <control type="textbox" name="AsString" label="As String" colspan="1" />
  </control>
</root>

In this example, render AllCar as a grid at position x="0", y="0". Render its nested AsString value as a text box. Treat control types and positions as UI guidance supplied by the model.

Documentation:ViewMeta documents the per-view metadata endpoint and its purpose. Tagged values set on ViewModel columns in MDriven Designer are also included in the metadata, so you can place client-specific rendering instructions in the model instead of hard-coding them in the client.

Blazor client metadata

For a client-side Blazor implementation, use the Blazor-specific per-view metadata endpoint:

http://<YourSite>/Turnkey/ViewMetaBlazorClient?view=NameOfViewModel

See Documentation:ViewMeta for this endpoint.

End-to-end example

The following sequence opens and renders the Show All Cars action without hard-coding the AllCars view into the client.

  1. Request /MDriven/GlobalActionsMeta?targetgroup=.
  2. Find the action whose Name is ShowAllCars; display its Presentation, Show All Cars, in its configured menu group.
  3. When selected, call /api/open?VMClassId=MAINMENU;ShowAllCars&ResetServerApp=false.
  4. Extract the ViewModel server identity before ¤ from the response.
  5. Request /api/ServerStream?VMId=returned-id&cursor=0 and apply its update commands.
  6. Request /MDriven/ViewMeta?view=AllCars and render the returned controls against the streamed state.
  7. Continue reading the server stream from the final MNo, following SuggestCallbackInSecs.

Security boundaries

The metadata is intentionally limited to what a client needs to present the application. It describes presentation and available actions; it is not a copy of the application's internal implementation. The ViewModel defines the subset of data available for a use case, and Turnkey performs that reduction and access control on the server. This applies whether the client is the standard Turnkey UI or a custom client.

Do not rely on hiding a menu item as a security control. A client can choose what to display, but the server must remain the authority for authentication, authorization, data filtering, and action execution.

Related implementation guidance

For a broader description of creating your own renderer and integrating a Turnkey application with an existing site, see Documentation:Rendering the MDriven Turnkey application yourself. If you need to add page-level browser metadata such as a Content Security Policy or a robots directive, see Documentation:Turnkey extra meta tags.

See also