@@ -21,6 +21,14 @@ public class NestedContentValueConnector : IValueConnector
21
21
private readonly Lazy < ValueConnectorCollection > _valueConnectorsLazy ;
22
22
private readonly ILogger _logger ;
23
23
24
+ // Our.Umbraco.NestedContent is the original NestedContent package
25
+ // Umbraco.NestedContent is Core NestedContent (introduced in v7.7)
26
+ public virtual IEnumerable < string > PropertyEditorAliases => new [ ] { "Our.Umbraco.NestedContent" , "Umbraco.NestedContent" } ;
27
+
28
+ // cannot inject ValueConnectorCollection else of course it creates a circular (recursive) dependency,
29
+ // so we have to inject it lazily and use the lazy value when actually needing it
30
+ private ValueConnectorCollection ValueConnectors => _valueConnectorsLazy . Value ;
31
+
24
32
public NestedContentValueConnector ( IContentTypeService contentTypeService , Lazy < ValueConnectorCollection > valueConnectors , ILogger logger )
25
33
{
26
34
if ( contentTypeService == null ) throw new ArgumentNullException ( nameof ( contentTypeService ) ) ;
@@ -31,8 +39,6 @@ public NestedContentValueConnector(IContentTypeService contentTypeService, Lazy<
31
39
_logger = logger ;
32
40
}
33
41
34
- // Our.Umbraco.NestedContent is the original NestedContent package
35
- // Umbraco.NestedContent is Core NestedContent (introduced in v7.7)
36
42
public string ToArtifact ( object value , PropertyType propertyType , ICollection < ArtifactDependency > dependencies )
37
43
{
38
44
var svalue = value as string ;
@@ -44,9 +50,13 @@ public string ToArtifact(object value, PropertyType propertyType, ICollection<Ar
44
50
45
51
var nestedContent = new List < NestedContentValue > ( ) ;
46
52
if ( svalue . Trim ( ) . StartsWith ( "{" ) )
53
+ {
47
54
nestedContent . Add ( JsonConvert . DeserializeObject < NestedContentValue > ( svalue ) ) ;
55
+ }
48
56
else
57
+ {
49
58
nestedContent . AddRange ( JsonConvert . DeserializeObject < NestedContentValue [ ] > ( svalue ) ) ;
59
+ }
50
60
51
61
if ( nestedContent . All ( x => x == null ) )
52
62
return null ;
@@ -86,13 +96,11 @@ public string ToArtifact(object value, PropertyType propertyType, ICollection<Ar
86
96
continue ;
87
97
}
88
98
99
+ // fetch the right value connector from the collection of connectors, intended for use with this property type.
89
100
// throws if not found - no need for a null check
90
101
var propValueConnector = ValueConnectors . Get ( propType ) ;
91
102
92
- // this should be enough for all other value connectors to work with
93
- // as all they should need is the value, and the property type infos
94
- //var mockProperty = new Property(propType);
95
- //var mockProperty = new Property(propType, row.PropertyValues[key]);
103
+ // pass the value, property type and the dependencies collection to the connector to get a "artifact" value
96
104
var val = row . PropertyValues [ key ] ;
97
105
object parsedValue = propValueConnector . ToArtifact ( val , propType , dependencies ) ;
98
106
@@ -145,25 +153,10 @@ public object FromArtifact(string value, PropertyType propertyType, object curre
145
153
throw new InvalidOperationException ( $ "Could not resolve these content types for the Nested Content property: { string . Join ( "," , allContentTypes . Where ( x => x . Value == null ) . Select ( x => x . Key ) ) } ") ;
146
154
}
147
155
148
- var mocks = new Dictionary < IContentType , IContent > ( ) ;
149
-
150
156
foreach ( var row in nestedContent )
151
157
{
152
158
var contentType = allContentTypes [ row . ContentTypeAlias ] ;
153
159
154
- // note
155
- // the way we do it here, doing content.SetValue() several time on the same content, reduces
156
- // allocations and should be ok because SetValue does not care about the previous value - would
157
- // be different for the overloads that manage eg files for uploads (not sure how NestedContent
158
- // deals with them really)
159
-
160
- // we need a fake content instance to pass in to the value connector, since the value connector
161
- // wants to SetValue on an object - then we can extract the value back from that object to set
162
- // it correctly on the real instance
163
- IContent mockContent ;
164
- if ( ! mocks . TryGetValue ( contentType , out mockContent ) )
165
- mockContent = mocks [ contentType ] = new Content ( "NC_" + Guid . NewGuid ( ) , - 1 , contentType ) ;
166
-
167
160
foreach ( var key in row . PropertyValues . Keys . ToArray ( ) )
168
161
{
169
162
// key is a system property that is added by NestedContent in Core v7.7
@@ -179,13 +172,15 @@ public object FromArtifact(string value, PropertyType propertyType, object curre
179
172
continue ;
180
173
}
181
174
175
+ // fetch the right value connector from the collection of connectors, intended for use with this property type.
182
176
// throws if not found - no need for a null check
183
177
var propValueConnector = ValueConnectors . Get ( innerPropertyType ) ;
184
178
185
179
var rowValue = row . PropertyValues [ key ] ;
186
180
187
181
if ( rowValue != null )
188
182
{
183
+ // pass the artifact value and property type to the connector to get a real value from the artifact
189
184
var convertedValue = propValueConnector . FromArtifact ( rowValue . ToString ( ) , innerPropertyType , null ) ;
190
185
if ( convertedValue == null )
191
186
{
@@ -200,7 +195,7 @@ public object FromArtifact(string value, PropertyType propertyType, object curre
200
195
{
201
196
// test if the value is a json object (thus could be a nested complex editor)
202
197
// if that's the case we'll need to add it as a json object instead of string to avoid it being escaped
203
- JToken jtokenValue = convertedValue . ToString ( ) . DetectIsJson ( ) ? JToken . Parse ( convertedValue . ToString ( ) ) : null ;
198
+ var jtokenValue = convertedValue . ToString ( ) . DetectIsJson ( ) ? JToken . Parse ( convertedValue . ToString ( ) ) : null ;
204
199
if ( jtokenValue != null )
205
200
{
206
201
row . PropertyValues [ key ] = jtokenValue ;
@@ -223,12 +218,6 @@ public object FromArtifact(string value, PropertyType propertyType, object curre
223
218
return value ;
224
219
}
225
220
226
- public virtual IEnumerable < string > PropertyEditorAliases => new [ ] { "Our.Umbraco.NestedContent" , "Umbraco.NestedContent" } ;
227
-
228
- // cannot inject ValueConnectorCollection else of course it creates a circular (recursive) dependency,
229
- // so we have to inject it lazily and use the lazy value when actually needing it
230
- private ValueConnectorCollection ValueConnectors => _valueConnectorsLazy . Value ;
231
-
232
221
/// <summary>
233
222
/// The typed value stored for Nested Content
234
223
/// </summary>
@@ -249,13 +238,6 @@ public class NestedContentValue
249
238
[ JsonProperty ( "ncContentTypeAlias" ) ]
250
239
public string ContentTypeAlias { get ; set ; }
251
240
252
- // starting with v7.7, Core's NestedContent implement "key" as a system property
253
- // but since we are supporting pre-v7.7 including the NestedContent package, we
254
- // cannot do it this way - it's all managed "manually" when dealing with
255
- // PropertyValues.
256
- //[JsonProperty("key")]
257
- //public Guid Key { get; set; }
258
-
259
241
/// <summary>
260
242
/// The remaining properties will be serialized to a dictionary
261
243
/// </summary>
0 commit comments