diff --git a/sdk/digitaltwins/Azure.DigitalTwins.Core/api/Azure.DigitalTwins.Core.netstandard2.0.cs b/sdk/digitaltwins/Azure.DigitalTwins.Core/api/Azure.DigitalTwins.Core.netstandard2.0.cs index cfade0ca518c..2e45f3395b5e 100644 --- a/sdk/digitaltwins/Azure.DigitalTwins.Core/api/Azure.DigitalTwins.Core.netstandard2.0.cs +++ b/sdk/digitaltwins/Azure.DigitalTwins.Core/api/Azure.DigitalTwins.Core.netstandard2.0.cs @@ -122,15 +122,11 @@ public static partial class QueryChargeHelper } namespace Azure.DigitalTwins.Core.Serialization { - public partial class BasicDigitalTwin + public partial class BasicDigitalTwin : Azure.DigitalTwins.Core.Serialization.ModelProperties { public BasicDigitalTwin() { } - [System.Text.Json.Serialization.JsonExtensionDataAttribute] - public System.Collections.Generic.IDictionary CustomProperties { get { throw null; } set { } } [System.Text.Json.Serialization.JsonPropertyNameAttribute("$dtId")] public string Id { get { throw null; } set { } } - [System.Text.Json.Serialization.JsonPropertyNameAttribute("$metadata")] - public Azure.DigitalTwins.Core.Serialization.DigitalTwinMetadata Metadata { get { throw null; } set { } } } public partial class BasicRelationship { @@ -152,7 +148,15 @@ public DigitalTwinMetadata() { } [System.Text.Json.Serialization.JsonPropertyNameAttribute("$model")] public string ModelId { get { throw null; } set { } } [System.Text.Json.Serialization.JsonExtensionDataAttribute] - public System.Collections.Generic.IDictionary ModelProperties { get { throw null; } set { } } + public System.Collections.Generic.IDictionary WriteableProperties { get { throw null; } set { } } + } + public partial class ModelProperties + { + public ModelProperties() { } + [System.Text.Json.Serialization.JsonExtensionDataAttribute] + public System.Collections.Generic.IDictionary CustomProperties { get { throw null; } set { } } + [System.Text.Json.Serialization.JsonPropertyNameAttribute("$metadata")] + public Azure.DigitalTwins.Core.Serialization.DigitalTwinMetadata Metadata { get { throw null; } set { } } } public partial class UpdateOperationsUtility { diff --git a/sdk/digitaltwins/Azure.DigitalTwins.Core/samples/DigitalTwinsClientSample/ComponentSamples.cs b/sdk/digitaltwins/Azure.DigitalTwins.Core/samples/DigitalTwinsClientSample/ComponentSamples.cs index 63a47a116a28..38d757db321e 100644 --- a/sdk/digitaltwins/Azure.DigitalTwins.Core/samples/DigitalTwinsClientSample/ComponentSamples.cs +++ b/sdk/digitaltwins/Azure.DigitalTwins.Core/samples/DigitalTwinsClientSample/ComponentSamples.cs @@ -2,6 +2,8 @@ // Licensed under the MIT License. using System; +using System.Collections.Generic; +using System.Text.Json; using System.Threading.Tasks; using Azure.DigitalTwins.Core.Serialization; using static Azure.DigitalTwins.Core.Samples.SampleLogger; @@ -30,54 +32,69 @@ public async Task RunSamplesAsync() string componentModelId = await GetUniqueModelIdAsync(SamplesConstants.TemporaryComponentModelPrefix, DigitalTwinsClient).ConfigureAwait(false); string modelId = await GetUniqueModelIdAsync(SamplesConstants.TemporaryModelPrefix, DigitalTwinsClient).ConfigureAwait(false); - string twinId = await GetUniqueTwinIdAsync(SamplesConstants.TemporaryTwinPrefix, DigitalTwinsClient).ConfigureAwait(false); + string dtId = await GetUniqueTwinIdAsync(SamplesConstants.TemporaryTwinPrefix, DigitalTwinsClient).ConfigureAwait(false); string newComponentModelPayload = SamplesConstants.TemporaryComponentModelPayload .Replace(SamplesConstants.ComponentId, componentModelId); - string newModelPayload = SamplesConstants.TemporaryModelPayload + string newModelPayload = SamplesConstants.TemporaryModelWithComponentPayload .Replace(SamplesConstants.ModelId, modelId) .Replace(SamplesConstants.ComponentId, componentModelId); // Then we create models - await DigitalTwinsClient.CreateModelsAsync(new[] { newComponentModelPayload, newModelPayload }).ConfigureAwait(false); - Console.WriteLine($"Successfully created models with Ids: {componentModelId}, {modelId}"); + Response> createModelsResponse = await DigitalTwinsClient + .CreateModelsAsync(new[] { newComponentModelPayload, newModelPayload }) + .ConfigureAwait(false); + Console.WriteLine($"Successfully created models Ids {componentModelId} and {modelId} with response {createModelsResponse.GetRawResponse().Status}."); - // Create digital twin with Component payload - string twinPayload = SamplesConstants.TemporaryTwinPayload - .Replace(SamplesConstants.ModelId, modelId) - .Replace(SamplesConstants.ComponentId, componentModelId); + #region Snippet:DigitalTwinsSampleCreateBasicTwin - await DigitalTwinsClient.CreateDigitalTwinAsync(twinId, twinPayload).ConfigureAwait(false); - Console.WriteLine($"Created digital twin {twinId}."); + // Create digital twin with Component payload using the BasicDigitalTwin serialization helper - #region Snippet:DigitalTwinsSampleUpdateComponent + var basicDigitalTwin = new BasicDigitalTwin(); + basicDigitalTwin.Metadata.ModelId = modelId; + basicDigitalTwin.CustomProperties.Add("Prop1", "Value1"); + basicDigitalTwin.CustomProperties.Add("Prop2", "Value2"); + + var componentMetadata = new ModelProperties(); + componentMetadata.Metadata.ModelId = componentModelId; + componentMetadata.CustomProperties.Add("ComponentProp1", "ComponentValue1"); + componentMetadata.CustomProperties.Add("ComponentProp2", "ComponentValue2"); - // Update Component with replacing property value - string propertyPath = "/ComponentProp1"; - string propValue = "New Value"; + basicDigitalTwin.CustomProperties.Add("Component1", componentMetadata); + string dtPayload = JsonSerializer.Serialize(basicDigitalTwin, new JsonSerializerOptions { IgnoreNullValues = true }); + + Response createDtResponse = await DigitalTwinsClient.CreateDigitalTwinAsync(dtId, dtPayload).ConfigureAwait(false); + Console.WriteLine($"Created digital twin {dtId} with response {createDtResponse.GetRawResponse().Status}."); + + #endregion Snippet:DigitalTwinsSampleCreateBasicTwin + + #region Snippet:DigitalTwinsSampleUpdateComponent + + // Update Component1 by replacing the property ComponentProp1 value var componentUpdateUtility = new UpdateOperationsUtility(); - componentUpdateUtility.AppendReplaceOp(propertyPath, propValue); + componentUpdateUtility.AppendReplaceOp("/ComponentProp1", "Some new value"); + string updatePayload = componentUpdateUtility.Serialize(); - Response response = await DigitalTwinsClient.UpdateComponentAsync(twinId, SamplesConstants.ComponentPath, componentUpdateUtility.Serialize()); + Response response = await DigitalTwinsClient.UpdateComponentAsync(dtId, "Component1", updatePayload); - #endregion Snippet:DigitalTwinsSampleUpdateComponent + Console.WriteLine($"Updated component for digital twin {dtId}. Update response status: {response.GetRawResponse().Status}"); - Console.WriteLine($"Updated component for digital twin {twinId}. Update response status: {response.GetRawResponse().Status}"); + #endregion Snippet:DigitalTwinsSampleUpdateComponent // Get Component #region Snippet:DigitalTwinsSampleGetComponent - response = await DigitalTwinsClient.GetComponentAsync(twinId, SamplesConstants.ComponentPath).ConfigureAwait(false); - - #endregion Snippet:DigitalTwinsSampleGetComponent + response = await DigitalTwinsClient.GetComponentAsync(dtId, SamplesConstants.ComponentPath).ConfigureAwait(false); Console.WriteLine($"Get component for digital twin: \n{response.Value}. Get response status: {response.GetRawResponse().Status}"); + #endregion Snippet:DigitalTwinsSampleGetComponent + // Now delete a Twin - await DigitalTwinsClient.DeleteDigitalTwinAsync(twinId).ConfigureAwait(false); + await DigitalTwinsClient.DeleteDigitalTwinAsync(dtId).ConfigureAwait(false); // Delete models try diff --git a/sdk/digitaltwins/Azure.DigitalTwins.Core/samples/DigitalTwinsClientSample/DigitalTwinsLifecycleSamples.cs b/sdk/digitaltwins/Azure.DigitalTwins.Core/samples/DigitalTwinsClientSample/DigitalTwinsLifecycleSamples.cs index 3814ed0b35bb..6f42947f0149 100644 --- a/sdk/digitaltwins/Azure.DigitalTwins.Core/samples/DigitalTwinsClientSample/DigitalTwinsLifecycleSamples.cs +++ b/sdk/digitaltwins/Azure.DigitalTwins.Core/samples/DigitalTwinsClientSample/DigitalTwinsLifecycleSamples.cs @@ -263,12 +263,8 @@ public async Task CreateAllTwinsAsync() { try { - #region Snippet:DigitalTwinsSampleCreateTwin - Response response = await DigitalTwinsClient.CreateDigitalTwinAsync(twin.Key, twin.Value).ConfigureAwait(false); - #endregion Snippet:DigitalTwinsSampleCreateTwin - Console.WriteLine($"Created digital twin {twin.Key}. Create response status: {response.GetRawResponse().Status}"); Console.WriteLine($"Body: {response?.Value}"); } diff --git a/sdk/digitaltwins/Azure.DigitalTwins.Core/samples/DigitalTwinsClientSample/ModelLifecycleSamples.cs b/sdk/digitaltwins/Azure.DigitalTwins.Core/samples/DigitalTwinsClientSample/ModelLifecycleSamples.cs index 6e02428cc3c2..20edf7e6d6c4 100644 --- a/sdk/digitaltwins/Azure.DigitalTwins.Core/samples/DigitalTwinsClientSample/ModelLifecycleSamples.cs +++ b/sdk/digitaltwins/Azure.DigitalTwins.Core/samples/DigitalTwinsClientSample/ModelLifecycleSamples.cs @@ -39,7 +39,7 @@ public async Task RunSamplesAsync() string newComponentModelPayload = SamplesConstants.TemporaryComponentModelPayload .Replace(SamplesConstants.ComponentId, newComponentModelId); - string newModelPayload = SamplesConstants.TemporaryModelPayload + string newModelPayload = SamplesConstants.TemporaryModelWithComponentPayload .Replace(SamplesConstants.ModelId, sampleModelId) .Replace(SamplesConstants.ComponentId, newComponentModelId); diff --git a/sdk/digitaltwins/Azure.DigitalTwins.Core/samples/DigitalTwinsClientSample/PublishTelemetrySamples.cs b/sdk/digitaltwins/Azure.DigitalTwins.Core/samples/DigitalTwinsClientSample/PublishTelemetrySamples.cs index 7314aea31ce5..3e694e7b9b1d 100644 --- a/sdk/digitaltwins/Azure.DigitalTwins.Core/samples/DigitalTwinsClientSample/PublishTelemetrySamples.cs +++ b/sdk/digitaltwins/Azure.DigitalTwins.Core/samples/DigitalTwinsClientSample/PublishTelemetrySamples.cs @@ -40,7 +40,7 @@ public async Task RunSamplesAsync() string newComponentModelPayload = SamplesConstants.TemporaryComponentModelPayload .Replace(SamplesConstants.ComponentId, componentModelId); - string newModelPayload = SamplesConstants.TemporaryModelPayload + string newModelPayload = SamplesConstants.TemporaryModelWithComponentPayload .Replace(SamplesConstants.ModelId, modelId) .Replace(SamplesConstants.ComponentId, componentModelId); diff --git a/sdk/digitaltwins/Azure.DigitalTwins.Core/samples/DigitalTwinsClientSample/SamplesConstants.cs b/sdk/digitaltwins/Azure.DigitalTwins.Core/samples/DigitalTwinsClientSample/SamplesConstants.cs index 3cec544fa6c3..9f8b42ff6e92 100644 --- a/sdk/digitaltwins/Azure.DigitalTwins.Core/samples/DigitalTwinsClientSample/SamplesConstants.cs +++ b/sdk/digitaltwins/Azure.DigitalTwins.Core/samples/DigitalTwinsClientSample/SamplesConstants.cs @@ -53,7 +53,7 @@ public static class SamplesConstants /// /// The application/json description of a temporary model /// - public const string TemporaryModelPayload = @" + public const string TemporaryModelWithComponentPayload = @" { ""@id"": ""MODEL_ID"", ""@type"": ""Interface"", diff --git a/sdk/digitaltwins/Azure.DigitalTwins.Core/samples/Readme.md b/sdk/digitaltwins/Azure.DigitalTwins.Core/samples/Readme.md index c93ae7e18cbb..8f45ecb97e5e 100644 --- a/sdk/digitaltwins/Azure.DigitalTwins.Core/samples/Readme.md +++ b/sdk/digitaltwins/Azure.DigitalTwins.Core/samples/Readme.md @@ -121,8 +121,25 @@ catch (Exception ex) For Creating Twin you will need to provide Id of a digital Twin such as `myTwin` and the application/json digital twin based on the model created earlier. You can look at sample application/json [here](https://github.com/Azure/azure-sdk-for-net-pr/tree/feature/IoT-ADT/sdk/digitaltwins/Azure.DigitalTwins.Core/samples/DigitalTwinsClientSample/DTDL/DigitalTwins "DigitalTwin"). -```C# Snippet:DigitalTwinsSampleCreateTwin -Response response = await DigitalTwinsClient.CreateDigitalTwinAsync(twin.Key, twin.Value).ConfigureAwait(false); +```C# Snippet:DigitalTwinsSampleCreateBasicTwin +// Create digital twin with Component payload using the BasicDigitalTwin serialization helper + +var basicDigitalTwin = new BasicDigitalTwin(); +basicDigitalTwin.Metadata.ModelId = modelId; +basicDigitalTwin.CustomProperties.Add("Prop1", "Value1"); +basicDigitalTwin.CustomProperties.Add("Prop2", "Value2"); + +var componentMetadata = new ModelProperties(); +componentMetadata.Metadata.ModelId = componentModelId; +componentMetadata.CustomProperties.Add("ComponentProp1", "ComponentValue1"); +componentMetadata.CustomProperties.Add("ComponentProp2", "ComponentValue2"); + +basicDigitalTwin.CustomProperties.Add("Component1", componentMetadata); + +string dtPayload = JsonSerializer.Serialize(basicDigitalTwin, new JsonSerializerOptions { IgnoreNullValues = true }); + +Response createDtResponse = await DigitalTwinsClient.CreateDigitalTwinAsync(dtId, dtPayload).ConfigureAwait(false); +Console.WriteLine($"Created digital twin {dtId} with response {createDtResponse.GetRawResponse().Status}."); ``` ### Query Digital Twin @@ -190,14 +207,14 @@ await DigitalTwinsClient.DeleteDigitalTwinAsync(twin.Key).ConfigureAwait(false); To update a component or in other words to replace, remove and/or add a component property or subproperty within Digital Twin, you would need id of a digital twin, component name and application/json-patch+json operations to be performed on the specified digital twin's component. Here is the sample code on how to do it. ```C# Snippet:DigitalTwinsSampleUpdateComponent -// Update Component with replacing property value -string propertyPath = "/ComponentProp1"; -string propValue = "New Value"; - +// Update Component1 by replacing the property ComponentProp1 value var componentUpdateUtility = new UpdateOperationsUtility(); -componentUpdateUtility.AppendReplaceOp(propertyPath, propValue); +componentUpdateUtility.AppendReplaceOp("/ComponentProp1", "Some new value"); +string updatePayload = componentUpdateUtility.Serialize(); -Response response = await DigitalTwinsClient.UpdateComponentAsync(twinId, SamplesConstants.ComponentPath, componentUpdateUtility.Serialize()); +Response response = await DigitalTwinsClient.UpdateComponentAsync(dtId, "Component1", updatePayload); + +Console.WriteLine($"Updated component for digital twin {dtId}. Update response status: {response.GetRawResponse().Status}"); ``` ### Get Digital Twin Component @@ -205,7 +222,9 @@ Response response = await DigitalTwinsClient.UpdateComponentAsync(twinId Get a component by providing name of a component and id of digital twin it belongs to. ```C# Snippet:DigitalTwinsSampleGetComponent -response = await DigitalTwinsClient.GetComponentAsync(twinId, SamplesConstants.ComponentPath).ConfigureAwait(false); +response = await DigitalTwinsClient.GetComponentAsync(dtId, SamplesConstants.ComponentPath).ConfigureAwait(false); + +Console.WriteLine($"Get component for digital twin: \n{response.Value}. Get response status: {response.GetRawResponse().Status}"); ``` ## Create and list Digital Twin edges diff --git a/sdk/digitaltwins/Azure.DigitalTwins.Core/src/DigitalTwinsClient.cs b/sdk/digitaltwins/Azure.DigitalTwins.Core/src/DigitalTwinsClient.cs index e8bed29036cf..95377339bab7 100644 --- a/sdk/digitaltwins/Azure.DigitalTwins.Core/src/DigitalTwinsClient.cs +++ b/sdk/digitaltwins/Azure.DigitalTwins.Core/src/DigitalTwinsClient.cs @@ -107,8 +107,8 @@ protected DigitalTwinsClient() /// Get a digital twin. /// /// - /// The returned application/json string can always be deserialized into an instance of . - /// It may also be deserialized into custom digital twin types that extend the with additional + /// The returned application/json string can always be deserialized into an instance of . + /// It may also be deserialized into custom digital twin types that extend the with additional /// strongly typed properties provided that you know the definition of the retrieved digital twin prior to deserialization. /// /// The Id of the digital twin. @@ -123,8 +123,8 @@ public virtual Task> GetDigitalTwinAsync(string digitalTwinId, /// Get a digital twin. /// /// - /// The returned application/json string can always be deserialized into an instance of . - /// It may also be deserialized into custom digital twin types that extend the with additional + /// The returned application/json string can always be deserialized into an instance of . + /// It may also be deserialized into custom digital twin types that extend the with additional /// strongly typed properties provided that you know the definition of the retrieved digital twin prior to deserialization. /// /// The Id of the digital twin. @@ -142,10 +142,27 @@ public virtual Response GetDigitalTwin(string digitalTwinId, Cancellatio /// The application/json digital twin to create. /// The cancellation token. /// The created application/json digital twin and the http response. - /// The digital twin must be the serialization of an instance of or the serialization of an extension of that type. + /// The digital twin must be the serialization of an instance of or the serialization of an extension of that type. /// - /// - /// Response<string> response = await DigitalTwinsClient.CreateDigitalTwinAsync(twin.Key, twin.Value).ConfigureAwait(false); + /// + /// // Create digital twin with Component payload using the BasicDigitalTwin serialization helper + /// + /// var basicDigitalTwin = new BasicDigitalTwin(); + /// basicDigitalTwin.Metadata.ModelId = modelId; + /// basicDigitalTwin.CustomProperties.Add("Prop1", "Value1"); + /// basicDigitalTwin.CustomProperties.Add("Prop2", "Value2"); + /// + /// var componentMetadata = new ModelProperties(); + /// componentMetadata.Metadata.ModelId = componentModelId; + /// componentMetadata.CustomProperties.Add("ComponentProp1", "ComponentValue1"); + /// componentMetadata.CustomProperties.Add("ComponentProp2", "ComponentValue2"); + /// + /// basicDigitalTwin.CustomProperties.Add("Component1", componentMetadata); + /// + /// string dtPayload = JsonSerializer.Serialize(basicDigitalTwin, new JsonSerializerOptions { IgnoreNullValues = true }); + /// + /// Response<string> createDtResponse = await DigitalTwinsClient.CreateDigitalTwinAsync(dtId, dtPayload).ConfigureAwait(false); + /// Console.WriteLine($"Created digital twin {dtId} with response {createDtResponse.GetRawResponse().Status}."); /// /// public virtual Task> CreateDigitalTwinAsync(string digitalTwinId, string digitalTwin, CancellationToken cancellationToken = default) @@ -160,7 +177,7 @@ public virtual Task> CreateDigitalTwinAsync(string digitalTwinI /// The application/json digital twin to create. /// The cancellation token. /// The created application/json digital twin and the http response. - /// The digital twin must be the serialization of an instance of or the serialization of an extension of that type. + /// The digital twin must be the serialization of an instance of or the serialization of an extension of that type. public virtual Response CreateDigitalTwin(string digitalTwinId, string digitalTwin, CancellationToken cancellationToken = default) { return _dtRestClient.Add(digitalTwinId, digitalTwin, cancellationToken); @@ -237,7 +254,9 @@ public virtual Response UpdateDigitalTwin(string digitalTwinId, string d /// Json string representation of the component corresponding to the provided componentPath and the HTTP response. /// /// - /// response = await DigitalTwinsClient.GetComponentAsync(twinId, SamplesConstants.ComponentPath).ConfigureAwait(false); + /// response = await DigitalTwinsClient.GetComponentAsync(dtId, SamplesConstants.ComponentPath).ConfigureAwait(false); + /// + /// Console.WriteLine($"Get component for digital twin: \n{response.Value}. Get response status: {response.GetRawResponse().Status}"); /// /// public virtual Task> GetComponentAsync(string digitalTwinId, string componentPath, CancellationToken cancellationToken = default) @@ -268,14 +287,14 @@ public virtual Response GetComponent(string digitalTwinId, string compon /// The HTTP response. /// /// - /// // Update Component with replacing property value - /// string propertyPath = "/ComponentProp1"; - /// string propValue = "New Value"; - /// + /// // Update Component1 by replacing the property ComponentProp1 value /// var componentUpdateUtility = new UpdateOperationsUtility(); - /// componentUpdateUtility.AppendReplaceOp(propertyPath, propValue); + /// componentUpdateUtility.AppendReplaceOp("/ComponentProp1", "Some new value"); + /// string updatePayload = componentUpdateUtility.Serialize(); + /// + /// Response<string> response = await DigitalTwinsClient.UpdateComponentAsync(dtId, "Component1", updatePayload); /// - /// Response<string> response = await DigitalTwinsClient.UpdateComponentAsync(twinId, SamplesConstants.ComponentPath, componentUpdateUtility.Serialize()); + /// Console.WriteLine($"Updated component for digital twin {dtId}. Update response status: {response.GetRawResponse().Status}"); /// /// public virtual Task> UpdateComponentAsync(string digitalTwinId, string componentPath, string componentUpdateOperations, RequestOptions requestOptions = default, CancellationToken cancellationToken = default) diff --git a/sdk/digitaltwins/Azure.DigitalTwins.Core/src/Serialization/BasicDigitalTwin.cs b/sdk/digitaltwins/Azure.DigitalTwins.Core/src/Serialization/BasicDigitalTwin.cs index e6150410131b..882205d0798a 100644 --- a/sdk/digitaltwins/Azure.DigitalTwins.Core/src/Serialization/BasicDigitalTwin.cs +++ b/sdk/digitaltwins/Azure.DigitalTwins.Core/src/Serialization/BasicDigitalTwin.cs @@ -1,7 +1,6 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. -using System.Collections.Generic; using System.Text.Json.Serialization; namespace Azure.DigitalTwins.Core.Serialization @@ -9,24 +8,34 @@ namespace Azure.DigitalTwins.Core.Serialization /// /// An optional, helper class for deserializing a digital twin. /// - public class BasicDigitalTwin + /// + /// + /// // Create digital twin with Component payload using the BasicDigitalTwin serialization helper + /// + /// var basicDigitalTwin = new BasicDigitalTwin(); + /// basicDigitalTwin.Metadata.ModelId = modelId; + /// basicDigitalTwin.CustomProperties.Add("Prop1", "Value1"); + /// basicDigitalTwin.CustomProperties.Add("Prop2", "Value2"); + /// + /// var componentMetadata = new ModelProperties(); + /// componentMetadata.Metadata.ModelId = componentModelId; + /// componentMetadata.CustomProperties.Add("ComponentProp1", "ComponentValue1"); + /// componentMetadata.CustomProperties.Add("ComponentProp2", "ComponentValue2"); + /// + /// basicDigitalTwin.CustomProperties.Add("Component1", componentMetadata); + /// + /// string dtPayload = JsonSerializer.Serialize(basicDigitalTwin, new JsonSerializerOptions { IgnoreNullValues = true }); + /// + /// Response<string> createDtResponse = await DigitalTwinsClient.CreateDigitalTwinAsync(dtId, dtPayload).ConfigureAwait(false); + /// Console.WriteLine($"Created digital twin {dtId} with response {createDtResponse.GetRawResponse().Status}."); + /// + /// + public class BasicDigitalTwin : ModelProperties { /// /// The unique Id of the digital twin in a digital twins instance. This field is present on every digital twin. /// [JsonPropertyName("$dtId")] public string Id { get; set; } - - /// - /// Information about the model a digital twin conforms to. This field is present on every digital twin. - /// - [JsonPropertyName("$metadata")] - public DigitalTwinMetadata Metadata { get; set; } - - /// - /// Additional properties of the digital twin. This field will contain any properties of the digital twin that are not already defined by the other strong types of this class. - /// - [JsonExtensionData] - public IDictionary CustomProperties { get; set; } = new Dictionary(); } } diff --git a/sdk/digitaltwins/Azure.DigitalTwins.Core/src/Serialization/DigitalTwinMetadata.cs b/sdk/digitaltwins/Azure.DigitalTwins.Core/src/Serialization/DigitalTwinMetadata.cs index 1a7464e4f744..bf2bbdbc31e2 100644 --- a/sdk/digitaltwins/Azure.DigitalTwins.Core/src/Serialization/DigitalTwinMetadata.cs +++ b/sdk/digitaltwins/Azure.DigitalTwins.Core/src/Serialization/DigitalTwinMetadata.cs @@ -8,7 +8,7 @@ namespace Azure.DigitalTwins.Core.Serialization { /// /// An optional, helper class for deserializing a digital twin. - /// The $metadata class on a . + /// The $metadata class on a . /// public class DigitalTwinMetadata { @@ -21,7 +21,8 @@ public class DigitalTwinMetadata /// /// Additional, model-defined properties. /// + /// For your convenience, the value of each dictionary object can be turned into an instance of . [JsonExtensionData] - public IDictionary ModelProperties { get; set; } = new Dictionary(); + public IDictionary WriteableProperties { get; set; } = new Dictionary(); } } diff --git a/sdk/digitaltwins/Azure.DigitalTwins.Core/src/Serialization/ModelProperties.cs b/sdk/digitaltwins/Azure.DigitalTwins.Core/src/Serialization/ModelProperties.cs new file mode 100644 index 000000000000..8d4102ad1274 --- /dev/null +++ b/sdk/digitaltwins/Azure.DigitalTwins.Core/src/Serialization/ModelProperties.cs @@ -0,0 +1,26 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System.Collections.Generic; +using System.Text.Json.Serialization; + +namespace Azure.DigitalTwins.Core.Serialization +{ + /// + /// Properties on a digital twin that adhere to a specific model. + /// + public class ModelProperties + { + /// + /// Information about the model a digital twin conforms to. This field is present on every digital twin. + /// + [JsonPropertyName("$metadata")] + public DigitalTwinMetadata Metadata { get; set; } = new DigitalTwinMetadata(); + + /// + /// Additional properties of the digital twin. This field will contain any properties of the digital twin that are not already defined by the other strong types of this class. + /// + [JsonExtensionData] + public IDictionary CustomProperties { get; set; } = new Dictionary(); + } +} diff --git a/sdk/digitaltwins/Azure.DigitalTwins.Core/src/Serialization/UpdateOperationsUtility.cs b/sdk/digitaltwins/Azure.DigitalTwins.Core/src/Serialization/UpdateOperationsUtility.cs index 2109fb680f5b..a7215b956473 100644 --- a/sdk/digitaltwins/Azure.DigitalTwins.Core/src/Serialization/UpdateOperationsUtility.cs +++ b/sdk/digitaltwins/Azure.DigitalTwins.Core/src/Serialization/UpdateOperationsUtility.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. using System.Collections.Generic; @@ -9,6 +9,18 @@ namespace Azure.DigitalTwins.Core.Serialization /// /// A utility to create the application/json-patch+json operations payload required for update operations. /// + /// + /// + /// // Update Component1 by replacing the property ComponentProp1 value + /// var componentUpdateUtility = new UpdateOperationsUtility(); + /// componentUpdateUtility.AppendReplaceOp("/ComponentProp1", "Some new value"); + /// string updatePayload = componentUpdateUtility.Serialize(); + /// + /// Response<string> response = await DigitalTwinsClient.UpdateComponentAsync(dtId, "Component1", updatePayload); + /// + /// Console.WriteLine($"Updated component for digital twin {dtId}. Update response status: {response.GetRawResponse().Status}"); + /// + /// public class UpdateOperationsUtility { private const string Op = "op"; diff --git a/sdk/digitaltwins/Azure.DigitalTwins.Core/src/Serialization/WritableProperty.cs b/sdk/digitaltwins/Azure.DigitalTwins.Core/src/Serialization/WritableProperty.cs index 0aa16611b39a..541154e0e094 100644 --- a/sdk/digitaltwins/Azure.DigitalTwins.Core/src/Serialization/WritableProperty.cs +++ b/sdk/digitaltwins/Azure.DigitalTwins.Core/src/Serialization/WritableProperty.cs @@ -7,7 +7,7 @@ namespace Azure.DigitalTwins.Core.Serialization { /// /// An optional, helper class for deserializing a digital twin. - /// The ModelProperties dictionary on . + /// The ModelProperties dictionary on . /// /// /// A writable property is one that the service may request a change for from the device.