You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
this content is in the folder doc, and it has most of the documentation to use the tool.
to
create our website we need to do the same with GitHub pages
in my opinion the documentation touches on the basics. what is missed is a lot. example, is missing Actions. i am just saying that we need better documentation which has been something users of RulesEngine have always complained about.
If anyone can provide better insights (e.g., documentation/examples) on utilizing "OnSuccess or OnFailure," that would be splendid. Specifically, how to deserialize a JSON, as shown in the picture, is where I am stuck.
Json File:
{ "WorkflowName": "inputWorkflow", "Rules": [ { "RuleName": "GiveDiscount20Percent", "Expression": "input1.couy == \"india\" AND input1.loyalityFactor <= 5 AND input1.totalPurchasesToDate >= 20000", "Actions": { "OnSuccess": { "Name": "OutputExpression", //Name of action you want to call "Context": { //This is passed to the action as action context "Expression": "input1.TotalBilled * 0.8" } }, "OnFailure": { // This will execute if the Rule evaluates to failure "Name": "EvaluateRule", "Context": { "WorkflowName": "inputWorkflow", "ruleName": "GiveDiscount10Percent" } } } }, { "RuleName": "GiveDiscount10Percent", "SuccessEvent": "10", "ErrorMessage": "One or more adjust rules failed.", "ErrorType": "Error", "RuleExpressionType": "LambdaExpression", "Expression": "input1.couy == \"india\" AND input1.loyalityFactor <= 2 AND input1.totalPurchasesToDate >= 5000 AND input2.totalOrders > 2 AND input2.noOfVisitsPerMonth > 2", "Actions": { "OnSuccess": { "Name": "OutputExpression", //Name of action you want to call "Context": { //This is passed to the action as action context "Expression": "input1.TotalBilled * 0.9" } } } } ] }
Code:
`
string? json = File.ReadAllText(FileDirectory!);
json = json.Replace("\r\n", "").Replace("\\", "").Trim();
var rule = JsonSerializer.Deserialize<Workflow>(json);
var rules = new List<Workflow> { rule! };
var re = new RulesEngine.RulesEngine(rules.ToArray());
var input = new RuleParameter("input1", new
{
couy = "india",
loyalityFactor = 2,
totalPurchasesToDate = 40000,
totalOrders = 3,
noOfVisitsPerMonth = 3,
TotalBilled = 2000
});
var result = await re.ExecuteActionWorkflowAsync("inputWorkflow", "GiveDiscount20Percent", new List<RuleParameter> { input }.ToArray());
Console.WriteLine(result);`
Error:
System.Text.Json.JsonException
HResult=0x80131500
Message='i' is invalid after a value. Expected either ',', '}', or ']'. Path: $.Rules[0] | LineNumber: 0 | BytePositionInLine: 131.
Source=System.Text.Json
StackTrace:
at System.Text.Json.ThrowHelper.ReThrowWithPath(ReadStack& state, JsonReaderException ex)
at System.Text.Json.Serialization.JsonConverter1.ReadCore(Utf8JsonReader& reader, JsonSerializerOptions options, ReadStack& state) at System.Text.Json.JsonSerializer.ReadFromSpan[TValue](ReadOnlySpan1 utf8Json, JsonTypeInfo1 jsonTypeInfo, Nullable1 actualByteCount)
at System.Text.Json.JsonSerializer.ReadFromSpan[TValue](ReadOnlySpan1 json, JsonTypeInfo1 jsonTypeInfo)
at System.Text.Json.JsonSerializer.Deserialize[TValue](String json, JsonSerializerOptions options)
at RuleBasedEngineLibrary.RuleEngineWrapper.d__5.MoveNext() in C:\Users\E1365537\Desktop\RuleBasedEngineApp\RuleBasedEngineLibrary\RuleEngineWrapper.cs:line 19
at Program.<
$>d__0.MoveNext() in C:\Users\E1365537\Desktop\RuleBasedEngineApp\ConsoleApp\Program.cs:line 9
This exception was originally thrown at this call stack:
[External Code]
Inner Exception 1:
JsonReaderException: 'i' is invalid after a value. Expected either ',', '}', or ']'. LineNumber: 0 | BytePositionInLine: 131.
@uBoscuBo, I understand the issue you're experiencing. This problem is related to JSON deserialization rather than the rules engine itself. Specifically, System.Text.Json does not natively handle comments within JSON files, which causes the deserialization process to fail.
note that you don't need to replace anything in the example, as we have to have double quotes in for example this case "input1.couy == \"india\" AND input1.loyalityFactor <= 5 AND input1.totalPurchasesToDate >= 20000"
To resolve this issue, you have two options:
Remove Comments from JSON: Manually remove any comments from your JSON file before attempting to deserialize it.
Configure JsonSerializerOptions to Skip Comments: You can configure the JsonSerializerOptions to ignore comments during deserialization. Here’s how you can modify your code:
By setting ReadCommentHandling to JsonCommentHandling.Skip, the deserializer will ignore any comments in the JSON and successfully parse the remaining content.
I hope this helps! If you have any further questions, feel free to ask.
@RenanCarlosPereira - Thanks for the heads up. That solved that one issue, but now I am getting the following error.
System.Text.Json.JsonException: 'The JSON value could not be converted to RulesEngine.Models.RuleExpressionType. Path: $.Rules[1].RuleExpressionType | LineNumber: 27 | BytePositionInLine: 46.'
Was there a change to the schema that affected the deserialization of the WorkFlow object?
string? json = File.ReadAllText(FileDirectory!);
var opts = new JsonSerializerOptions
{
ReadCommentHandling = JsonCommentHandling.Skip
};
var rule = JsonSerializer.Deserialize<Workflow>(json, opts);
var rules = new List<Workflow> { rule! };
var re = new RulesEngine.RulesEngine(rules.ToArray());
var input = new RuleParameter("input1", new
{
couy = "india",
loyalityFactor = 2,
totalPurchasesToDate = 40000,
totalOrders = 3,
noOfVisitsPerMonth = 3,
TotalBilled = 2000
});
var result = await re.ExecuteActionWorkflowAsync("inputWorkflow", "GiveDiscount20Percent", new List<RuleParameter> { input }.ToArray());
Console.WriteLine(result);
@RenanCarlosPereira - Thanks for the heads up. That solved that one issue, but now I am getting the following error.
System.Text.Json.JsonException: 'The JSON value could not be converted to RulesEngine.Models.RuleExpressionType. Path: $.Rules[1].RuleExpressionType | LineNumber: 27 | BytePositionInLine: 46.'
Was there a change to the schema that affected the deserialization of the WorkFlow object?
`string? json = File.ReadAllText(FileDirectory!); var opts = new JsonSerializerOptions { ReadCommentHandling = JsonCommentHandling.Skip }; var rule = JsonSerializer.Deserialize(json, opts);
var rules = new List { rule! }; var re = new RulesEngine.RulesEngine(rules.ToArray());
var input = new RuleParameter("input1", new { couy = "india", loyalityFactor = 2, totalPurchasesToDate = 40000, totalOrders = 3, noOfVisitsPerMonth = 3, TotalBilled = 2000 });
var result = await re.ExecuteActionWorkflowAsync("inputWorkflow", "GiveDiscount20Percent", new List { input }.ToArray());
Console.WriteLine(result); `
No, we didn't change anything, remember you are Deserializing an workflow not a rule. var workflow = JsonSerializer.Deserialize<Workflow>(data, options)!;
the data in the file is a workflow as it shows in the documentation.
If you want to Deserialize a rule the file is different
@RenanCarlosPereira , my apologies. That was a typo. You are correct on that part.
I'll rephrase the question since I have resolved my issue. According to the previous error,
System.Text.Json.JsonException: 'The JSON value could not be converted to RulesEngine.Models.RuleExpressionType. Path: $.Rules[1].RuleExpressionType | LineNumber: 27 | BytePositionInLine: 46.'
The problem was with the second rule's RuleExpressionType. The model itself looks like it has already initialized as a LamdaExpression. The error will be resolved if I remove this line `"RuleExpressionType": "LambdaExpression" from the JSON itself.
From my observation, explicitly stating the RuleExpressionType can cause issues as it is already initialized within the code. Thoughts? I guess the only problem is that the second rule won't output its expression.
@asulwer The most significant difference that pops up is using "Actions" in the JSON files, hence why I have to use the ExecuteActionWorkflowAsync command instead of the ExecuteAllRulesAsync.
For example, from the documentation:
{ "WorkflowName": "inputWorkflow", "Rules": [ { "RuleName": "GiveDiscount20Percent", "Expression": "input1.couy == \"india\" AND input1.loyalityFactor <= 5 AND input1.totalPurchasesToDate >= 20000", "Actions": { "OnSuccess": { "Name": "OutputExpression", //Name of action you want to call "Context": { //This is passed to the action as action context "Expression": "input1.TotalBilled * 0.8" } }, "OnFailure": { // This will execute if the Rule evaluates to failure "Name": "EvaluateRule", "Context": { "WorkflowName": "inputWorkflow", "ruleName": "GiveDiscount10Percent" } } } }, { "RuleName": "GiveDiscount10Percent", "SuccessEvent": "10", "ErrorMessage": "One or more adjust rules failed.", "ErrorType": "Error", "RuleExpressionType": "LambdaExpression", "Expression": "input1.couy == \"india\" AND input1.loyalityFactor <= 2 AND input1.totalPurchasesToDate >= 5000 AND input2.totalOrders > 2 AND input2.noOfVisitsPerMonth > 2", "Actions": { "OnSuccess": { "Name": "OutputExpression", //Name of action you want to call "Context": { //This is passed to the action as action context "Expression": "input1.TotalBilled * 0.9" } } } } ] }
I guess the only thing I am confused about is why the RuleExpressionType is only needed on the second rule and not the first rule? Is "Workflow" the correct data structure for Action types?
Activity
RenanCarlosPereira commentedon Jun 30, 2024
please check out the documentation on the original website:
https://microsoft.github.io/RulesEngine/
this content is in the folder doc, and it has most of the documentation to use the tool.
to
create our website we need to do the same with GitHub pages
asulwer commentedon Jul 1, 2024
in my opinion the documentation touches on the basics. what is missed is a lot. example, is missing Actions. i am just saying that we need better documentation which has been something users of RulesEngine have always complained about.
RenanCarlosPereira commentedon Jul 1, 2024
Nice, so what exactly are we missing in the documentation?
Would be nice to know so we can work on it.
A valid good point is how to create expressions, but we can see it here:
https://dynamic-linq.net/expression-language#operators
asulwer commentedon Jul 1, 2024
expressions are 'sort of' created for us., something i want to fix, seems hardcoded at the moment
asulwer commentedon Jul 4, 2024
@RenanCarlosPereira
uBoscuBo commentedon Jul 15, 2024
If anyone can provide better insights (e.g., documentation/examples) on utilizing "OnSuccess or OnFailure," that would be splendid. Specifically, how to deserialize a JSON, as shown in the picture, is where I am stuck.
Json File:
{ "WorkflowName": "inputWorkflow", "Rules": [ { "RuleName": "GiveDiscount20Percent", "Expression": "input1.couy == \"india\" AND input1.loyalityFactor <= 5 AND input1.totalPurchasesToDate >= 20000", "Actions": { "OnSuccess": { "Name": "OutputExpression", //Name of action you want to call "Context": { //This is passed to the action as action context "Expression": "input1.TotalBilled * 0.8" } }, "OnFailure": { // This will execute if the Rule evaluates to failure "Name": "EvaluateRule", "Context": { "WorkflowName": "inputWorkflow", "ruleName": "GiveDiscount10Percent" } } } }, { "RuleName": "GiveDiscount10Percent", "SuccessEvent": "10", "ErrorMessage": "One or more adjust rules failed.", "ErrorType": "Error", "RuleExpressionType": "LambdaExpression", "Expression": "input1.couy == \"india\" AND input1.loyalityFactor <= 2 AND input1.totalPurchasesToDate >= 5000 AND input2.totalOrders > 2 AND input2.noOfVisitsPerMonth > 2", "Actions": { "OnSuccess": { "Name": "OutputExpression", //Name of action you want to call "Context": { //This is passed to the action as action context "Expression": "input1.TotalBilled * 0.9" } } } } ] }Code:
`
Error:
$>d__0.MoveNext() in C:\Users\E1365537\Desktop\RuleBasedEngineApp\ConsoleApp\Program.cs:line 9System.Text.Json.JsonException
HResult=0x80131500
Message='i' is invalid after a value. Expected either ',', '}', or ']'. Path: $.Rules[0] | LineNumber: 0 | BytePositionInLine: 131.
Source=System.Text.Json
StackTrace:
at System.Text.Json.ThrowHelper.ReThrowWithPath(ReadStack& state, JsonReaderException ex)
at System.Text.Json.Serialization.JsonConverter
1.ReadCore(Utf8JsonReader& reader, JsonSerializerOptions options, ReadStack& state) at System.Text.Json.JsonSerializer.ReadFromSpan[TValue](ReadOnlySpan1 utf8Json, JsonTypeInfo1 jsonTypeInfo, Nullable1 actualByteCount)at System.Text.Json.JsonSerializer.ReadFromSpan[TValue](ReadOnlySpan
1 json, JsonTypeInfo1 jsonTypeInfo)at System.Text.Json.JsonSerializer.Deserialize[TValue](String json, JsonSerializerOptions options)
at RuleBasedEngineLibrary.RuleEngineWrapper.d__5.MoveNext() in C:\Users\E1365537\Desktop\RuleBasedEngineApp\RuleBasedEngineLibrary\RuleEngineWrapper.cs:line 19
at Program.<
This exception was originally thrown at this call stack:
[External Code]
Inner Exception 1:
JsonReaderException: 'i' is invalid after a value. Expected either ',', '}', or ']'. LineNumber: 0 | BytePositionInLine: 131.
asulwer commentedon Jul 15, 2024
@uBoscuBo could you please edit your comment to include that code and not an image of it?
uBoscuBo commentedon Jul 16, 2024
@asulwer It is updated. This example is from the Rule Engine website, given here
RenanCarlosPereira commentedon Jul 16, 2024
@uBoscuBo, I understand the issue you're experiencing. This problem is related to JSON deserialization rather than the rules engine itself. Specifically,
System.Text.Jsondoes not natively handle comments within JSON files, which causes the deserialization process to fail.note that you don't need to replace anything in the example, as we have to have double quotes in for example this case
"input1.couy == \"india\" AND input1.loyalityFactor <= 5 AND input1.totalPurchasesToDate >= 20000"To resolve this issue, you have two options:
Remove Comments from JSON: Manually remove any comments from your JSON file before attempting to deserialize it.
Configure
JsonSerializerOptionsto Skip Comments: You can configure theJsonSerializerOptionsto ignore comments during deserialization. Here’s how you can modify your code:By setting
ReadCommentHandlingtoJsonCommentHandling.Skip, the deserializer will ignore any comments in the JSON and successfully parse the remaining content.I hope this helps! If you have any further questions, feel free to ask.
uBoscuBo commentedon Jul 19, 2024
@RenanCarlosPereira - Thanks for the heads up. That solved that one issue, but now I am getting the following error.
System.Text.Json.JsonException: 'The JSON value could not be converted to RulesEngine.Models.RuleExpressionType. Path: $.Rules[1].RuleExpressionType | LineNumber: 27 | BytePositionInLine: 46.'
Was there a change to the schema that affected the deserialization of the WorkFlow object?
RenanCarlosPereira commentedon Jul 19, 2024
No, we didn't change anything, remember you are Deserializing an workflow not a rule.
var workflow = JsonSerializer.Deserialize<Workflow>(data, options)!;the data in the file is a workflow as it shows in the documentation.
If you want to Deserialize a rule the file is different
uBoscuBo commentedon Jul 19, 2024
@RenanCarlosPereira , my apologies. That was a typo. You are correct on that part.
I'll rephrase the question since I have resolved my issue. According to the previous error,
The problem was with the second rule's RuleExpressionType. The model itself looks like it has already initialized as a LamdaExpression. The error will be resolved if I remove this line `"RuleExpressionType": "LambdaExpression" from the JSON itself.
From my observation, explicitly stating the RuleExpressionType can cause issues as it is already initialized within the code. Thoughts? I guess the only problem is that the second rule won't output its expression.
asulwer commentedon Jul 19, 2024
@uBoscuBo what are you doing different than the example? the example Deserializes a Workflow, your issue is when you Deserialize a rule directly?
uBoscuBo commentedon Jul 19, 2024
@asulwer The most significant difference that pops up is using "Actions" in the JSON files, hence why I have to use the
ExecuteActionWorkflowAsynccommand instead of theExecuteAllRulesAsync.For example, from the documentation:
{ "WorkflowName": "inputWorkflow", "Rules": [ { "RuleName": "GiveDiscount20Percent", "Expression": "input1.couy == \"india\" AND input1.loyalityFactor <= 5 AND input1.totalPurchasesToDate >= 20000", "Actions": { "OnSuccess": { "Name": "OutputExpression", //Name of action you want to call "Context": { //This is passed to the action as action context "Expression": "input1.TotalBilled * 0.8" } }, "OnFailure": { // This will execute if the Rule evaluates to failure "Name": "EvaluateRule", "Context": { "WorkflowName": "inputWorkflow", "ruleName": "GiveDiscount10Percent" } } } }, { "RuleName": "GiveDiscount10Percent", "SuccessEvent": "10", "ErrorMessage": "One or more adjust rules failed.", "ErrorType": "Error", "RuleExpressionType": "LambdaExpression", "Expression": "input1.couy == \"india\" AND input1.loyalityFactor <= 2 AND input1.totalPurchasesToDate >= 5000 AND input2.totalOrders > 2 AND input2.noOfVisitsPerMonth > 2", "Actions": { "OnSuccess": { "Name": "OutputExpression", //Name of action you want to call "Context": { //This is passed to the action as action context "Expression": "input1.TotalBilled * 0.9" } } } } ] }I guess the only thing I am confused about is why the
RuleExpressionTypeis only needed on the second rule and not the first rule? Is "Workflow" the correct data structure for Action types?RenanCarlosPereira commentedon Jul 19, 2024
Workflows are just a set of rules grouped.
Actions are executed for each rule inside the workflow.
you can pass RuleExpressionType or not, as it will fallback to the default both ways works
uBoscuBo commentedon Jul 19, 2024
@RenanCarlosPereira - Gotcha, that makes sense. I do appreciate y'all patience and assistance.