Can not resolve method 'Abs' on type 'System.Math'

I am facing a strange issue while using Known External Types with Aspose.Words .NET.

I have updated the known types as follows:

var reportingEngine = new ReportingEngine();
reportingEngine.KnownTypes.Add(typeof(Math));

Input Sample JSON:

{
    "number_variable": 963.36
}

Please find cases below.

Case 1: <<[Math.Abs(number_variable)]>>

System.InvalidOperationException
  HResult=0x80131509
  Message=An error has been encountered at the end of expression 'Math.Abs(number_variable)]>'. Can not resolve method 'Abs' on type 'System.Math'.
  Source=Aspose.Words

Case 2: <<[Math.Abs(-369)]>>

369

Case 3: <<[Math.Abs((double)number_variable)]>>

963.36

Case 4: <<[Math.Abs(number_variable.Value)]>>

963.36

Additional Note: <<[number_variable.GetType()]>>

System.Double

Please let me know if I am doing something wrong or if there is an alternative solution.

Thank you in advance.

@abhishekouta

The issue you’re encountering with the Math.Abs method in the Aspose.Words Reporting Engine seems to stem from how the method is being resolved in the context of the known types you’ve added.

In your first case, the expression <<[Math.Abs(number_variable)]>> is not resolving correctly, which results in an InvalidOperationException. This could be due to the way the Reporting Engine interprets the method call on the Math class.

Here are a few suggestions to troubleshoot and potentially resolve the issue:

  1. Ensure Correct Type Registration: Make sure that the Math class is correctly registered as a known type. You can try explicitly adding the System namespace to your known types if it’s not already included.

    reportingEngine.KnownTypes.Add(typeof(System.Math));
    
  2. Use Explicit Casting: In your third case, you successfully used <<[Math.Abs((double)number_variable)]>>. This indicates that the Reporting Engine can handle explicit type casting. You might want to try this approach consistently when dealing with variables.

  3. Check for Nullable Types: In your fourth case, <<[Math.Abs(number_variable.Value)]>> works because you’re accessing the Value property of a nullable type. Ensure that number_variable is not null before accessing its value.

  4. Debugging: If the above suggestions do not resolve the issue, consider logging or debugging the expressions being evaluated to see how the Reporting Engine is interpreting them.

  5. Alternative Solutions: If the problem persists, you might consider creating a custom method that wraps the Math.Abs functionality and register that method with the Reporting Engine instead.

Here’s an example of how you might define a custom method:

public static class CustomMath
{
    public static double Abs(double value)
    {
        return Math.Abs(value);
    }
}

// Register the custom method
reportingEngine.KnownTypes.Add(typeof(CustomMath));

Then you can use it in your template like this:

<<[CustomMath.Abs(number_variable)]>>

This approach allows you to bypass any issues with method resolution on the Math class directly.

If you continue to experience issues, consider checking the Aspose.Words documentation or forums for any updates or similar cases that might provide additional insights.

Sources:

  1. Tried this approach, getting same error.
  2. Other solutions are not looking promising and not aligned with my requirement as well.

could you please provide root cause of this issue?

@abhishekouta

This is expected behavior rather than a bug. In JSON notation, every element may accept null values. Therefore, the engine maps JSON numbers to Nullable<double> values. System.Math.Abs does not accept nullable values, hence the method cannot be resolved. You have correctly found possible workarounds:

Alternatively, you can add your own class with a method accepting Nullable<double> as an argument like this one:

public static class MyMath
{
    public static double? Abs(double? value)
    {
        return value.HasValue ? (double?)Math.Abs(value.Value) : null;
    }
}

After making the engine aware of this class, you can use the following syntax in your templates:

<<[MyMath.Abs(number_variable)]>>