public static IViewModelSerializationMapper Map(this IViewModelSerializationMapper mapper, Type type, Action <ViewModelSerializationMap> action) { var map = mapper.GetMap(type); action(map); map.ResetFunctions(); return(mapper); }
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); } }
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); }
private ViewModelSerializationMap GetSerializationMapForType(Type type) { return(viewModelSerializationMapper.GetMap(type)); }
/// <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 }); } } } }