コード例 #1
0
 private static object Deserialize(JsonSerializer serializer, JToken jtoken, ViewModelPropertyMap property, object existingValue)
 {
     if (property.JsonConverter != null && property.JsonConverter.CanRead && property.JsonConverter.CanConvert(property.Type))
     {
         return(property.JsonConverter.ReadJson(jtoken.CreateReader(), property.Type, existingValue, serializer));
     }
     else if (existingValue != null && property.Populate)
     {
         if (jtoken.Type == JTokenType.Null)
         {
             return(null);
         }
         else if (jtoken.Type == JTokenType.Object)
         {
             serializer.Converters.OfType <ViewModelJsonConverter>().First().Populate((JObject)jtoken, serializer, existingValue);
             return(existingValue);
         }
         else
         {
             serializer.Populate(jtoken.CreateReader(), existingValue);
             return(existingValue);
         }
     }
     else
     {
         if (property.Type.GetTypeInfo().IsValueType&& jtoken.Type == JTokenType.Null)
         {
             return(Activator.CreateInstance(property.Type));
         }
         else
         {
             return(serializer.Deserialize(jtoken.CreateReader(), property.Type));
         }
     }
 }
コード例 #2
0
        private void GenerateOptionsBlock(IList <Expression> block, ViewModelPropertyMap property, Dictionary <string, object> options, ParameterExpression writer)
        {
            block.Add(ExpressionUtils.Replace <JsonWriter>(w => w.WritePropertyName(property.Name + "$options"), writer));
            block.Add(ExpressionUtils.Replace <JsonWriter>(w => w.WriteStartObject(), writer));
            foreach (var option in options)
            {
                block.Add(ExpressionUtils.Replace <JsonWriter>(w => w.WritePropertyName(option.Key), writer));
                switch (option.Key)
                {
                case CLIENT_EXTENDERS_KEY:
                {
                    // declare 'clientExtenders' as the array of objects
                    block.Add(ExpressionUtils.Replace <JsonWriter>(w => w.WriteStartArray(), writer));
                    foreach (var extender in property.ClientExtenders)
                    {
                        block.Add(ExpressionUtils.Replace <JsonWriter>(w => w.WriteStartObject(), writer));
                        block.Add(ExpressionUtils.Replace <JsonWriter>(w => w.WritePropertyName("name"), writer));
                        block.Add(ExpressionUtils.Replace <JsonWriter>(w => w.WriteValue(extender.Name), writer));
                        block.Add(ExpressionUtils.Replace <JsonWriter>(w => w.WritePropertyName("parameter"), writer));
                        block.Add(ExpressionUtils.Replace <JsonWriter>(w => w.WriteValue(extender.Parameter), writer));
                        block.Add(ExpressionUtils.Replace <JsonWriter>(w => w.WriteEndObject(), writer));
                    }
                    block.Add(ExpressionUtils.Replace <JsonWriter>(w => w.WriteEndArray(), writer));
                    break;
                }

                default:
                    // legacy code - direct { property : value }
                    block.Add(ExpressionUtils.Replace <JsonWriter>(w => w.WriteValue(option.Value), writer));
                    break;
                }
            }
            block.Add(ExpressionUtils.Replace <JsonWriter>(w => w.WriteEndObject(), writer));
        }
コード例 #3
0
        /// <summary>
        /// Gets the properties of the specified type.
        /// </summary>
        protected virtual IEnumerable <ViewModelPropertyMap> GetProperties(Type type)
        {
            foreach (var property in type.GetProperties(BindingFlags.Public | BindingFlags.Instance).OrderBy(p => p.Name))
            {
                if (property.GetCustomAttribute <JsonIgnoreAttribute>() != null)
                {
                    continue;
                }

                var propertyMap = new ViewModelPropertyMap()
                {
                    PropertyInfo          = property,
                    Name                  = property.Name,
                    ViewModelProtection   = ProtectMode.None,
                    Type                  = property.PropertyType,
                    TransferAfterPostback = property.GetMethod != null && property.GetMethod.IsPublic,
                    TransferFirstRequest  = property.GetMethod != null && property.GetMethod.IsPublic,
                    TransferToServer      = property.SetMethod != null && property.SetMethod.IsPublic,
                    JsonConverter         = GetJsonConverter(property),
                    Populate              = ViewModelJsonConverter.IsComplexType(property.PropertyType) && !ViewModelJsonConverter.IsEnumerable(property.PropertyType) && property.GetMethod != null
                };

                foreach (ISerializationInfoAttribute attr in property.GetCustomAttributes().OfType <ISerializationInfoAttribute>())
                {
                    attr.SetOptions(propertyMap);
                }

                var bindAttribute = property.GetCustomAttribute <BindAttribute>();
                if (bindAttribute != null)
                {
                    propertyMap.Bind(bindAttribute.Direction);
                    if (bindAttribute.Name != null)
                    {
                        propertyMap.Name = bindAttribute.Name;
                    }
                }

                var viewModelProtectionAttribute = property.GetCustomAttribute <ProtectAttribute>();
                if (viewModelProtectionAttribute != null)
                {
                    propertyMap.ViewModelProtection = viewModelProtectionAttribute.Settings;
                }

                propertyMap.ClientExtenders =
                    property.GetCustomAttributes <ClientExtenderAttribute>()
                    .OrderBy(c => c.Order)
                    .Select(extender => new ClientExtenderInfo()
                {
                    Name = extender.Name, Parameter = extender.Parameter
                })
                    .ToList();

                var validationAttributes = validationMetadataProvider.GetAttributesForProperty(property);
                propertyMap.ValidationRules = validationRuleTranslator.TranslateValidationRules(property, validationAttributes).ToList();

                propertyMap.ValidateSettings();

                yield return(propertyMap);
            }
        }
コード例 #4
0
        public static ViewModelPropertyMap Bind(this ViewModelPropertyMap property, Direction direction)
        {
            property.TransferAfterPostback      = direction.HasFlag(Direction.ServerToClientPostback);
            property.TransferFirstRequest       = direction.HasFlag(Direction.ServerToClientFirstRequest);
            property.TransferToServer           = direction.HasFlag(Direction.ClientToServerNotInPostbackPath) || direction.HasFlag(Direction.ClientToServerInPostbackPath);
            property.TransferToServerOnlyInPath = !direction.HasFlag(Direction.ClientToServerNotInPostbackPath) && property.TransferToServer;

            return(property);
        }
コード例 #5
0
        /// <summary>
        /// Gets the properties of the specified type.
        /// </summary>
        protected virtual IEnumerable <ViewModelPropertyMap> GetProperties(Type type)
        {
            foreach (var property in type.GetProperties(BindingFlags.Public | BindingFlags.Instance).OrderBy(p => p.Name))
            {
                if (property.GetCustomAttribute <JsonIgnoreAttribute>() != null)
                {
                    continue;
                }

                var propertyMap = new ViewModelPropertyMap()
                {
                    PropertyInfo          = property,
                    Name                  = property.Name,
                    ViewModelProtection   = ProtectMode.None,
                    Type                  = property.PropertyType,
                    TransferAfterPostback = property.GetMethod != null && property.GetMethod.IsPublic,
                    TransferFirstRequest  = property.GetMethod != null && property.GetMethod.IsPublic,
                    TransferToServer      = property.SetMethod != null && property.SetMethod.IsPublic,
                    JsonConverter         = GetJsonConverter(property),
                    Populate              = ViewModelJsonConverter.IsComplexType(property.PropertyType) && !ViewModelJsonConverter.IsEnumerable(property.PropertyType) && property.GetMethod != null
                };

                var bindAttribute = property.GetCustomAttribute <BindAttribute>();
                if (bindAttribute != null)
                {
                    propertyMap.TransferAfterPostback      = bindAttribute.Direction.HasFlag(Direction.ServerToClientPostback);
                    propertyMap.TransferFirstRequest       = bindAttribute.Direction.HasFlag(Direction.ServerToClientFirstRequest);
                    propertyMap.TransferToServer           = bindAttribute.Direction.HasFlag(Direction.ClientToServerNotInPostbackPath) || bindAttribute.Direction.HasFlag(Direction.ClientToServerInPostbackPath);
                    propertyMap.TransferToServerOnlyInPath = !bindAttribute.Direction.HasFlag(Direction.ClientToServerNotInPostbackPath) && propertyMap.TransferToServer;
                }

                var viewModelProtectionAttribute = property.GetCustomAttribute <ProtectAttribute>();
                if (viewModelProtectionAttribute != null)
                {
                    propertyMap.ViewModelProtection = viewModelProtectionAttribute.Settings;
                }

                var clientExtenderList = property.GetCustomAttributes <ClientExtenderAttribute>();
                if (clientExtenderList.Any())
                {
                    clientExtenderList
                    .OrderBy(c => c.Order)
                    .ToList()
                    .ForEach(extender => propertyMap.ClientExtenders.Add(new ClientExtenderInfo()
                    {
                        Name = extender.Name, Parameter = extender.Parameter
                    }));
                }

                var validationAttributes = validationMetadataProvider.GetAttributesForProperty(property);
                propertyMap.ValidationRules = validationRuleTranslator.TranslateValidationRules(property, validationAttributes).ToList();

                yield return(propertyMap);
            }
        }
コード例 #6
0
 private static void Serialize(JsonSerializer serializer, JsonWriter writer, ViewModelPropertyMap property, object value)
 {
     if (property.JsonConverter != null && property.JsonConverter.CanWrite && property.JsonConverter.CanConvert(property.Type))
     {
         property.JsonConverter.WriteJson(writer, value, serializer);
     }
     else
     {
         serializer.Serialize(writer, value);
     }
 }
コード例 #7
0
        /// <summary>
        /// Gets the properties of the specified type.
        /// </summary>
        protected virtual IEnumerable<ViewModelPropertyMap> GetProperties(Type type)
        {
            foreach (var property in type.GetProperties(BindingFlags.Public | BindingFlags.Instance).OrderBy(p => p.Name))
            {
                if (property.GetCustomAttribute<JsonIgnoreAttribute>() != null) continue;

                var propertyMap = new ViewModelPropertyMap()
                {
                    PropertyInfo = property,
                    Name = property.Name,
                    ViewModelProtection = ProtectMode.None,
                    Type = property.PropertyType,
                    TransferAfterPostback = property.GetMethod != null && property.GetMethod.IsPublic,
                    TransferFirstRequest = property.GetMethod != null && property.GetMethod.IsPublic,
                    TransferToServer = property.SetMethod != null && property.SetMethod.IsPublic,
                    JsonConverter = GetJsonConverter(property),
                    Populate = ViewModelJsonConverter.IsComplexType(property.PropertyType) && !ViewModelJsonConverter.IsEnumerable(property.PropertyType) && property.GetMethod != null
                };

                var bindAttribute = property.GetCustomAttribute<BindAttribute>();
                if (bindAttribute != null)
                {
                    propertyMap.TransferAfterPostback = bindAttribute.Direction.HasFlag(Direction.ServerToClientPostback);
                    propertyMap.TransferFirstRequest = bindAttribute.Direction.HasFlag(Direction.ServerToClientFirstRequest);
                    propertyMap.TransferToServer = bindAttribute.Direction.HasFlag(Direction.ClientToServerNotInPostbackPath) || bindAttribute.Direction.HasFlag(Direction.ClientToServerInPostbackPath);
                    propertyMap.TransferToServerOnlyInPath = !bindAttribute.Direction.HasFlag(Direction.ClientToServerNotInPostbackPath) && propertyMap.TransferToServer;
                }

                var viewModelProtectionAttribute = property.GetCustomAttribute<ProtectAttribute>();
                if (viewModelProtectionAttribute != null)
                {
                    propertyMap.ViewModelProtection = viewModelProtectionAttribute.Settings;
                }

                var clientExtenderList = property.GetCustomAttributes<ClientExtenderAttribute>();
                if (clientExtenderList.Any())
                {
                    clientExtenderList
                        .OrderBy(c => c.Order)
                        .ToList()
                        .ForEach(extender => propertyMap.ClientExtenders.Add(new ClientExtenderInfo() { Name = extender.Name, Parameter = extender.Parameter }));
                }

                var validationAttributes = validationMetadataProvider.GetAttributesForProperty(property);
                propertyMap.ValidationRules = validationRuleTranslator.TranslateValidationRules(property, validationAttributes).ToList();

                yield return propertyMap;
            }
        }
コード例 #8
0
 private static Expression GetSerializeExpression(ViewModelPropertyMap property, Expression jsonWriter, Expression value, Expression serializer)
 {
     if (property.JsonConverter?.CanWrite == true)
     {
         // maybe use the converter. It can't be easily inlined because polymorpism
         return(ExpressionUtils.Replace((JsonSerializer s, JsonWriter w, object v) => Serialize(s, w, property, v), serializer, jsonWriter, Expression.Convert(value, typeof(object))));
     }
     else if (writeValueMethods.TryGetValue(value.Type, out var method))
     {
         return(Expression.Call(jsonWriter, method, new [] { value }));
     }
     else
     {
         return(Expression.Call(serializer, "Serialize", Type.EmptyTypes, new [] { jsonWriter, Expression.Convert(value, typeof(object)) }));
     }
 }
コード例 #9
0
 private void AddTypeOptions(Dictionary <string, object> options, ViewModelPropertyMap property)
 {
     if (property.TransferToClient || property.TransferToServer)
     {
         if ((property.Type == typeof(DateTime) || property.Type == typeof(DateTime?)) && property.JsonConverter == null) // TODO: allow customization using attributes
         {
             options["isDate"] = true;
         }
         else if (property.Type.IsNumericType())
         {
             options["type"] = property.Type.Name.ToLower();
         }
         else if (Nullable.GetUnderlyingType(property.Type)?.IsNumericType() == true)
         {
             options["type"] = Nullable.GetUnderlyingType(property.Type).Name.ToLower() + "?";
         }
     }
 }
コード例 #10
0
 private static object Deserialize(JsonSerializer serializer, JToken jtoken, ViewModelPropertyMap property, object existingValue)
 {
     if (property.JsonConverter != null && property.JsonConverter.CanRead && property.JsonConverter.CanConvert(property.Type))
     {
         return property.JsonConverter.ReadJson(jtoken.CreateReader(), property.Type, existingValue, serializer);
     }
     else if (existingValue != null && property.Populate)
     {
         if (jtoken.Type == JTokenType.Null)
             return null;
         else if (jtoken.Type == JTokenType.Object)
         {
             serializer.Converters.OfType<ViewModelJsonConverter>().First().Populate((JObject)jtoken, serializer, existingValue);
             return existingValue;
         }
         else
         {
             serializer.Populate(jtoken.CreateReader(), existingValue);
             return existingValue;
         }
     }
     else
     {
         return serializer.Deserialize(jtoken.CreateReader(), property.Type);
     }
 }
コード例 #11
0
 public static void Ignore(this ViewModelPropertyMap property)
 {
     property.Bind(Direction.None);
     property.ValidationRules.Clear();
     property.ClientExtenders.Clear();
 }
コード例 #12
0
 public static ViewModelPropertyMap Protect(this ViewModelPropertyMap property, ProtectMode protectMode)
 {
     property.ViewModelProtection = protectMode;
     return(property);
 }
コード例 #13
0
 public static ViewModelPropertyMap AddClientExtender(this ViewModelPropertyMap property, ClientExtenderInfo clientExtender)
 {
     property.ClientExtenders.Add(clientExtender);
     return(property);
 }
コード例 #14
0
 public static ViewModelPropertyMap SetJsonConverter(this ViewModelPropertyMap property, JsonConverter converter)
 {
     property.JsonConverter = converter;
     return(property);
 }
コード例 #15
0
 public DotvvmPropertySerializationException(string message, Exception innerException, ViewModelPropertyMap serializedProperty)
     : base(message, innerException)
 {
     SerializedProperty = serializedProperty;
 }
コード例 #16
0
 private static void Serialize(JsonSerializer serializer, JsonWriter writer, ViewModelPropertyMap property, object value)
 {
     if (property.JsonConverter != null && property.JsonConverter.CanWrite && property.JsonConverter.CanConvert(property.Type))
     {
         property.JsonConverter.WriteJson(writer, value, serializer);
     }
     else
     {
         serializer.Serialize(writer, value);
     }
 }
コード例 #17
0
        private void GenerateOptionsBlock(IList<Expression> block,  ViewModelPropertyMap property, Dictionary<string, object> options, ParameterExpression writer)
        {
            block.Add(ExpressionUtils.Replace<JsonWriter>(w => w.WritePropertyName(property.Name + "$options"), writer));
            block.Add(ExpressionUtils.Replace<JsonWriter>(w => w.WriteStartObject(), writer));
            foreach (var option in options)
            {
                block.Add(ExpressionUtils.Replace<JsonWriter>(w => w.WritePropertyName(option.Key), writer));
                switch (option.Key)
                {
                    case CLIENT_EXTENDERS_KEY:
                    {
                        // declare 'clientExtenders' as the array of objects
                        block.Add(ExpressionUtils.Replace<JsonWriter>(w => w.WriteStartArray(), writer));
                        foreach (var extender in property.ClientExtenders)
                        {
                            block.Add(ExpressionUtils.Replace<JsonWriter>(w => w.WriteStartObject(), writer));
                            block.Add(ExpressionUtils.Replace<JsonWriter>(w => w.WritePropertyName("name"), writer));
                            block.Add(ExpressionUtils.Replace<JsonWriter>(w => w.WriteValue(extender.Name), writer));
                            block.Add(ExpressionUtils.Replace<JsonWriter>(w => w.WritePropertyName("parameter"), writer));
                            block.Add(ExpressionUtils.Replace<JsonWriter>(w => w.WriteValue(extender.Parameter), writer));
                            block.Add(ExpressionUtils.Replace<JsonWriter>(w => w.WriteEndObject(), writer));

                        }
                        block.Add(ExpressionUtils.Replace<JsonWriter>(w => w.WriteEndArray(), writer));
                        break;
                    }
                    default:
                        // legacy code - direct { property : value }
                        block.Add(ExpressionUtils.Replace<JsonWriter>(w => w.WriteValue(option.Value), writer));
                        break;
                }
            }
            block.Add(ExpressionUtils.Replace<JsonWriter>(w => w.WriteEndObject(), writer));

        }