public FilterViewModel GetFilterViewModel(string propertyName, PropertyTypeEnum propertyType, int propertyId, JsonDocument filterInfo, JsonDocument constraints, FilterDTO filterDto = null) { Type filterViewType = null; if (_mapper.ContainsId(propertyId)) { filterViewType = _mapper.GetFilterForProperty(propertyId); } else if (_mapper.ContainsType(propertyType)) { filterViewType = _mapper.GetFilterForType(propertyType); } else { return(null); } var filterViewModel = (FilterViewModel)_mapper.GetFilterFactory(filterViewType)(); filterViewModel.PropertyId = propertyId; filterViewModel.PropertyType = propertyType; filterViewModel.PropertyName = propertyName; dynamic filterInfoJObject = JsonConvert.DeserializeObject(filterInfo.ToJsonString()); dynamic constraintsJObject = JsonConvert.DeserializeObject(constraints.ToJsonString()); if (_buildersMap.ContainsKey(filterViewType)) { filterViewModel = _buildersMap[filterViewType] .BuildFilterViewModel(filterViewModel, filterInfoJObject, constraintsJObject, filterDto); } /*else * { * var metadata = _mapper.GetFilterPropertiesMetadata(filterViewType); * foreach (var property in metadata) * { * if(filterInfo.RootElement.TryGetProperty(property.Name, out var p)) * p. * } * }*/ return(filterViewModel); }
public IViewComponentResult Invoke(FilterViewModel model) { Type rendererType = null; if (_renderersMap.ContainsId(model.PropertyId)) rendererType = _renderersMap.GetFilterForProperty(model.PropertyId); else if (_renderersMap.ContainsType(model.PropertyType)) rendererType = _renderersMap.GetFilterForType(model.PropertyType); else return new ContentViewComponentResult($"Cannot render filter for property {model.PropertyName}"); var renderer = (IFilterRenderer)_renderersMap.GetFilterFactory(rendererType)(); var expectedModelType = rendererType.GetInterfaces() .Single(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IFilterRenderer<>)) .GetGenericArguments()[0]; if(expectedModelType != model.GetType()) throw new Exception($"Renderer '{rendererType.Name}' was expecting view model of type '{expectedModelType.Name}', but received '{model.GetType().Name}'"); var result = renderer.Render(model); if (result is ViewViewComponentResult viewResult) result = View(viewResult.ViewName, model); return result; }
public Task BindModelAsync(ModelBindingContext bindingContext) { if (bindingContext == null) { throw new ArgumentNullException(nameof(bindingContext)); } var modelName = bindingContext.ModelName; var propertyIdValue = bindingContext.ValueProvider.GetValue($"{modelName}.PropertyId"); var propertyTypeValue = bindingContext.ValueProvider.GetValue($"{modelName}.PropertyType"); if (propertyIdValue == ValueProviderResult.None || propertyTypeValue == ValueProviderResult.None || !int.TryParse(propertyIdValue.FirstValue, out var propertyId) || !int.TryParse(propertyTypeValue.FirstValue, out var propertyType)) { bindingContext.Result = ModelBindingResult.Failed(); return(Task.CompletedTask); } Type filterType = null; if (_filterMapper.ContainsId(propertyId)) { filterType = _filterMapper.GetFilterForProperty(propertyId); } else if (_filterMapper.ContainsType(propertyType)) { filterType = _filterMapper.GetFilterForType(propertyType); } else { return(Task.CompletedTask); } var metadata = _filterMapper.GetFilterPropertiesMetadata(filterType); var obj = _filterMapper.GetFilterFactory(filterType)(); foreach (var property in metadata) { //TODO: Try to improve with fallback to default model binder var propertyName = property.Name; var resolvedType = property.UnderlyingOrModelType; var value = bindingContext.ValueProvider.GetValue($"{modelName}.{propertyName}"); var firstValue = value.FirstValue; if (value != ValueProviderResult.None && firstValue != null && !string.IsNullOrWhiteSpace(firstValue)) { if (!property.IsCollectionType) { property.PropertySetter(obj, Convert.ChangeType(firstValue, resolvedType)); } else { var elementType = property.ElementType; property.PropertySetter(obj, value.Values.ToList()); } } } bindingContext.Result = ModelBindingResult.Success((FilterDTO)obj); return(Task.CompletedTask); }