C# index to dynamic object variable works in method but not when returned, Error C50021

234 Views Asked by At

I have a method that uses MediaInfo.exe to get information from a video file and returns a dynamic object. When the code runs, the information is readable inside the method but when I return the dynamic object, it throws a RuntimeBinderException with this error:

CS0021: Cannot apply indexing with [] to an expression of type 'object'.

I call the method with:

dynamic o = GetMediaInfoJson(filename);

I type o["media"]["track"][1]["@type"] in the Immediate Window and get the error. Same error if I try to reference it with an "if" statement. ...

public dynamic GetMediaInfoJson(filename)
{
    string s = GetMediaInfoOutput(filename);  // s = json output from MediaInfo.exe
    JavaScriptSerializer serializer = new JavaScriptSerializer();
    dynamic o = serializer.Deserialize<dynamic>(s);

    return o;

I type o["media"]["track"][1]["@type"] in the Immediate Window and seethe correct value.

I.e. after the return I "reference" o["media"]["track"][1]["@type"] and get the error! Why can I reference the dynamic variable inside the method but not when it's returned?

Using Visual Studio 2019 on Windows Service Server 2019. Error is run-time, not compile time error.

Attempt at Minimum Reproducible Example:

dynamic o = GetMediaInfo();


    public dynamic MediaInfoJson()
    {
        JavaScriptSerializer serializer = new JavaScriptSerializer();
        string s = "{\"media\": {\"@ref\": \"d:\\\\inetpub\\\\ftproot\\\\slides\\\\1063_0_0_6_old.mp4\",\"track\": [{\"@type\": \"general\",\"videocount\": \"1\",\"audiocount\": \"1\",\"fileextension\": \"mp4\",\"format\": \"mpeg-4\",\"format_profile\": \"base media\",\"codecid\": \"isom\",\"codecid_compatible\": \"isom/iso2/avc1/mp41\",\"vidSize\": \"9199451\",\"vidSeconds\": \"31.834\",\"overallbitrate\": \"2311856\",\"vidFrameRate\": \"30.000\",\"framecount\": \"955\",\"streamsize\": \"26218\",\"headersize\": \"40\",\"datasize\": \"9173241\",\"footersize\": \"26170\",\"isstreamable\": \"no\",\"file_created_date\": \"utc 2021-05-24 21:04:22.909\",\"file_created_date_local\": \"2021-05-24 17:04:22.909\",\"file_modified_date\": \"utc 2021-05-24 21:04:22.914\",\"file_modified_date_local\": \"2021-05-24 17:04:22.914\",\"encoded_application\": \"lavf58.45.100\"},{\"@type\": \"video\",\"streamorder\": \"0\",\"id\": \"1\",\"format\": \"avc\",\"format_profile\": \"high\",\"format_level\": \"3\",\"format_settings_cabac\": \"yes\",\"format_settings_refframes\": \"4\",\"codecid\": \"avc1\",\"vidSeconds\": \"31.834\",\"bitrate\": \"2177206\",\"vidWidth\": \"790\",\"vidHeight\": \"402\",\"stored_vidWidth\": \"800\",\"stored_vidHeight\": \"416\",\"sampled_vidWidth\": \"790\",\"sampled_vidHeight\": \"402\",\"pixelaspectratio\": \"1.000\",\"vidAspect\": \"1.965\",\"vidRotation\": \"0.000\",\"vidFrameRate_mode\": \"cfr\",\"vidFrameRate_mode_original\": \"vfr\",\"vidFrameRate\": \"30.000\",\"framecount\": \"955\",\"colorspace\": \"yuv\",\"chromasubsampling\": \"4:2:0\",\"bitdepth\": \"8\",\"scantype\": \"progressive\",\"streamsize\": \"8663467\",\"encoded_library\": \"x264 - core 161\",\"encoded_library_name\": \"x264\",\"encoded_library_version\": \"core 161\",\"encoded_library_settings\": \"cabac=1 / ref=3 / deblock=1:0:0 / analyse=0x3:0x113 / me=hex / subme=7 / psy=1 / psy_rd=1.00:0.00 / mixed_ref=1 / me_range=16 / chroma_me=1 / trellis=1 / 8x8dct=1 / cqm=0 / deadzone=21,11 / fast_pskip=1 / chroma_qp_offset=-2 / threads=3 / lookahead_threads=1 / sliced_threads = 0 / nr = 0 / decimate = 1 / interlaced = 0 / bluray_compat = 0 / constrained_intra = 0 / bframes = 3 / b_pyramid = 2 / b_adapt = 1 / b_bias = 0 / direct = 1 / weightb = 1 / open_gop = 0 / weightp = 2 / keyint = 250 / keyint_min = 25 / scenecut = 40 / intra_refresh = 0 / rc_lookahead = 40 / rc = crf / mbtree = 1 / crf = 23.0 / qcomp = 0.60 / qpmin = 0 / qpmax = 69 / qpstep = 4 / ip_ratio = 1.40 / aq = 1:1.00\",\"extra\": {\"codecconfigurationbox\": \"avcc\"}},{\"@type\": \"audio\",\"streamorder\": \"1\",\"id\": \"2\",\"format\": \"aac\",\"format_settings_sbr\": \"no (explicit)\",\"format_additionalfeatures\": \"lc\",\"codecid\": \"mp4a-40-2\",\"vidSeconds\": \"31.781\",\"vidSeconds_lastframe\": \"-0.030\",\"bitrate_mode\": \"cbr\",\"bitrate\": \"128320\",\"channels\": \"2\",\"channelpositions\": \"front: l r\",\"channellayout\": \"l r\",\"samplesperframe\": \"1024\",\"vidAudio\": \"22050\",\"samplingcount\": \"700771\",\"vidFrameRate\": \"21.533\",\"framecount\": \"685\",\"compression_mode\": \"lossy\",\"streamsize\": \"509766\",\"streamsize_proportion\": \"0.05541\",\"default\": \"yes\",\"alternategroup\": \"1\"}]}}";
        dynamic o = serializer.Deserialize<dynamic>(s);
        return o;
    }
1

There are 1 best solutions below

5
On

To fix this, I think what you need (subject to some conditions on the input) is to cast to string:

dynamic o = GetMediaInfoJson(filename);
Debug.WriteLine((string)o["media"]["track"][1]["@type"] );   // Here I get the error!

Presumably you want to do something with this value other than just write it to the debug output; you will probably still need to cast to string for that purpose.

I would expect you to need to do the same within the method being called; based on the code you've provided so far I can't explain the difference.

EDIT: The question has now been edited to remove references to Debug.WriteLine().