-
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
Changes from 12 commits
25400cd
5878bfb
3233246
91f2d56
2383094
93bebcb
b4cc16a
900d41a
88a7f55
2f8a642
6623648
4447f64
ba9c864
f5a6267
61e2678
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Text.Json; | ||
using System.Text.Json.Nodes; | ||
using Json.More; | ||
|
||
namespace OrchardCore.Json.Dynamic; | ||
public class DefaultJsonDyanmicValueHandler : IJsonDynamicValueHandler | ||
{ | ||
public bool GetValue(JsonObject jsonObject, Dictionary<string, object> dynamicValueDict, string memberName, JsonNode currentNode) | ||
{ | ||
if (currentNode is JsonValue jsonValue) | ||
{ | ||
var valueKind = jsonValue.GetValueKind(); | ||
switch (valueKind) | ||
{ | ||
case JsonValueKind.String: | ||
if (memberName == "Value") | ||
{ | ||
if (jsonValue.TryGetValue<DateTime>(out var datetime)) | ||
{ | ||
dynamicValueDict[memberName] = datetime; | ||
return true; | ||
} | ||
|
||
if (jsonValue.TryGetValue<TimeSpan>(out var timeSpan)) | ||
{ | ||
dynamicValueDict[memberName] = timeSpan; | ||
return true; | ||
} | ||
} | ||
dynamicValueDict[memberName] = jsonValue.GetString(); | ||
return true; | ||
case JsonValueKind.Number: | ||
dynamicValueDict[memberName] = jsonValue.GetNumber(); | ||
return true; | ||
case JsonValueKind.True: | ||
dynamicValueDict[memberName] = true; | ||
return true; | ||
case JsonValueKind.False: | ||
dynamicValueDict[memberName] = false; | ||
return true; | ||
} | ||
} | ||
return false; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
using System.Collections.Generic; | ||
using System.Text.Json.Dynamic; | ||
using System.Text.Json.Nodes; | ||
|
||
namespace OrchardCore.Json.Dynamic; | ||
public interface IJsonDynamicValueHandler | ||
{ | ||
/// <summary> | ||
/// Building dynamic fetch logic for the ContentItem.Content property. | ||
/// <para><see cref="JsonDynamicObject.GetValue(string)"/></para> | ||
/// <para><seealso cref="DefaultJsonDyanmicValueHandler"/></para> | ||
/// </summary> | ||
/// <param name="parentNode"></param> | ||
/// <param name="dynamicValueDict"></param> | ||
/// <param name="memberName"></param> | ||
/// <param name="memberNode"></param> | ||
/// <returns></returns> | ||
bool GetValue(JsonObject parentNode, Dictionary<string, object?> dynamicValueDict, string memberName, JsonNode memberNode); | ||
Check failure on line 18 in src/OrchardCore/OrchardCore.Abstractions/Json/Dynamic/IJsonDynamicValueHandler.cs
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
using System.Collections.Generic; | ||
|
||
namespace OrchardCore.Json.Dynamic; | ||
public static class JsonDynamicConfigurations | ||
{ | ||
public static HashSet<IJsonDynamicValueHandler> ValueHandlers { get; } = [new DefaultJsonDyanmicValueHandler()]; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,6 +4,8 @@ | |
using System.Reflection; | ||
using System.Text.Json.Nodes; | ||
using System.Text.Json.Settings; | ||
using Json.More; | ||
using OrchardCore.Json.Dynamic; | ||
|
||
#nullable enable | ||
|
||
|
@@ -52,7 +54,6 @@ public override bool TryGetMember(GetMemberBinder binder, out object? result) | |
result = "{null}"; | ||
return true; | ||
} | ||
|
||
result = GetValue(binder.Name); | ||
return true; | ||
} | ||
|
@@ -80,6 +81,7 @@ public bool Remove(string key) | |
|
||
public object? GetValue(string key) | ||
{ | ||
|
||
if (_dictionary.TryGetValue(key, out var value)) | ||
{ | ||
return value; | ||
|
@@ -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 commentThe reason will be displayed to describe this comment to others. Learn more. Added a static collection to handle dynamic values for custom development environments |
||
{ | ||
if (handler.GetValue(_jsonObject, _dictionary, key, jsonNode)) | ||
{ | ||
return _dictionary[key]; | ||
} | ||
} | ||
|
||
if (jsonNode is JsonObject jsonObject) | ||
{ | ||
return _dictionary[key] = new JsonDynamicObject(jsonObject); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,7 @@ | ||
using System.Linq; | ||
using Microsoft.Extensions.DependencyInjection; | ||
using OrchardCore.Json; | ||
using OrchardCore.Json.Dynamic; | ||
|
||
namespace System.Text.Json.Serialization; | ||
|
||
|
@@ -21,4 +23,19 @@ public static IServiceCollection AddJsonDerivedTypeInfo<TDerived, TBase>(this IS | |
|
||
derivedTypes.Add(new JsonDerivedTypeInfo<TDerived, TBase>()); | ||
}); | ||
|
||
/// <summary> | ||
/// Add additional dynamic object fetching logic. | ||
/// </summary> | ||
/// <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 commentThe reason will be displayed to describe this comment to others. Learn more. Custom fetch logic can be added here |
||
{ | ||
if (JsonDynamicConfigurations.ValueHandlers.Any(x => x.GetType() != typeof(T))) | ||
{ | ||
JsonDynamicConfigurations.ValueHandlers.Add(new T()); | ||
} | ||
return services; | ||
} | ||
} |
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