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"
}
]
CustomBinder
?