How to prevent a System.NullReferenceException inside an if [closed]

-2

I'm developing a web application where a photographer does upload of an image. After copying the image, I'm going to scan all the metadata of the image in order to capture some information from the directories (Exif, IPTC, XMP, JFIF, PNG, BMP, href="https://github.com/drewnoakes/metadata-extractor"> Metadata Extractor . Okay, I learned to use it. First I need to get the directories:

 IEnumerable<MetadataExtractor.Directory> directories = iptcReader.ReturnMetadataFile(Path.Combine(StorageRootPOOL, imagePool.File_name[i]));

Here I already have all the directories of my image, after that I need to declare variables of each directory that I need to capture in my case:

var IPTCDirectory = directories.OfType<IptcDirectory>().FirstOrDefault();
var JPEGDirectory = directories.OfType<JpegDirectory>().FirstOrDefault();
var JFIFDirectory = directories.OfType<JfifDirectory>().FirstOrDefault();
var EXIFDirectory = directories.OfType<ExifIfd0Directory>().FirstOrDefault();
var EXIFSubDirectory = directories.OfType<ExifSubIfdDirectory>().FirstOrDefault();

All directory values are NOT NULL even though there is no directory in the image, the problem is in tags that exist within them. To capture the tags within the directories I use the following code:

imageFileInfo.Keywords = IPTCDirectory.GetDescription(IptcDirectory.TagKeywords);

imageFileInfo is the class where I will be saving all the data. My problem is, if for example there is no TAG IptcDirectory.TagKeywords I will get a NullException, so nothing out of the ordinary, however if I will prevent this error with an if for example:

 if (IPTCDirectory.GetDescription(IptcDirectory.TagKeywords) == null)
 {
 }

I get another NullException , there's the problem, I wanted to set a default value for tags that do not exist, for example:

if (IPTCDirectory.GetDescription(IptcDirectory.TagKeywords) == null)
{
      imageFileInfo.Keywords = "valor padrão";
}

Remembering that I do not use the following code, because I need to know which tags are null and not what directories, since the directories always exist, but some tags do not :

if (EXIFDirectory != null && ExifIfd0Directory != null) {
    //Os diretórios nunca são nulos e sim as tags, então esse exemplo não iria se aplica ao meu problema.
}
    
asked by anonymous 20.07.2017 / 20:28

3 answers

5

Do not under any circumstances what is in the other answer swallowing the exception. This does not solve any problem, it only makes the situation worse. This is even more terrible than capturing Exception . And using goto is even worse.

Only catch exception if you really need it. It is slow and should only be used in exceptional situations, not for flow control.

If you are receiving NullReferenceException , you have a programming error there. You have to fix the bug. Capturing and swallowing exceptions is not making the code look right, the solution is to get it fixed.

Check with a if what can be null and treat it the way you want, if you want to assign a default value, do this. Then you may not even need if .

You have to see what is generating the exception and check this exactly before the error happens. That it is very clear whenever you receive NullReferenceException is a programming error that must be solved, you should not capture it. And checking for the error before it occurs is the solution. So I still consider the answer accepted now is not appropriate, although it is not the absurdity that the other proposed.

Maybe this is what you want:

for (int i = 0; i < numberOfProcessAvailable; i++) {
    var IptcDirectory = directories.OfType<IptcDirectoryBase>().FirstOrDefault();
    imageFileInfo.Keywords = IptcDirectory.TagKeywords == null ? "padrao keywords" : IptcDirectory.GetDescription(IptcDirectory.TagKeywords);
    imageFileInfo.LensModel = IptcDirectory.TagLensModel == null ? "padrao lensmodel" : IptcDirectory.GetDescription(IptcDirectory.TagLensModel);
    imageFileInfo.TagMake = IIptcDirectory.TagMake == null ? "padrao make" : IptcDirectory.GetDescription(IptcDirectory.TagMake);
}

I placed GitHub for future reference .

Read this: How best to handle exceptions in Java? . Even though it's another language, it's worth it.

    
20.07.2017 / 21:34
1

I had understood your question the first time in a different way.

In your case, the reason for NullReferenceException is clear and known by you and is expected behavior when tag does not exist. In this case it is in your best interest to catch the exception to assign a default value to% of non-existent%.

There is no problem in this case when you use:

try {
    imageFileInfo.Keywords = IPTCDirectory.GetDescription(IptcDirectory.TagKeywords);
} catch (NullReferenceException e) {
    imageFileInfo.Keywords = "valor padrao"
}

It is even better to use tags than try catch to test if the error exists, so processing is reduced when there is no error.

Note

You're getting if on line

if (IPTCDirectory.GetDescription(IptcDirectory.TagKeywords) == null)

Probably because the NullException object does not have the IptcDirectory property, the right way to test would be:

if (IptcDirectory.GetProperty('TagKeywords') == null) {
    imageFileInfo.Keywords = "valor padrao";
} else {
    imageFileInfo.Keywords = IPTCDirectory.GetDescription(IptcDirectory.TagKeywords);
}

But this code with TagKeywords is less efficient than if .

EDIT

As pointed out by bigown, in fact, C # exceptions are very expensive, so the try catch structure is no less efficient at first (it all depends on how expensive if else is in relation to throwing exceptions)

    
21.07.2017 / 15:38
0

In this case you should separate each statement in blocks of try catch specific.

for (int i = 0; i < numberOfProcessAvailable; i++) {
    var EXIFDirectory = directories.OfType<ExifDirectoryBase().FirstOrDefault();

    try {
        imageFileInfo.LensModel = Convert.ToString(EXIFDirectory.GetDescription(ExifIfd0Directory.TagLensModel));
    } catch (NullReferenceException e){ //tratar excecao }

    try {    
        imageFileInfo.Make = Convert.ToString(EXIFDirectory.GetDescription(ExifIfd0Directory.TagMake));
    } catch (NullReferenceException e){ //tratar excecao }

    try {
        imageFileInfo.Model = Convert.ToString(EXIFDirectory.GetDescription(ExifIfd0Directory.TagModel));
    } catch (NullReferenceException e){ //tratar excecao }
}

In this way all blocks would always be executed.

PS: You could treat this problem also by using the goto statement, but this usually makes the code less readable and more complicated.

Ps2 .: I had not made it explicit because I thought it was obvious. But exceptions should always be treated and be as specific as possible.

    
20.07.2017 / 21:00