1

I'm querying the Google Books API, and I'm parsing the books into a custom object like this:

foreach (JToken item in items)
{
    try
    {
        FoundBookViewModel viewModel = new FoundBookViewModel
        {
            Title = item.SelectToken("volumeInfo.title").ToString(),
            Isbn13 = item.SelectToken("volumeInfo.industryIdentifiers[1].identifier").ToString(),
            Authors = item.SelectToken("volumeInfo.authors").Select(x => x.ToString()).ToList().Aggregate((i, j) => i + ", " + j),
            Pages = item.SelectToken("volumeInfo.pageCount").ToString(),
            ImageUri = item.SelectToken("volumeInfo.imageLinks.smallThumbnail").ToString()
        };

        newList.Add(viewModel);
    }
    catch (Exception)
    {
        newList.Add(new FoundBookViewModel());
    }
}

However, sometimes not all data is available. Sometimes there is no 'pageCount', sometimes there is no 'ISBN13', etc. In those cases an exception is thrown at the ToString() part.

So what I want is this: when an exception is thrown for one of the properties, I just want it to be an empty string. But I don't know a clean way to accomplish this.

I tried multiple things:

  • I wrapped the whole thing inside a try catch, but then I don't know what property was empty, so I can't 'fill' it with an empty string.
  • I tried using safe casting ('as string') but that operation is not available on SelectToken().
  • Couple of other things that didn't work anyway.

Of course I could put every operation inside its own try catch, but that will result in 5 try catch blocks in this situation, so that's not what I'm looking for.

Who knows a clean way to solve this? Btw. I choose to use LINQ to JSON instead of materializing it directly because the Google Books API doesn't neatly map to simple entities (the JSON contains lots of nesting).

1 Answer 1

5

If you don't want to throw exception - don't...

I.e. you can change item.SelectToken("volumeInfo.pageCount").ToString() into:

item.SelectToken("volumeInfo.pageCount") == null? 
   String.Empty : item.SelectToken("volumeInfo.pageCount").ToString()
Sign up to request clarification or add additional context in comments.

5 Comments

Ah, the ternary operator. I already played around with that (but I didn't mention it), but I did it like this: item.SelectToken("volumeInfo.industryIdentifiers[1].identifier").ToString() ? blabla : blabla;, which is (of course) not going to work. Stupid of me. Btw, is there any way to avoid duplication of the 'item.SelectToken' part?
You can create a a function like ValueAsStringOrDefault(valueThatCanBeNull, "some default for null"). If you make it extension on string code will be very compact.
Thanks, I just came up with another solution: (item.SelectToken("volumeInfo.title") ?? string.Empty).ToString(). Works like a charm now :)
Yes, if SelectToken already returns string you don't even need last .ToString() (I assumed SelectToken returns some sort of non-trivial object as result)
It does :-) That's what the last ToString() is for.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.