@@ -19,6 +19,7 @@ namespace GeneXus.Utils
1919 using System . Xml . Serialization ;
2020 using GeneXus . Application ;
2121 using GeneXus . Configuration ;
22+ using GeneXus . Data ;
2223 using GeneXus . Http ;
2324 using GeneXus . Metadata ;
2425 using GeneXus . XML ;
@@ -1044,8 +1045,8 @@ public string Name
10441045 public class GxUserType : IGxXMLSerializable , ICloneable , IGxJSONAble , IGxJSONSerializable , IGXAssigned
10451046 {
10461047 static readonly IGXLogger log = GXLoggerFactory . GetLogger < GxUserType > ( ) ;
1047- protected GXProperties dirties = new GXProperties ( ) ;
1048-
1048+ protected ConcurrentDictionary < string , byte > dirties = new ConcurrentDictionary < string , byte > ( StringComparer . OrdinalIgnoreCase ) ;
1049+ private const string PROPERTY_PREFIX = "gxtpr_" ;
10491050 static object setupChannelObject = null ;
10501051 static bool setupChannelInitialized ;
10511052 [ XmlIgnore ]
@@ -1103,11 +1104,11 @@ public GxUserType()
11031104
11041105 public virtual void SetDirty ( string fieldName )
11051106 {
1106- dirties [ fieldName . ToLower ( ) ] = "true" ;
1107+ dirties [ fieldName ] = 1 ;
11071108 }
11081109 public virtual bool IsDirty ( string fieldName )
11091110 {
1110- if ( dirties . ContainsKey ( fieldName . ToLower ( ) ) )
1111+ if ( dirties . ContainsKey ( fieldName ) )
11111112 return true ;
11121113 return false ;
11131114 }
@@ -1605,24 +1606,27 @@ public Object GetJSONObject()
16051606
16061607 private ICollection getFromJSONObjectOrderIterator ( ICollection it )
16071608 {
1608- List < string > v = new List < string > ( ) ;
1609+ if ( GxUploadAttrs . IsEmpty && ! typeof ( GxSilentTrnSdt ) . IsAssignableFrom ( this . GetType ( ) ) )
1610+ {
1611+ return it ;
1612+ }
1613+ List < string > _JsonObjectOrderIterator = new List < string > ( ) ;
1614+
16091615 List < string > vAtEnd = new List < string > ( ) ;
16101616 foreach ( string name in it )
16111617 {
1612- string map = JsonMap ( name ) ;
1613- PropertyInfo objProperty = GetTypeProperty ( "gxtpr_" + ( ! string . IsNullOrEmpty ( map ) ? map : name ) . ToLower ( ) ) ;
1614- if ( name . EndsWith ( "_N" ) || objProperty != null && IsGxUploadAttribute ( objProperty ) )
1618+ if ( name . EndsWith ( "_N" ) || IsGxUploadAttribute ( name ) )
16151619 {
16161620 vAtEnd . Add ( name ) ;
16171621 }
16181622 else
16191623 {
1620- v . Add ( name ) ; //keep the order of attributes that do not end with _N.
1624+ _JsonObjectOrderIterator . Add ( name ) ; //keep the order of attributes that do not end with _N.
16211625 }
16221626 }
16231627 if ( vAtEnd . Count > 0 )
1624- v . AddRange ( vAtEnd ) ;
1625- return v ;
1628+ _JsonObjectOrderIterator . AddRange ( vAtEnd ) ;
1629+ return _JsonObjectOrderIterator ;
16261630 }
16271631
16281632 public void FromJSONObject ( dynamic obj )
@@ -1635,9 +1639,7 @@ public void FromJSONObject(dynamic obj)
16351639 foreach ( string name in jsonIterator )
16361640 {
16371641 object currObj = jobj [ name ] ;
1638- string map = JsonMap ( name ) ;
1639- PropertyInfo objProperty = GetTypeProperty ( "gxtpr_" + ( map != null ? map : name ) . ToLower ( ) ) ;
1640-
1642+ PropertyInfo objProperty = GetTypeProperty ( JsonNameToInternalName ( name ) ) ;
16411643 if ( objProperty != null )
16421644 {
16431645 if ( ! JSONHelper . IsJsonNull ( currObj ) )
@@ -1897,32 +1899,51 @@ private bool TryConvertValueToProperty(object Value, PropertyInfo property, out
18971899 return success ;
18981900 }
18991901
1900- [ System . Diagnostics . CodeAnalysis . SuppressMessage ( "GxFxCopRules" , "CR1000:EnforceThreadSafeType" ) ]
1901- private Dictionary < string , bool > gxuploadAttrs = new Dictionary< string , bool > ( ) ;
1902- private bool IsGxUploadAttribute ( PropertyInfo property )
1902+ private GXTypeInfo _compatibilityGxuploadAttrs = null ;
1903+ private bool IsGxUploadAttribute ( string jsonPropertyName )
19031904 {
1904- string key = property . Name ;
1905- if ( ! gxuploadAttrs . ContainsKey ( key ) )
1906- {
1907- bool hasAtt = property . IsDefined ( typeof ( GxUpload ) , false ) ;
1908- gxuploadAttrs . Add ( key , hasAtt ) ;
1909- }
1910- return gxuploadAttrs [ key ] ;
1905+ return GxUploadAttrs . ContainsKey ( JsonNameToInternalName ( jsonPropertyName ) ) ;
19111906 }
1912-
1913- private Hashtable props ;
1914-
1915- private PropertyInfo GetTypeProperty ( string propName )
1907+ private bool IsGxUploadAttribute ( PropertyInfo propertyInfo )
1908+ {
1909+ return GxUploadAttrs . ContainsKey ( propertyInfo . Name ) ;
1910+ }
1911+ private string JsonNameToInternalName ( string jsonPropertyName )
1912+ {
1913+ string map = JsonMap ( jsonPropertyName ) ;
1914+ if ( ! string . IsNullOrEmpty ( map ) )
1915+ return $ "{ PROPERTY_PREFIX } { map } ";
1916+ else
1917+ return $ "{ PROPERTY_PREFIX } { jsonPropertyName } ";
1918+ }
1919+ protected virtual GXTypeInfo TypeInfo { get { return _compatibilityGxuploadAttrs ; } set { _compatibilityGxuploadAttrs = value ; } }
1920+ private ConcurrentDictionary < string , byte > GxUploadAttrs
19161921 {
1917- if ( props == null )
1922+ get
19181923 {
1919- props = new Hashtable ( ) ;
1920- foreach ( PropertyInfo prop in this . GetType ( ) . GetProperties ( ) )
1924+ if ( TypeInfo == null )
19211925 {
1922- props . Add ( prop . Name . ToLower ( ) , prop ) ;
1926+ TypeInfo = new GXTypeInfo ( ) ;
1927+
1928+ TypeInfo . UploadAttrs = new ConcurrentDictionary < string , byte > ( StringComparer . OrdinalIgnoreCase ) ;
1929+ foreach ( PropertyInfo property in this . GetType ( ) . GetProperties ( BindingFlags . Public | BindingFlags . Instance ) )
1930+ {
1931+ if ( property . Name . StartsWith ( PROPERTY_PREFIX , StringComparison . OrdinalIgnoreCase ) )
1932+ {
1933+ bool hasAtt = property . IsDefined ( typeof ( GxUpload ) , false ) ;
1934+ if ( hasAtt )
1935+ {
1936+ TypeInfo . UploadAttrs . TryAdd ( property . Name , 1 ) ;
1937+ }
1938+ }
1939+ }
19231940 }
1941+ return TypeInfo . UploadAttrs ;
19241942 }
1925- return ( PropertyInfo ) props [ propName ] ;
1943+ }
1944+ private PropertyInfo GetTypeProperty ( string propName )
1945+ {
1946+ return this . GetType ( ) . GetProperty ( propName , BindingFlags . IgnoreCase | BindingFlags . Public | BindingFlags . Instance ) ;
19261947 }
19271948
19281949 private Hashtable methods ;
@@ -2004,7 +2025,10 @@ public void SetPropertyValue(string propertyName, object propertyValue)
20042025 GetType ( ) . GetProperty ( $ "gxTpr_{ propertyName } ") . SetValue ( this , propertyValue ) ;
20052026 }
20062027 }
2007-
2028+ public class GXTypeInfo
2029+ {
2030+ public ConcurrentDictionary < string , byte > UploadAttrs { get ; set ; }
2031+ }
20082032 public interface IGxJSONAble
20092033 {
20102034 void AddObjectProperty ( string name , object prop ) ;
0 commit comments