Hi,
I'm working on a custom chat bot command that retrieves the last BPA results. See repo here: SkylineCommunications/SLC-AS-ChatOps-BPA (github.com).
The script uses the following NuGet packages:
which results in the following DLL references when deploying the script on the agent:
The problem I'm facing is that the "AdaptiveCards" NuGet does not seem to be compatible with the latest NewtonSoft NuGet (13.0.2 in this case) which is (from what I understood) referenced in the "Skyline.DataMiner.Core.DataMinerSystem.Automation" NuGet. If I manually change the reference for the NewtonSoft NuGet to version 11.0.2 (C:\Skyline DataMiner\ProtocolScripts\DllImport\newtonsoft.json\11.0.2\lib\net45\Newtonsoft.Json.dll), then my command is working as expected.
Is there anyway to enforce the use of that specific NuGet version so I don't have to manually change this after deploying my script?
After a long investigation it turns out that it looks like the [JsonObject] on top of the AdaptiveTypedElement class is not being detected. The attribute defines that classes need to be serialized as object, even though as array might be more appropriate. Because the attribute is not detected, some classes are being serialized as array, which is causing the NotImplementedException.
This is related to how DataMiner is loading DLLs into memory. What happens is the following:
- When the AdaptiveCards DLL is loaded, it uses the attributes from Newtonsoft11, specifically the AdaptiveTypedElement with Newtonsoft11.JsonObjectAttribute.
- Newtonsoft13 is used for serialization and looks for the NewtonSoft13.JsonObjectAttribute above classes. Since this attribute is not available (because the AdaptiveCards dll relies on the older version, Newtonsoft11), Newtonsoft13 behaves as if this attribute does not exist. Serialization continues as if theJsonObjectAttribute is not specified above the AdaptiveTypedElement class.
As a workaround you can force to serialize as object instead of array, by using a custom resolver:
private static void Test()
{
var adaptiveCardBody = new List<AdaptiveElement>()
{
new AdaptiveContainer { new AdaptiveFactSet(), }
};var settings = new JsonSerializerSettings()
{
ContractResolver = new CustomContractResolver(),
};var json = JsonConvert.SerializeObject(adaptiveCardBody, settings);
}
}public class CustomContractResolver : DefaultContractResolver
{
public override JsonContract ResolveContract(Type objectType)
{
var contract = base.ResolveContract(objectType);if (typeof(AdaptiveCollectionElement).IsAssignableFrom(contract.UnderlyingType))
{
contract = CreateObjectContract(objectType);
}return contract;
}
}
Thanks Tom! Even though that indeed solves the issues with the serialization (exception no longer thrown). It does result in a different string which causes problems when it is being deserialized to show the AdaptiveCard in Teams.
Hi Joey
Currently we don't have a way to force lower versions of Newtonsoft. Keep in mind that lower versions also have security vulnerabilities. That is why it's advised to keep using the latest Newtonsoft versions. I would suggest to create an issue on their repository. I saw that someone else has an issue with it as well, but it seems there isn't much activity focused on that, so it could be that they won't update soon.
Hi Michiel, I have been trying to reproduce this issue in a console application but I’m unable to. No matter what version I’m using of the NewtonSoft NuGet in combination with the AdaptiveCards NuGet, I never run into that issue. Could this be related to this question (which was for a protocol): https://community.dataminer.services/question/dis-importing-dllimports-wrong
Hi Joey
This is indeed related to the issue from the question. Unfortunately, we don’t have a fix for this yet, but we are looking into it.
Hi,
We just released support for Adaptive Cards with ChatIntegration and also had issues with serialization/dlls during development. We found another easier way of doing it.
We added a helper method in our ChatIntegrationHelper nuget (version 1.2.0) so you can easily call `.ToJson()` on the list of AdaptiveElements. We've updated the Custom Command with adaptive card example here: https://github.com/SkylineCommunications/ChatOps-Extensions/tree/main/CustomCommandExamples
We are in the progress of designing several POC’s that will change the architecture of how DataMiner loads up assemblies to address problems with assembly version conflicts and inconsistent behavior between a normal program/visual studio and the runtime of the code on a DataMiner.
Without going too deep into it. The root cause of most of these issues is the lack of bindingredirects in DataMiner for automationscripts and connectors. It’s that lack we’ll be looking to fix. We’ve got a few options but they all consist of running more than one SLScripting process or similar which will need good scaling tests.