Closed davidpeden3 closed 9 years ago
So impromptu uses the same api's as the C# dynamic keyword, which binding is case sensitive, however the dynamic objects themselves don't have to be.
Here is the line for the dynamic object in json.net: https://github.com/JamesNK/Newtonsoft.Json/blob/73a266217bfbcbb90b506d4e56ef2741fe76484f/Src/Newtonsoft.Json/Linq/JObject.cs#L801
What it could possibly do instead is
result = instance.GetValue(binder.Name, StringComparison.InvariantCultureIgnoreCase);
There maybe a more better or consistent way to do this with json.net api's, this is just any example.
I'm cool with "wontfix" but to be clear on what I was asking for, Json.NET can't know (and shouldn't really) to create a dynamic object with Pascal-cased properties when the incoming JSON is camel-cased. With camel-cased properties on the dynamic object, ActLike fails to bind them to the interface (which has Pascal-cased properties) as mentioned. It's not an issue with Json.NET at all. Nonetheless, thanks for the comment.
ActLike uses the DLR and late binds to JObjectDynamicProxy.TryGetMember
whether that method returns true
or false
determines whether the binding will be successful and what result
is set to determines the return value.
When you call JsonConvert.DeserializeObjectTryGetMember
is called with the name passed as an argument, inside that method is the only place your issue can be solved. It works with ImpromptuInterface exactly the same way it works with the dynamic
keyword.
Gotcha. Thanks for the detailed explanation.
It is common for JSON to be camel-cased and .NET interfaces to be Pascal-cased. Adding case-insensitive binding similar to JSON.NET's behavior would be great. The use case comes up when deserializing JSON to dynamic.
The following two lines of code:
var dynamicValue = JsonConvert.DeserializeObject<dynamic>(value); var duckType = Impromptu.ActLike<TInterface>(dynamicValue);
work as expected when the JSON properties are Pascal-cased but fail when they are camel-cased. Since JSON.NET is told to deserialize into dynamic, it does not bind like it would if you were deserializing to a specific class. Enabling case-insensitivity in the call to ActLike would solve the problem.