首页 > 解决方案 > Azure IOT Hub SDK 使用布尔值设置设备孪生所需属性不起作用

问题描述

我在编译 json 字符串时使用布尔值设置一些所需的属性时遇到问题,我从 azure Hub SDK 返回异常,其中“解析值时遇到意外字符:T. Path 'properties.desired.smtpServer。 logEvents',第 9 行,第 39 位。""

             var twin = await _registryManager.GetTwinAsync(deviceId);

             var patch =           
             @"{
                properties: {
                    desired: {
                        smtpServer: {
                            encoding: '" + server.Encoding + @"',
                            dataLimit: " + server.DataLimit + @",
                            ipAddress: '" + server.IpAddress + @"',
                            portNumber: " + server.PortNumber + @",
                            logEvents: " + true + @", // not working - doesnt like the boolean
                            autoStart: " + true + @", // not working - doesnt like the boolean
                        }
                    }
                }
            }";

            await _registryManager.UpdateTwinAsync(twin.DeviceId, patch, twin.ETag);

如果将属性 logEvents 设置为字符串,则它通过 OK。

查看其他所需的属性示例,我们没有理由不能使用布尔值而不是将它们转换为字符串,我构建 json 的方式有问题吗?完全失去了这里的问题......

更新 - 一种不同的方法,但仍然无法正常工作:

按照下面给出的答案,然后我尝试使用 Newtonsoft Serializer,但现在发现所需的属性根本没有更新,但同样我没有从 IOT Hub SDK 得到任何异常,所以我不知道如何解决这个问题。

模型类:

public class properties
{
    [JsonProperty("desired")]
    public desired desired { get; set; }
}

public class desired
{
    [JsonProperty("smtpServer")]
    public smtpServer smtpServer { get; set; }
}

public class smtpServer
{
    [JsonProperty("encoding")]
    public string encoding { get; set; }

    [JsonProperty("dataLimit")]
    public int dataLimit { get; set; }

    [JsonProperty("ipAddress")]
    public string ipAddress { get; set; }

    [JsonProperty("portNumber")]
    public int portNumber { get; set; }

    [JsonProperty("logEvents")]
    public bool logEvents { get; set; }

    [JsonProperty("autoStart")]
    public bool autoStart { get; set; }

    [JsonProperty("enabled")]
    public bool enabled { get; set; }
}

更新方法:

    public async Task UpdateServer(string deviceId, smtpServer server)
    {
        var twin = await _registryManager.GetTwinAsync(deviceId);

        var smtpServer = new smtpServer
        {
            encoding = server.encoding,
            dataLimit = server.dataLimit,
            ipAddress = server.ipAddress,
            portNumber = server.portNumber,
            logEvents = server.logEvents,
            autoStart = server.autoStart,
            enabled = server.enabled,
        };

        var desired = new desired
        {
            smtpServer = smtpServer
        };

        var properties = new properties
        {
            desired = desired
        };

        //var patch = JsonConvert.SerializeObject(properties, Formatting.Indented);
        var patch = JsonConvert.SerializeObject(properties);
        await _registryManager.UpdateTwinAsync(twin.DeviceId, patch, twin.ETag);
    }

标签: c#azure-iot-hubazure-iot-sdk

解决方案


IoT Hub 将不接受这种形式的 JSON,因为使用该值true并将其添加到字符串会将其转换为True(注意大写 T)。这不是 JSON 解析器的有效值。确保您发送的值是小写的。

虽然这将解决异常并解决您的问题(IoT 中心将接受此文本就好了),但这仍然不是有效的 JSON。所有属性和字符串值都应该用双引号括起来。你希望你的 JSON 最终看起来像这样:

{
   "properties":{
      "desired":{
         "smtpServer":{
            "encoding":"yes",
            "dataLimit":100,
            "ipAddress":"yes",
            "portNumber":22,
            "logEvents":true,
            "autoStart":true
         }
      }
   }
}

自己编写 JSON 非常繁琐,因此最好使用 JSON 序列化程序。Azure SDK 在内部使用 Newtonsoft.Json,因此您可以执行以下操作而不自己调用序列化程序:

private static async Task UpdateTwin()
{
    var smtpServer = new SmtpServer
    {
        Encoding = "bar",
        DataLimit = 100,
        IpAddress = "foo",
        PortNumber = 42,
        LogEvents = true,
        AutoStart = true
    };
    var registryManager = RegistryManager.CreateFromConnectionString(ConnectionString);
    var twin = await registryManager.GetTwinAsync(TestDevice);
    twin.Properties.Desired["smtpServer"] = smtpServer;
    await registryManager.UpdateTwinAsync(twin.DeviceId, twin, twin.ETag);
}

public class SmtpServer
{
    [JsonProperty("encoding")] 
    public string Encoding { get; set; }

    [JsonProperty("dataLimit")] 
    public int DataLimit { get; set; }

    [JsonProperty("ipAddress")] 
    public string IpAddress { get; set; }

    [JsonProperty("portNumber")] 
    public int PortNumber { get; set; }

    [JsonProperty("logEvents")] 
    public bool LogEvents { get; set; }
    
    [JsonProperty("autoStart")] 
    public bool AutoStart { get; set; }
}

在我的集线器上测试了该代码,它可以正常工作。


推荐阅读