NullReferenceException is thrown when evaluating a null-conditional operator on missing related DataRow

Hello,
I see you get a NullReferenceException if a DataTable has a foreign key with some NULL values.

I created a simple example with a TextBlock class/table with a BackColor property which refers to a CustomColor class/table: the color is nullable for “transparent” color.

Case 1) (I moved this case to post 203684, see below)
No check for nulls are done in the template: you get a NullReferenceException for both custom classes and DataTable examples

==> This is right, but it would be nice if you could give some context to the exception, because with a long template it is very difficult to find where is missing the check for “null”!

Case 2)
With a check for “null” (either with “?.” or an explicit “if”) the example with custom classes works correctly, but the example with DataTables continues to give a NullReferenceException.

This is the syntax I tried and with custom classes it works correctly, but with DataTables an exception is thrown when Color is NULL in TextBlock.

For custom classes (works):

<<foreach [textBlock in textBlocks]>> <<[BackColor?.Name]>> <</foreach>>

For DataTables (does not work):

<<foreach [textBlock in TextBlocks]>> <<[CustomColors?.Name]>> <</foreach>>

Then I tried to check with “.Any()” on DataTables and it worked, but this is not intuitive and seems a bug to me: why you get an empty list of DataRows (or an empty DataRow, I don’t know) instead of “null”? This is not a list, it is a reference to a single item which does not exist…

<<foreach [textBlock in TextBlocks]>> <<if [CustomColors.Any()]>> <<[CustomColors.Name]>> <</if>><</foreach>>

Please fix this returning “null” in this case, so that it is possible to use the same simple syntax “?.” that you can use with custom classes, because having to add an “if” with “Any()” on every field makes the template much more complex.

Attached you can find all the described examples:
Aspose.Words - NullableForeignKey.zip (58.8 KB)
Note: in the example, to try with/without “null” values and see/hide the errors, uncomment/comment the first line in Common.cs to define ADD_NULL_VALUES.

@agarberi

We have logged this feature request as WORDSNET-19237 in our issue tracking system. You will be notified via this forum thread once this feature is available.

We apologize for your inconvenience.

Hello,
thank you for the feature request accepted.

Please, could you split it in 2 requests?

  1. Give context information when a NullReferenceException occurs.
  2. Allow to use “null” check (“?.” or explicit “if”) also in DataTables (like it is already for Custom Classes).

Having at least part 1 would be very useful to identify these conditions in long reports.

Thanks!

@agarberi

Could you please elaborate your query further along with input and expected output? We will then log new features according to your requirement. Thanks for your cooperation.

Tell me what is not clear for you: I have already attached a real example with code and templates.

Anyway, summing up: when you go from one table to another using a nullable ID you have 2 issues if the value is null.
Example:

<<foreach [textBlock in TextBlocks]>> <<[CustomColors.Name]>> <</foreach>>

Issue 1) If the link between “textBlock” and “CustomColors” is null for some “textBlock”, you get a NullReferenceException, but without context: you do not known where the error is in the document (while for other errors you have a piece of document in the error message to help you identify the position of the error)
[Moved to separate post 203684, see below]

Issue 2) If the link between “textBlock” and “CustomColors” is null for some “textBlock”, you do not have a “null” value for “CustomColors”, but an empty list (and this is an error, it should be a null value)

Probably it is better if I make a new post in the forum to separate the part 1 (which is more generic then this specific issue) and continue this post only for part 2.
I made a separate post for issue 1 here:

@agarberi

We have logged separate issue for this case. Please follow your other thread for further proceedings.

Hello,
do you have an exstimated time for this bug fix?

It makes the template code much longer with this syntax:

<<foreach [textBlock in TextBlocks]>> <<if [CustomColors.Any()]>> <<[CustomColors.Name]>> <</if>><</foreach>>

instead of this one:

<<foreach [textBlock in TextBlocks]>> <<[CustomColors?.Name]>> <</foreach>>

Consider also that what in the example is CustomColors, in our real template is a much longer expression that must be completely reapeated in the <<if>> part.

Thanks.

@agarberi

We try our best to deal with every customer request in a timely fashion, we unfortunately cannot guarantee a delivery date to every customer issue. We work on issues on a first come, first served basis. We feel this is the fairest and most appropriate way to satisfy the needs of the majority of our customers.

Currently, your issue is under analysis phase. Once we complete the analysis of your issue, we will then be able to provide you an estimate.

We have logged this detail in our issue tracking system.

I know you have many requests, I just wanted to know if you were considering this and an approximate idea of the time, because this condition is very frequent in our reports.

I hope you will be able to fix this soon!

Thanks for your support

@agarberi

We have good news for you i.e. WORDSNET-19237 has now been resolved. This feature will be included in the next version of Aspose.Words i.e. 19.12. We will inform you via this forum thread as soon as the next version of Aspose.Words is available.

Thank you very much for the rapid fix.

I noticed that the new version come out and I tried it (although there has been no notification from the forum thread).

It works as expected with “?.” syntax, but for the “if” statement you still have to use “.Any()” instead of “!= null”.

This is not working yet:

<<foreach [textBlock in TextBlocks]>> <<if [CustomColors != null]>>Data filled<</if>><</foreach>>

You still have to use this syntax to make it work:

<<foreach [textBlock in TextBlocks]>> <<if [CustomColors.Any()]>>Data filled<</if>><</foreach>>

Please note that I have just updated my previous post as it was not correct (there was an error in my test case).

In the original test case Word file “NullableForeignKey_DataSet_WithCheckForAny.doc” there was a typo: “.Anys()” instead of “.Any()”.

It seems that “if [MyTable != null]” returns always “true”, also if the ID required by the relation is null.

Here is a new test case for 19.12:
Aspose.Words - NullableForeignKey2.zip (68.0 KB)

@agarberi

We have logged this feature request as WORDSNET-19663 in our issue tracking system. You will be notified via this forum thread once this feature is available.

We apologize for your inconvenience.

Thank you Tahir,
anyway the main issue was to allow the usage of “?.” and this works perfectly now!

@agarberi

Thanks for your feedback. Please feel free to ask if you have any question about Aspose.Words, we will be happy to help you.

The issues you have found earlier (filed as WORDSNET-19237) have been fixed in this Aspose.Words for .NET 19.12 update and this Aspose.Words for Java 19.12 update.

@agarberi

It is to inform you that we have closed the issue (WORDSNET-19663) with “Won’t Fix” resolution. The behavior of Aspose.Words that you are facing is by design.

The ways of representing the same data by ADO.NET objects (i.e. DataSet/DataTable/DataRow) and instances of regular CLR classes are different. We try to make working with the two closer and provide syntax for ADO.NET objects similar to syntax used for regular CLR objects in C#. But in some scenarios, we cannot get 100% matching.

Using of CustomColors.Any() does work and it is not longer than CustomColors != null (although it can be less intuitive), so please use CustomColors.Any() in templates as we will not change the current behavior.

OK, thank you Tahir for the information.

Please add this to the documentation because this is not intuitive and I found this solution after several tries of different possible ways to resolve this.

@agarberi

Thanks for your inquiry. Sure, we will add this detail in our documentation. Please let us know if you have any more queries.