Delen via


Modellen parseren en valideren met de DTDL-parserbibliotheek

In dit artikel wordt beschreven hoe u Azure Digital Twins-modellen parseert en valideert met behulp van de .NET-parserbibliotheek.

Modellen in Azure Digital Twins worden gedefinieerd met behulp van de op JSON-LD gebaseerde Digital Twins Definition Language (DTDL).

Nadat u een model hebt gemaakt, is het raadzaam om uw modellen offline te valideren voordat u ze uploadt naar uw Azure Digital Twins-exemplaar.

Om u te helpen uw modellen te valideren, wordt er een DTDL-parseringsbibliotheek aan de clientzijde van .NET aangeboden in NuGet: DTDLParser. U kunt de parserbibliotheek rechtstreeks in uw C#-code gebruiken. U kunt ook het voorbeeldgebruik van de parser bekijken in de DTDLParserResolveSample in GitHub.

Over de .NET-parserbibliotheek

De DTDLParser-bibliotheek biedt modeltoegang tot de DTDL-definities, die in wezen fungeren als het equivalent van C#-reflectie voor DTDL. Deze bibliotheek kan onafhankelijk van elke Azure Digital Twins SDK worden gebruikt, met name voor DTDL-validatie in een visual of teksteditor. Het is handig om ervoor te zorgen dat uw modeldefinitiebestanden geldig zijn voordat u ze probeert te uploaden naar de service.

Als u de parserbibliotheek wilt gebruiken, geeft u deze een set DTDL-documenten op. Normaal gesproken haalt u deze modeldocumenten op uit de service, maar u hebt ze mogelijk ook lokaal beschikbaar als uw client verantwoordelijk was voor het uploaden naar de service.

Dit is de algemene werkstroom voor het gebruik van de parser:

  1. Haal enkele of alle DTDL-documenten op uit de service.
  2. Geef de geretourneerde DTDL-documenten in het geheugen door aan de parser.
  3. De parser valideert de set documenten die eraan zijn doorgegeven en retourneert gedetailleerde foutinformatie. Deze mogelijkheid is handig in editorscenario's.
  4. Gebruik de parser-API's om door te gaan met het analyseren van de modellen die zijn opgenomen in de documentenset.

De mogelijkheden van de parser zijn onder andere:

  • Haal alle geïmplementeerde modelinterfaces op (de inhoud van de interfacesectie extends ).
  • Haal alle eigenschappen, telemetrie, opdrachten, onderdelen en relaties op die in het model zijn gedeclareerd. Met deze opdracht worden ook alle metagegevens in deze definities opgeslagen en wordt rekening gehouden met overname (extends secties).
  • Alle complexe modeldefinities ophalen.
  • Bepaal of een model kan worden toegewezen vanuit een ander model.

Notitie

IoT Plug en Play-apparaten gebruiken een kleine syntaxisvariant om hun functionaliteit te beschrijven. Deze syntaxisvariant is een semantisch compatibele subset van de DTDL die wordt gebruikt in Azure Digital Twins. Wanneer u de parserbibliotheek gebruikt, hoeft u niet te weten welke syntaxisvariant is gebruikt om de DTDL voor uw digitale dubbel te maken. De parser retourneert altijd hetzelfde model voor zowel IoT-Plug en Play als Azure Digital Twins-syntaxis.

Code met de parserbibliotheek

U kunt de parserbibliotheek rechtstreeks gebruiken voor zaken als het valideren van modellen in uw eigen toepassing of voor het genereren van dynamische, modelgestuurde gebruikersinterface, dashboards en rapporten.

Bekijk verschillende modellen die zijn gedefinieerd in een Azure Digital Twins-exemplaar om het onderstaande voorbeeld van parsercode te ondersteunen:

