From 55dc940abb02786e47fc01da3aa209d640c1860a Mon Sep 17 00:00:00 2001 From: PMExtra Date: Mon, 30 Mar 2020 17:10:04 +0800 Subject: [PATCH 1/6] GetUserProperty extension. --- .../Extensions/UserPropertyExtension.cs | 18 ++++++++++++ .../MqttApplicationMessage_Tests.cs | 29 +++++++++++++++++++ 2 files changed, 47 insertions(+) create mode 100644 Source/MQTTnet/Extensions/UserPropertyExtension.cs create mode 100644 Tests/MQTTnet.Core.Tests/MqttApplicationMessage_Tests.cs diff --git a/Source/MQTTnet/Extensions/UserPropertyExtension.cs b/Source/MQTTnet/Extensions/UserPropertyExtension.cs new file mode 100644 index 0000000..273be25 --- /dev/null +++ b/Source/MQTTnet/Extensions/UserPropertyExtension.cs @@ -0,0 +1,18 @@ +using System; +using System.Linq; + +namespace MQTTnet.Extensions +{ + public static class UserPropertyExtension + { + public static string GetUserProperty(this MqttApplicationMessage message, string propertyName, StringComparison comparisonType = StringComparison.OrdinalIgnoreCase) + { + return message.UserProperties.SingleOrDefault(up => up.Name.Equals(propertyName, comparisonType))?.Value; + } + + public static T GetUserProperty(this MqttApplicationMessage message, string propertyName, StringComparison comparisonType = StringComparison.OrdinalIgnoreCase) + { + return (T) Convert.ChangeType(GetUserProperty(message, propertyName, comparisonType), typeof(T)); + } + } +} diff --git a/Tests/MQTTnet.Core.Tests/MqttApplicationMessage_Tests.cs b/Tests/MQTTnet.Core.Tests/MqttApplicationMessage_Tests.cs new file mode 100644 index 0000000..073e4c4 --- /dev/null +++ b/Tests/MQTTnet.Core.Tests/MqttApplicationMessage_Tests.cs @@ -0,0 +1,29 @@ +using System.Collections.Generic; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using MQTTnet.Extensions; +using MQTTnet.Packets; + +namespace MQTTnet.Tests +{ + [TestClass] + public class MqttApplicationMessage_Tests + { + [TestMethod] + public void GetUserProperty_Test() + { + var message = new MqttApplicationMessage + { + UserProperties = new List + { + new MqttUserProperty("foo", "bar"), + new MqttUserProperty("value", "1011"), + new MqttUserProperty("CASE", "insensitive") + } + }; + + Assert.AreEqual("bar", message.GetUserProperty("foo")); + Assert.AreEqual(1011, message.GetUserProperty("value")); + Assert.AreEqual("insensitive", message.GetUserProperty("case")); + } + } +} From f7f00f4e061562c957d398e10130484dca77951d Mon Sep 17 00:00:00 2001 From: PMExtra Date: Tue, 31 Mar 2020 12:03:00 +0800 Subject: [PATCH 2/6] Update nuspec. --- Build/MQTTnet.nuspec | 1 + 1 file changed, 1 insertion(+) diff --git a/Build/MQTTnet.nuspec b/Build/MQTTnet.nuspec index a6e7faf..e09ed01 100644 --- a/Build/MQTTnet.nuspec +++ b/Build/MQTTnet.nuspec @@ -22,6 +22,7 @@ * [Server] Added interceptor for unsubscriptions. * [MQTTnet.Server] Added interceptor for unsubscriptions. * [MQTTnet.AspNetCore] improved compatibility with AspNetCore 3.1 +* [MqttApplicationMessage] Added GetUserProperty convenience method (thanks to @PMExtra). Copyright Christian Kratky 2016-2019 MQTT Message Queue Telemetry Transport MQTTClient MQTTServer Server MQTTBroker Broker NETStandard IoT InternetOfThings Messaging Hardware Arduino Sensor Actuator M2M ESP Smart Home Cities Automation Xamarin From aafd4ea6580a3ed73ea853d19457e1b16cbaa60f Mon Sep 17 00:00:00 2001 From: PMExtra Date: Wed, 1 Apr 2020 15:30:24 +0800 Subject: [PATCH 3/6] Fix. --- Build/MQTTnet.nuspec | 2 +- Source/MQTTnet/Extensions/UserPropertyExtension.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Build/MQTTnet.nuspec b/Build/MQTTnet.nuspec index e09ed01..c409f86 100644 --- a/Build/MQTTnet.nuspec +++ b/Build/MQTTnet.nuspec @@ -22,7 +22,7 @@ * [Server] Added interceptor for unsubscriptions. * [MQTTnet.Server] Added interceptor for unsubscriptions. * [MQTTnet.AspNetCore] improved compatibility with AspNetCore 3.1 -* [MqttApplicationMessage] Added GetUserProperty convenience method (thanks to @PMExtra). +* [Core] Added MqttApplicationMessage.GetUserProperty<T>() convenience method (thanks to @PMExtra). Copyright Christian Kratky 2016-2019 MQTT Message Queue Telemetry Transport MQTTClient MQTTServer Server MQTTBroker Broker NETStandard IoT InternetOfThings Messaging Hardware Arduino Sensor Actuator M2M ESP Smart Home Cities Automation Xamarin diff --git a/Source/MQTTnet/Extensions/UserPropertyExtension.cs b/Source/MQTTnet/Extensions/UserPropertyExtension.cs index 273be25..b4c83b4 100644 --- a/Source/MQTTnet/Extensions/UserPropertyExtension.cs +++ b/Source/MQTTnet/Extensions/UserPropertyExtension.cs @@ -7,7 +7,7 @@ namespace MQTTnet.Extensions { public static string GetUserProperty(this MqttApplicationMessage message, string propertyName, StringComparison comparisonType = StringComparison.OrdinalIgnoreCase) { - return message.UserProperties.SingleOrDefault(up => up.Name.Equals(propertyName, comparisonType))?.Value; + return message?.UserProperties?.SingleOrDefault(up => up.Name.Equals(propertyName, comparisonType))?.Value; } public static T GetUserProperty(this MqttApplicationMessage message, string propertyName, StringComparison comparisonType = StringComparison.OrdinalIgnoreCase) From 763d9778bb66bf131960d9281d243d9a826219a5 Mon Sep 17 00:00:00 2001 From: PMExtra Date: Thu, 2 Apr 2020 17:29:00 +0800 Subject: [PATCH 4/6] Check parameters and add friendly exceptions. --- .../MQTTnet/Extensions/UserPropertyExtension.cs | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/Source/MQTTnet/Extensions/UserPropertyExtension.cs b/Source/MQTTnet/Extensions/UserPropertyExtension.cs index b4c83b4..8918600 100644 --- a/Source/MQTTnet/Extensions/UserPropertyExtension.cs +++ b/Source/MQTTnet/Extensions/UserPropertyExtension.cs @@ -7,12 +7,24 @@ namespace MQTTnet.Extensions { public static string GetUserProperty(this MqttApplicationMessage message, string propertyName, StringComparison comparisonType = StringComparison.OrdinalIgnoreCase) { - return message?.UserProperties?.SingleOrDefault(up => up.Name.Equals(propertyName, comparisonType))?.Value; + if (message == null) throw new ArgumentNullException(nameof(message)); + if (propertyName == null) throw new ArgumentNullException(nameof(propertyName)); + + return message.UserProperties?.SingleOrDefault(up => up.Name.Equals(propertyName, comparisonType))?.Value; } public static T GetUserProperty(this MqttApplicationMessage message, string propertyName, StringComparison comparisonType = StringComparison.OrdinalIgnoreCase) { - return (T) Convert.ChangeType(GetUserProperty(message, propertyName, comparisonType), typeof(T)); + var value = GetUserProperty(message, propertyName, comparisonType); + + try + { + return (T) Convert.ChangeType(value, typeof(T)); + } + catch (Exception ex) + { + throw new InvalidOperationException($"Cannot convert value({value}) of UserProperty({propertyName}) to {typeof(T).FullName}.", ex); + } } } } From c83bec6e81421553741d39d4966b9d3ee8d09e22 Mon Sep 17 00:00:00 2001 From: PMExtra Date: Fri, 3 Apr 2020 14:44:04 +0800 Subject: [PATCH 5/6] Fix for Nullable. --- Source/MQTTnet/Extensions/UserPropertyExtension.cs | 4 +++- Source/MQTTnet/MQTTnet.csproj | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/Source/MQTTnet/Extensions/UserPropertyExtension.cs b/Source/MQTTnet/Extensions/UserPropertyExtension.cs index 8918600..e950141 100644 --- a/Source/MQTTnet/Extensions/UserPropertyExtension.cs +++ b/Source/MQTTnet/Extensions/UserPropertyExtension.cs @@ -1,4 +1,5 @@ using System; +using System.ComponentModel; using System.Linq; namespace MQTTnet.Extensions @@ -17,9 +18,10 @@ namespace MQTTnet.Extensions { var value = GetUserProperty(message, propertyName, comparisonType); + var typeDescriptor = TypeDescriptor.GetConverter(typeof(T)); try { - return (T) Convert.ChangeType(value, typeof(T)); + return (T) typeDescriptor.ConvertFromString(value); } catch (Exception ex) { diff --git a/Source/MQTTnet/MQTTnet.csproj b/Source/MQTTnet/MQTTnet.csproj index 28e3f3d..07b9161 100644 --- a/Source/MQTTnet/MQTTnet.csproj +++ b/Source/MQTTnet/MQTTnet.csproj @@ -42,6 +42,7 @@ + From 774d49a908a62b893f67f9b6a07894bfd01cd386 Mon Sep 17 00:00:00 2001 From: PMExtra Date: Fri, 3 Apr 2020 14:49:39 +0800 Subject: [PATCH 6/6] Fix exception message and add test cases. --- Source/MQTTnet/Extensions/UserPropertyExtension.cs | 2 +- Tests/MQTTnet.Core.Tests/MqttApplicationMessage_Tests.cs | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/Source/MQTTnet/Extensions/UserPropertyExtension.cs b/Source/MQTTnet/Extensions/UserPropertyExtension.cs index e950141..5bb28cf 100644 --- a/Source/MQTTnet/Extensions/UserPropertyExtension.cs +++ b/Source/MQTTnet/Extensions/UserPropertyExtension.cs @@ -25,7 +25,7 @@ namespace MQTTnet.Extensions } catch (Exception ex) { - throw new InvalidOperationException($"Cannot convert value({value}) of UserProperty({propertyName}) to {typeof(T).FullName}.", ex); + throw new InvalidOperationException($"Cannot convert value({value ?? "null"}) of UserProperty({propertyName}) to {typeof(T).FullName}.", ex); } } } diff --git a/Tests/MQTTnet.Core.Tests/MqttApplicationMessage_Tests.cs b/Tests/MQTTnet.Core.Tests/MqttApplicationMessage_Tests.cs index 073e4c4..6b791dc 100644 --- a/Tests/MQTTnet.Core.Tests/MqttApplicationMessage_Tests.cs +++ b/Tests/MQTTnet.Core.Tests/MqttApplicationMessage_Tests.cs @@ -1,3 +1,4 @@ +using System; using System.Collections.Generic; using Microsoft.VisualStudio.TestTools.UnitTesting; using MQTTnet.Extensions; @@ -24,6 +25,9 @@ namespace MQTTnet.Tests Assert.AreEqual("bar", message.GetUserProperty("foo")); Assert.AreEqual(1011, message.GetUserProperty("value")); Assert.AreEqual("insensitive", message.GetUserProperty("case")); + Assert.AreEqual(null, message.GetUserProperty("nonExists")); + Assert.AreEqual(null, message.GetUserProperty("nonExists")); + Assert.ThrowsException(() => message.GetUserProperty("nonExists")); } } }