您好,当我们尝试从IOT集线器获取设备孪生时,会出现此投射错误
@Edge(value="children")
public class NodeChild extends CommonBo {
...
}
我们使用设备SDK,
Microsoft.Azure.Devices.Common.Exceptions.IotHubException: Unable to cast object of type 'System.DateTimeOffset' to type 'System.DateTime'. ---> System.InvalidCastException: Unable to cast object of type 'System.DateTimeOffset' to type 'System.DateTime'.
at Microsoft.Azure.Devices.Shared.TwinJsonConverter.ReadJson(JsonReader reader, Type objectType, Object existingValue, JsonSerializer serializer)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.DeserializeConvertable(JsonConverter converter, JsonReader reader, Type objectType, Object existingValue)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize(JsonReader reader, Type objectType, Boolean checkAdditionalContent)
at Newtonsoft.Json.JsonSerializer.DeserializeInternal(JsonReader reader, Type objectType)
at Newtonsoft.Json.JsonConvert.DeserializeObject(String value, Type type, JsonSerializerSettings settings)
at Newtonsoft.Json.JsonConvert.DeserializeObject[T](String value, JsonSerializerSettings settings)
at Microsoft.Azure.Devices.HttpClientHelper.<ReadResponseMessageAsync>d__17`1.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.Azure.Devices.HttpClientHelper.<>c__DisplayClass10_0`1.<<GetAsync>b__9>d.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.Azure.Devices.HttpClientHelper.<ExecuteAsync>d__35.MoveNext()
--- End of inner exception stack trace ---
at Microsoft.Azure.Devices.HttpClientHelper.<ExecuteAsync>d__35.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.Azure.Devices.HttpClientHelper.<GetAsync>d__10`1.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
到目前为止,我还无法从本地复制此文件,但是它是在我们的一种测试环境中发生的。
答案 0 :(得分:1)
使用registryManager中的Rest API获取双胞胎设备:
#region get the device twin
var finfo = registryManager.GetType().GetField("httpClientHelper", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(registryManager);
HttpClient client = finfo.GetType().GetField("httpClientObj", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(finfo) as HttpClient;
var provider = finfo.GetType().GetField("authenticationHeaderProvider", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(finfo);
dynamic sastoken = provider.GetType().InvokeMember("GetAuthorizationHeader", BindingFlags.Public | BindingFlags.Instance | BindingFlags.InvokeMethod, null, provider, null);
if (client.DefaultRequestHeaders.Authorization == null)
client.DefaultRequestHeaders.Add("Authorization", sastoken);
var jsontext = client.GetStringAsync("https://{yourNamespace}.azure-devices.net/twins/{yourDeviceId}?api-version=2018-04-01").Result;
// log this jsontext
var twin = JsonConvert.DeserializeObject<Twin>(jsontext);
#endregion
在您的“不良”环境中使用上述代码段查看设备的json格式文本。
答案 1 :(得分:1)
我们花了一些时间才弄清楚,但请检查默认json序列化程序是否已将DateParseHandling配置为DateTimeOffset。
JsonConvert.DefaultSettings = () => new JsonSerializerSettings
{
DateParseHandling = DateParseHandling.DateTimeOffset
};
在这种情况下,您将不得不覆盖DeviceTwin的序列化程序,因为其他代码必须取决于此设置。
答案 2 :(得分:0)
尽管DateTimeOffset结构提供了比DateTime结构更大的时区感知能力,但DateTime参数在方法调用中更常用。因此,将DateTimeOffset值转换为DateTime值,反之亦然的能力尤其重要。更多信息here。
我认为您需要检查不同环境中的时区设置以及双胞胎设备的属性值。