C# Azure IOT Hub SDK设置了一个布尔值无效的所需属性

C# Azure IOT Hub SDK设置了一个布尔值无效的所需属性,c#,azure-iot-hub,azure-iot-sdk,C#,Azure Iot Hub,Azure Iot Sdk,在编译json字符串时,我遇到了一个问题,即使用布尔值设置一些所需的属性。我从azure Hub SDK返回了一个异常,“在分析值时遇到意外字符:T.Path”properties.desired.smtpServer.logEvents”,第9行,第39位 如果将属性logEvents设置为字符串,则会执行OK 看看其他想要的属性示例,我们没有理由不能使用布尔值而不是将它们转换为字符串,我构建json的方式是否有问题?完全失去了这里的问题所在 更新-一种不同的方法,但仍然不起作用: 根据下面给

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

如果将属性logEvents设置为字符串,则会执行OK

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

更新-一种不同的方法,但仍然不起作用:

根据下面给出的答案,我尝试使用Newtonsoft序列化程序,但现在发现所需的属性根本没有更新,但同样地,我也没有从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);
    }

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

虽然这将修复异常,并修复您的问题(IoT Hub将很好地接受此文本),但这仍然是无效的JSON。所有属性和字符串值都应该用双引号括起来。您希望您的JSON最终看起来像这样:

{
“财产”:{
“期望”:{
“smtpServer”:{
“编码”:“是”,
“数据限制”:100,
“ipAddress”:“是”,
“端口号”:22,
“日志事件”:正确,
“自动启动”:正确
}
}
}
}
自己编写JSON会变得相当乏味,因此最好使用JSON序列化程序。Azure SDK在内部使用Newtonsoft.Json,因此您可以执行以下操作,而不必自己调用序列化程序:

private静态异步任务updatewin()
{
var smtpServer=新的smtpServer
{
Encoding=“bar”,
数据限制=100,
IpAddress=“foo”,
端口号=42,
LogEvents=true,
自动启动=真
};
var registryManager=registryManager.CreateFromConnectionString(ConnectionString);
var twin=await registryManager.GetTwinAsync(TestDevice);
twin.Properties.required[“smtpServer”]=smtpServer;
等待registryManager.updatewinasync(twin.DeviceId,twin,twin.ETag);
}
公共类SmtpServer
{
[JsonProperty(“编码”)]
公共字符串编码{get;set;}
[JsonProperty(“数据限制”)]
公共int数据限制{get;set;}
[JsonProperty(“ipAddress”)]
公共字符串IpAddress{get;set;}
[JsonProperty(“端口号”)]
公共int端口号{get;set;}
[JsonProperty(“logEvents”)]
公共bool日志事件{get;set;}
[JsonProperty(“autoStart”)]
公共bool自动启动{get;set;}
}

在我的集线器上测试了该代码,它运行正常。

嗨,Matthijis,谢谢你的回复。我想一种方法是使用一个模型类,并在我前进的过程中用新属性更新该类?比如这里的例子:那就更好了!将JSON写入软件始终是一个好策略!您好,我尝试使用JsonConvert.SerializeObject(属性);使用模型类,但发现在Azure中设置属性没有任何作用。我没有从IOT Hub SDK收到任何错误,因此我不知道如何对此进行故障排除。我已经用一个示例更新了我的答案,说明了如何在不必自己序列化任何内容的情况下更新twin。太棒了,非常感谢您花这么多时间在这方面。听说他们自己使用Newtonsoft很有趣,但仍然不确定我做错了什么,但你的方法是一个更干净的解决方案。
    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);
    }