Link to home
Start Free TrialLog in
Avatar of trevor1940
trevor1940

asked on

C#: GetEnumerator errors when using TMDB API

I have a need to perform two functions  to retrieve information about a person i'm guessing the error  is the same reason?

1st if the person ID isn't known I need to do a search by name
using the API  even if correct it gives back several hits
However it dose reveal what a person is "known_for" which is some of the information I'm after as is the person ID
You need the person's ID to reveal details like BIO

Is it possible to chain queries together?

In the code bellow I'm the errors listed

using System;

using TMDbLib.Client;
using TMDbLib.Objects.General;
using TMDbLib.Objects.Movies;
using TMDbLib.Objects.TvShows;
using TMDbLib.Objects.Search;

namespace TMDBTest
{
    class Program
    {
        static void Main(string[] args)
        {
        // Access to The Movie DB API
        TMDbClient client = new TMDbClient("2c8a02fa36fb5299dcd97bbc84609899");
            Console.WriteLine("Hello World!");
            var People = client.SearchPersonAsync("jessica alba").Result;

            foreach(var Person in People)
            {

            }
            // assuming you know the id of the  person

            

            var PersonKF = client.GetCreditsAsync("56731").Result;
            foreach(var PNF in PersonKF)
            {

            }

        }
    }
}

Open in new window


Errors
Error	CS1579	foreach statement cannot operate on variables of type 'SearchContainer<SearchPerson>' because 'SearchContainer<SearchPerson>' does not contain a public instance definition for 'GetEnumerator'


Error	CS1579	foreach statement cannot operate on variables of type 'Credit' because 'Credit' does not contain a public instance definition for 'GetEnumerator'	

Open in new window

ASKER CERTIFIED SOLUTION
Avatar of gr8gonzo
gr8gonzo
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Illustrating what Gonzo means:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using TMDbLib.Client;
using TMDbLib.Objects.Credit;

namespace EE_Q29156747
{
    class Program
    {
        static void Main(string[] args)
        {
            TMDbClient client = new TMDbClient("2c8a02fa36fb5299dcd97bbc84609899");
            var People = client.SearchPersonAsync("jessica alba").Result;
            int id = default(int);
            foreach (var person in People.Results)
            {
                id = person.Id;
            }

            var credit = client.GetCreditsAsync(id.ToString()).Result;

            Console.WriteLine($"{{ {string.Join(", ", from property in typeof(Credit).GetProperties() select $"{property.Name}: {property.GetValueOrValues(credit)}")} }}");
            Console.ReadLine();
        }
    }

    static class Extensions
    {
        public static string GetValueOrValues(this PropertyInfo property, object source)
        {
            var value = property.GetValue(source);
            if (ReferenceEquals(value, null))
            {
                return string.Empty;
            }
            else if (Equals(property.PropertyType, typeof(string)) && typeof(IEnumerable<>).IsAssignableFrom(property.PropertyType))
            {
                return $"{{ {string.Join(", ", from item in value as IEnumerable<object> select item)} }}";
            }
            else
            {
                return value.ToString();
            }
        }
    }
}

Open in new window

Which produces the following results:User generated image-saige-
Avatar of trevor1940
trevor1940

ASKER

I'm going to have to look at the 2nd part  more closely

Doing what Gonzo  suggested returns the properties of person correctly

Hovering over "PKF" in PKF in Person.KnownFor reveals a List of movies but not all the properties @ PKF.  seem to be accessible see pic  

Am I missing something?

            var People = client.SearchPersonAsync("jessica alba").Result;

            foreach(var Person in People.Results)
            {
                Console.WriteLine("Name: {0} id {1} ", Person.Name, Person.Id );
                foreach(var PKF in Person.KnownFor)
                {
                    Console.WriteLine("Known For {0} {1}", PKF.Id, PKF.Overview);
                     PKF.t
                    
                }
            }

Open in new window


User generated imagepkf3.jpg
What property are you trying to access that is not available?
Title for 1
See pkf3.jpg in last post shows what is availible
I'm confused - your screenshot shows Title as available - "Fantastic Four".
Oh I think I know what you're saying. Your screenshot is showing the properties that you EXPECT to be available on all movies but when you're iterating through the list of "KnownForMovie" objects, those objects don't have all of those expected properties.

If that's correct, then that is expected behavior. The KnownForMovie is a separate class that should be treated almost like a brief summary of the full movie details.

If you want the full details, then you would have to issue another API call (using the movie ID from the KnownForMovie object) to pull the rest of the details.
Really?

My Understanding was you need a persons ID to access there properties like DOB Bio etc
You get this ID from searching by name the also reveals there top 4 movies under known for
Within the know for each movie has an ID, Title ect another API with the Movie ID gives more
Similarly searching for a movie by Title


In Debug why when hovering over PKF  and expand dose is  show the pic below id & overview are accessible  with "PKF.Id, PKF.Overview" but "PKF.Title;" gives the error

            foreach(var Person in People.Results)
            {
                Console.WriteLine("Name: {0} id {1} ", Person.Name, Person.Id );
                foreach(var PKF *Hover Here* in Person.KnownFor)
                {
                    Console.WriteLine("Known For {0} {1}", PKF.Id, PKF.Overview);
                    string Title = PKF.Title;
                   
                }
            }

Open in new window


Error

Severity	Code	Description	Project	File	Line	Suppression State
Error	CS1061	'KnownForBase' does not contain a definition for 'Title' and no accessible extension method 'Title' accepting a first argument of type 'KnownForBase' could be found (are you missing a using directive or an assembly reference?)	TMDBTest	

Open in new window


Looking at the API documentation gives that's similar to the picture

{
  "page": 1,
  "total_results": 2,
  "total_pages": 1,
  "results": [
    {
      "popularity": 8.343,
      "known_for_department": "Acting",
      "gender": 1,
      "id": 56731,
      "profile_path": "/yMiHrSyrv5u8qwfi3T8EuI4VPFk.jpg",
      "adult": false,
      "known_for": [
        {
          "poster_path": "/aJwUBmUA11lkNVSJ3if3h3xHSFd.jpg",
          "id": 9738,
          "vote_count": 5796,
          "video": false,
          "media_type": "movie",
          "adult": false,
          "backdrop_path": "/6RaH2Znu7dUQq7c8surf7hRp44f.jpg",
          "genre_ids": [
            28,
            12,
            14,
            878
          ],
          "original_title": "Fantastic Four",
          "original_language": "en",
          "title": "Fantastic Four",
          "vote_average": 5.7,
          "overview": "During a space voyage, four scientists are altered by cosmic rays: Reed Richards gains the ability to stretch his body; Sue Storm can become invisible; Johnny Storm controls fire; and Ben Grimm is turned into a super-strong … thing. Together, these \"Fantastic Four\" must now thwart the evil plans of Dr. Doom and save the world from certain destruction.",
          "release_date": "2005-07-08"
        },

Open in new window



User generated image
If TMDB reports other "known for" data that isn't always a movie, then you might just need to cast from the base class. For example:

foreach(var PKF in Person.KnownFor)
{
  if(PKF is KnownForMovie)
  {
    var PKFM = (KnownForMovie)PKF;
    Console.WriteLine(PKFM.Title);
  }
}

Open in new window


In the above, PKF is a "KnownForBase" object that has properties that are common to all "KnownFor..." data elements while PKFM is the child class "KnownForMovie" that is more specific to movie data.
As Gonzo stated, you need to cast it to the explicit type, in this case, KnownForMovie.

-saige-
Thank you both for your help

It's a pity the examples on the LordMike Github page don't all work