[
    {
      "@context": "dtmi:dtdl:context;3",
      "@id": "dtmi:com:contoso:coffeeMaker;1",
      "@type": "Interface",
      "contents": [
        {
          "@type": "Component",
          "name": "coffeeMaker",
          "schema": "dtmi:com:contoso:coffeeMakerInterface;1"
        }
      ]
    },
    {
      "@context": "dtmi:dtdl:context;3",
      "@id": "dtmi:com:contoso:coffeeMakerInterface;1",
      "@type": "Interface",
      "contents": [
        {
          "@type": "Property",
          "name": "waterTemp",
          "schema": "double"
        }
      ]
    },
    {
      "@context": "dtmi:dtdl:context;3",
      "@id": "dtmi:com:contoso:coffeeBar;1",
      "@type": "Interface",
      "contents": [
        {
          "@type": "Relationship",
          "name": "foo",
          "target": "dtmi:com:contoso:coffeeMaker;1"
        },
        {
          "@type": "Property",
          "name": "capacity",
          "schema": "integer"
        }
      ]
    }
  ]

In de volgende code ziet u een voorbeeld van het gebruik van de parserbibliotheek om deze definities in C# weer te geven:

using Azure;
using Azure.DigitalTwins.Core;
using DTDLParser;
using DTDLParser.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DigitalTwins_Samples
{
    public static class ListExtensions
    {
        public static async IAsyncEnumerable<T> AsAsyncEnumerable<T>(this IEnumerable<T> input)
        {
            foreach (var value in input)
            {
                yield return value;
            }
            await Task.Yield();
        }
    }

    public class ParseModelsSample
    {
        public async Task ParseDemoAsync(DigitalTwinsClient client)
        {
            try
            {
                AsyncPageable<DigitalTwinsModelData> mdata = client.GetModelsAsync(new GetModelsOptions { IncludeModelDefinition = true });
                var models = new List<string>();
                await foreach (DigitalTwinsModelData md in mdata)
                    models.Add(md.DtdlModel);
                var parser = new ModelParser();
                IReadOnlyDictionary<Dtmi, DTEntityInfo> dtdlOM = await parser.ParseAsync(models.AsAsyncEnumerable());

                var interfaces = new List<DTInterfaceInfo>();
                IEnumerable<DTInterfaceInfo> ifenum =
                    from entity in dtdlOM.Values
                    where entity.EntityKind == DTEntityKind.Interface
                    select entity as DTInterfaceInfo;
                interfaces.AddRange(ifenum);
                foreach (DTInterfaceInfo dtif in interfaces)
                {
                    PrintInterfaceContent(dtif, dtdlOM);
                }
            }
            catch (RequestFailedException ex)
            {
                Console.WriteLine($"Failed due to {ex}");
                throw;
            }
        }

        public void PrintInterfaceContent(DTInterfaceInfo dtif, IReadOnlyDictionary<Dtmi, DTEntityInfo> dtdlOM, int indent = 0)
        {
            var sb = new StringBuilder();
            for (int i = 0; i < indent; i++) sb.Append("  ");
            Console.WriteLine($"{sb}Interface: {dtif.Id} | {dtif.DisplayName}");
            IReadOnlyDictionary<string, DTContentInfo> contents = dtif.Contents;

            foreach (DTContentInfo item in contents.Values)
            {
                switch (item.EntityKind)
                {
                    case DTEntityKind.Property:
                        DTPropertyInfo pi = item as DTPropertyInfo;
                        Console.WriteLine($"{sb}--Property: {pi.Name} with schema {pi.Schema}");
                        break;
                    case DTEntityKind.Relationship:
                        DTRelationshipInfo ri = item as DTRelationshipInfo;
                        Console.WriteLine($"{sb}--Relationship: {ri.Name} with target {ri.Target}");
                        break;
                    case DTEntityKind.Telemetry:
                        DTTelemetryInfo ti = item as DTTelemetryInfo;
                        Console.WriteLine($"{sb}--Telemetry: {ti.Name} with schema {ti.Schema}");
                        break;
                    case DTEntityKind.Component:
                        DTComponentInfo ci = item as DTComponentInfo;
                        Console.WriteLine($"{sb}--Component: {ci.Id} | {ci.Name}");
                        DTInterfaceInfo component = ci.Schema;
                        PrintInterfaceContent(component, dtdlOM, indent + 1);
                        break;                
                }
            }
        }
    }
}

Volgende stappen

Zodra u klaar bent met het schrijven van uw modellen, kunt u zien hoe u ze uploadt (en andere beheerbewerkingen uitvoert) met de Azure Digital Twins Models-API's: