Ejemplo n.º 1
0
        public static IViewModelSerializationMapper Map(this IViewModelSerializationMapper mapper, Type type, Action <ViewModelSerializationMap> action)
        {
            var map = mapper.GetMap(type);

            action(map);
            map.ResetFunctions();
            return(mapper);
        }
Ejemplo n.º 2
0
        protected override void DefaultVisit(JsNode node)
        {
            base.DefaultVisit(node);

            if (node.Annotation <VMPropertyInfoAnnotation>() is VMPropertyInfoAnnotation propAnnotation)
            {
                var target = node.GetChildByRole(JsTreeRoles.TargetExpression);
                if (target.HasAnnotation <ObservableUnwrapInvocationAnnotation>())
                {
                    target = target.GetChildByRole(JsTreeRoles.TargetExpression);
                }
                else if (target.HasAnnotation <ObservableSetterInvocationAnnotation>())
                {
                    throw new NotImplementedException();
                }

                var propertyType        = propAnnotation.MemberInfo.GetResultType();
                var containsObservables = true;
                if (propAnnotation.SerializationMap == null && target?.Annotation <ViewModelInfoAnnotation>() is ViewModelInfoAnnotation targetAnnotation)
                {
                    propAnnotation.SerializationMap = targetAnnotation.SerializationMap.Properties.FirstOrDefault(p => p.PropertyInfo == propAnnotation.MemberInfo);
                    containsObservables             = targetAnnotation.ContainsObservables;
                }
                if (propAnnotation.SerializationMap is ViewModelPropertyMap propertyMap)
                {
                    if (propertyMap.ViewModelProtection == ViewModel.ProtectMode.EncryptData)
                    {
                        throw new Exception($"Property {propAnnotation.MemberInfo.Name} is encrypted and cannot be used in JS.");
                    }
                    if (node is JsMemberAccessExpression memberAccess && propertyMap.Name != memberAccess.MemberName)
                    {
                        memberAccess.MemberName = propertyMap.Name;
                    }
                }
                else if (propAnnotation.MemberInfo is FieldInfo)
                {
                    throw new NotSupportedException($"Can not translate field '{propAnnotation.MemberInfo}' to Javascript");
                }

                if (containsObservables)
                {
                    node.AddAnnotation(ResultIsObservableAnnotation.Instance);

                    if (ViewModelJsonConverter.IsCollection(propertyType))
                    {
                        node.AddAnnotation(ResultIsObservableArrayAnnotation.Instance);
                    }
                }

                node.AddAnnotation(new ViewModelInfoAnnotation(propertyType, containsObservables: containsObservables));
                node.AddAnnotation(MayBeNullAnnotation.Instance);
            }

            if (node.Annotation <ViewModelInfoAnnotation>() is var vmAnnotation && vmAnnotation?.Type != null && vmAnnotation.SerializationMap == null)
            {
                vmAnnotation.SerializationMap = mapper.GetMap(vmAnnotation.Type);
            }
        }
Ejemplo n.º 3
0
        public IReadOnlyDictionary <string, string> GetMapping(Type type)
        {
            if (mappingCache.TryGetValue(type, out var columnsMapping))
            {
                return(columnsMapping);
            }

            var serializationMap = serializationMapper.GetMap(type);

            columnsMapping = new Dictionary <string, string>();
            foreach (var property in serializationMap.Properties)
            {
                var resolvedName = property.Name;
                if (resolvedName == property.PropertyInfo.Name)
                {
                    continue;
                }

                // Store only remapped columns
                columnsMapping.Add(property.PropertyInfo.Name, resolvedName);
            }
            mappingCache.TryAdd(type, columnsMapping);
            return(columnsMapping);
        }
Ejemplo n.º 4
0
 private ViewModelSerializationMap GetSerializationMapForType(Type type)
 {
     return(viewModelSerializationMapper.GetMap(type));
 }
Ejemplo n.º 5
0
        /// <summary>
        /// Validates the view model.
        /// </summary>
        private IEnumerable <ViewModelValidationError> ValidateViewModel(object viewModel, string pathPrefix, HashSet <object> alreadyValidated)
        {
            if (alreadyValidated.Contains(viewModel))
            {
                yield break;
            }

            if (viewModel == null)
            {
                yield break;
            }
            var viewModelType = viewModel.GetType();

            if (ReflectionUtils.IsPrimitiveType(viewModelType) || ReflectionUtils.IsNullableType(viewModelType))
            {
                yield break;
            }

            alreadyValidated.Add(viewModel);

            if (ReflectionUtils.IsEnumerable(viewModelType))
            {
                if (pathPrefix.Length == 0)
                {
                    pathPrefix = "$data";
                }
                else
                {
                    pathPrefix += "()";
                }

                // collections
                var index = 0;
                foreach (var item in (IEnumerable)viewModel)
                {
                    foreach (var error in ValidateViewModel(item, pathPrefix + "[" + index + "]()", alreadyValidated))
                    {
                        yield return(error);
                    }
                    index++;
                }
                yield break;
            }

            // validate all properties on the object
            var map = viewModelSerializationMapper.GetMap(viewModel.GetType());

            foreach (var property in map.Properties.Where(p => p.TransferToServer))
            {
                var value = property.PropertyInfo.GetValue(viewModel);
                var path  = CombinePath(pathPrefix, property.Name);

                // validate the property
                if (property.ValidationRules.Any())
                {
                    var context = new ValidationContext(viewModel, validationItems)
                    {
                        MemberName = property.Name
                    };

                    foreach (var rule in property.ValidationRules)
                    {
                        var propertyResult = rule.SourceValidationAttribute?.GetValidationResult(value, context);
                        if (propertyResult != ValidationResult.Success)
                        {
                            yield return(new ViewModelValidationError()
                            {
                                PropertyPath = path,
                                ErrorMessage = rule.ErrorMessage
                            });
                        }
                    }
                }

                // inspect objects
                if (value != null)
                {
                    if (ReflectionUtils.IsComplexType(property.Type))
                    {
                        // complex objects
                        foreach (var error in ValidateViewModel(value, path, alreadyValidated))
                        {
                            yield return(error);
                        }
                    }
                }
            }

            if (viewModel is IValidatableObject)
            {
                foreach (var error in ((IValidatableObject)viewModel).Validate(
                             new ValidationContext(viewModel, validationItems)))
                {
                    var paths = new List <string>();
                    if (error.MemberNames != null)
                    {
                        foreach (var memberName in error.MemberNames)
                        {
                            paths.Add(CombinePath(pathPrefix, memberName));
                        }
                    }
                    if (!paths.Any())
                    {
                        paths.Add(pathPrefix);
                    }

                    foreach (var memberPath in paths)
                    {
                        yield return(new ViewModelValidationError()
                        {
                            PropertyPath = memberPath,
                            ErrorMessage = error.ErrorMessage
                        });
                    }
                }
            }
        }