示例#1
0
        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;
        }
示例#3
0
        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);
        }