0

Have any of you guys ever created an MVC RuleEngine UI editor with composite pattern in .NET Core?

How did you do that? I struggling with rendering that Tree and making it bindable to model for controller while trying to save changes to db in XML.

@edit

I've tried to make this Custom Model Binder but it doesnt work :P

public class CustomBinder : IModelBinder
{
    public Task BindModelAsync(ModelBindingContext bindingContext)
    {
        if (bindingContext == null)
        {
            throw new ArgumentNullException(nameof(bindingContext));
        }

        var modelType = bindingContext.ModelType;
        if (modelType.IsAbstract)
        {
            var modelName = bindingContext.ModelName;
            var valueProviderResult = bindingContext.ValueProvider.GetValue(modelName + ".ClassName");

            if (valueProviderResult != ValueProviderResult.None)
            {
                var modelTypeName = valueProviderResult.FirstValue;
                var type = modelType.Assembly.GetTypes().SingleOrDefault(x => x.IsSubclassOf(modelType) && x.Name == modelTypeName);

                if (type != null)
                {
                    FilterRule instance = Activator.CreateInstance(type) as FilterRule;
                    bindingContext.Result = ModelBindingResult.Success(instance);
                }
                else
                {
                    bindingContext.Result = ModelBindingResult.Failed();
                }
            }
        }

        return Task.CompletedTask;
    }
}

Instance is created by activator but it isnt binded to a model prop obj. Any ideas?

@Edit2

This is how I registred Binder:

builder.Services.AddControllers(o =>
{
    o.ModelBinderProviders.Insert(0, new CustomModelBinderProvider());
});

This is my Controller Action:

    [HttpPost]
    public IActionResult Update(RuleModel model)
    {
        try
        {
            ruleService.Update(model);
            return View();
        }
        catch (Exception ex)
        {
            return StatusCode(500, ex);
        }
    }

This is RuleModel:

public class RuleModel
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public string Description { get; set; }
        [NotMapped]
        public FilterRule FilterRule
        {
            get
            {
                if (!string.IsNullOrWhiteSpace(this.FilterRuleRaw))
                {

                    return HtmlHelpers.Deserialize<FilterRule>(this.FilterRuleRaw, typeof(BaseAbstractClass));
                }
                else
                    return null;
            }
            set 
            { 
                this.FilterRuleRaw = HtmlHelpers.Serialize(this.FilterRule, typeof(BaseAbstractClass)); 
            }
        }
        public string FilterRuleRaw { get; set; }
        [NotMapped]
        public List<EffectRule> EffectRule
        {
            get
            {
                if (!string.IsNullOrWhiteSpace(this.EffectRuleRaw))
                    return JsonConvert.DeserializeObject<List<EffectRule>>(this.EffectRuleRaw);
                else
                    return null;
            }
            set
            {
                this.EffectRuleRaw = JsonConvert.SerializeObject(this.EffectRule, typeof(BaseAbstractClass), Formatting.None, new JsonSerializerSettings());
            }
        }
        public string? EffectRuleRaw { get; set; }
        public bool IsEnabled { get; set; }
        public DateTime DateChanged { get; set; }
        public int RuleSetId { get; set; }
        public virtual RuleSetModel RuleSet { get; set; }
    }

Here you have my request body key value pairs:

[
    {
        "key": "Id",
        "value": "14"
    },
    {
        "key": "RuleSetId",
        "value": "9"
    },
    {
        "key": "Name",
        "value": "New Rule"
    },
    {
        "key": "Description",
        "value": "123"
    },
    {
        "key": "IsEnabled",
        "value": "true"
    },
    {
        "key": "FilterRule.ClassName",
        "value": "FilterRuleMethodLogicalAnd"
    },
    {
        "key": "__RequestVerificationToken",
        "value": "CfDJ8C7XVp-U3ThBoklDaiDPi9n3-Y8WpuXvSu52ewI-x0BJSHaoOn1aOhKKf2BfqSqbYLxVXqNESQcFUnzeIRgo5B2i2oTIteCZORnY8zoY6wR7l1Uimb-qO1uOtpUn13MfhUN5UOfuQ9J4PS0ETorLxeY"
    },
    {
        "key": "IsEnabled",
        "value": "false"
    }
]
6
  • Where/how have you registered your CustomBinder? Commented Sep 23, 2023 at 12:51
  • Dai I've copied my code to post. Basicly I've created a dropdown list in form. That dropdown list contains List of subclasses of class FilterRule. Then in custom model binder I try to create an instance of which class name user choosed. Commented Sep 23, 2023 at 13:04
  • That instance is created correctly but it still isnt binded to a FilterRule prop. Commented Sep 23, 2023 at 13:06
  • Can you show us an example POST request body? Commented Sep 23, 2023 at 13:31
  • I have pasted pairs of keys and values to this post. Commented Sep 23, 2023 at 15:12

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.