-
Notifications
You must be signed in to change notification settings - Fork 2.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix dynamic field value issues #16294
Conversation
This approach is not feasible IMHO, because you loose the dynamic behavior of |
@@ -0,0 +1,41 @@ | |||
namespace System.Text.Json.Dynamic; | |||
|
|||
public struct JsonDynamicValueWrapper<T> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe refer to Nullable, this experiment didn't work for me~
I remember that under version 1.8, |
I think your problem is not in the dynamic wrappers itself, but the fact that they are serialized as well. In contrast to NSJ we now have a layer more, to support the dynamic behavior NSJ has by default. But when you serialize e.g. a public override void Write(
Utf8JsonWriter writer,
object objectToWrite,
JsonSerializerOptions options)
{
if (objectToWrite is JsonDynamicValue value && value.JsonValue != null)
{
value.JsonValue.WriteTo(writer, options);
}
else
{
JsonSerializer.Serialize(writer, objectToWrite, objectToWrite.GetType(), options);
} |
Like the following unit test, actually in version 1.8 we can use It looks like if we have to use STJ in 2.0, we'll have to give up a few things. var contentItem2 = JConvert.DeserializeObject<ContentItem>(json);
Assert.Equal(new DateTime(2024, 1, 1, 10, 42, 0, DateTimeKind.Utc), (DateTime?)contentItem2.Content.MyPart.myField.Value); |
switch (valueKind) | ||
{ | ||
case JsonValueKind.String: | ||
if(jsonValue.TryGetValue<DateTime>(out var datetime)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've added some type conversion tests here, If this solution is acceptable, perhaps we need to add some abstraction converters for some custom development scenarios
src/OrchardCore/OrchardCore.Abstractions/Json/Dynamic/JsonDynamicObject.cs
Outdated
Show resolved
Hide resolved
Co-authored-by: Hisham Bin Ateya <hishamco_2007@yahoo.com>
Co-authored-by: Hisham Bin Ateya <hishamco_2007@yahoo.com>
src/OrchardCore/OrchardCore.Abstractions/Json/Dynamic/JsonDynamicObject.cs
Outdated
Show resolved
Hide resolved
switch (valueKind) | ||
{ | ||
case JsonValueKind.String: | ||
if (memberName == "Value") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If I remember correctly the only two types of fields that currently take values from strings in OC seem to be these two types, which are always wrapped in Value
If I understand your approach correctly, you are moving parts of the value conversions from In summary, I strongly suggest to keep the current separation of value and object. Don't add conversion functionality into the |
@@ -95,6 +97,14 @@ public bool Remove(string key) | |||
return null; | |||
} | |||
|
|||
foreach (var handler in JsonDynamicConfigurations.ValueHandlers) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added a static collection to handle dynamic values for custom development environments
/// <typeparam name="T"></typeparam> | ||
/// <param name="services"></param> | ||
/// <returns></returns> | ||
public static IServiceCollection AddJsonDynamicValueHandler<T>(this IServiceCollection services) where T : IJsonDynamicValueHandler, new() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Custom fetch logic can be added here
Okay, if we have to do that, it's not impossible, we may have to pass the MemberName to the |
I don't understand exactly what you mean by that, but I think we don't have to do a lot beside #16292. I'll add custom [Fact]
public void TestDynamicValueAssignToOther()
{
var contentItem = new ContentItem();
contentItem.Alter<TestPart>(part =>
{
part.TextFieldProp = new TextField { Text = "test" };
part.NumericFieldProp = new NumericField { Value = 123 };
part.BooleanFieldProp = new BooleanField { Value = true };
});
dynamic expandoValue = new ExpandoObject();
expandoValue.stringValue = contentItem.Content.TestPart.TextFieldProp.Text;
expandoValue.numberValue = contentItem.Content.TestPart.NumericFieldProp.Value;
expandoValue.booleanValue = contentItem.Content.TestPart.BooleanFieldProp.Value;
var jsonStr = JConvert.SerializeObject((ExpandoObject)expandoValue);
Assert.Equal("{\"stringValue\":\"test\",\"numberValue\":123,\"booleanValue\":true}", jsonStr);
} Note that we decided to not bring back support for |
If we don't seem to have a way to ask the user to force a type conversion in Jint |
But it should be almost the same as with NSJ now. Only |
Please check #16292 again if it is enough for you. |
Thanks, but I still need to verify the difference between it and NSJ in Jint to make sure I don't have any more problems with my existing programmes. I need some time to verify them. |
fixes #16290
/cc @gvkries