3

I was using the following code:

public async Task<string> LoginAsync(string username, string password)
{
    //removed irrelevant code from snippet

    var response = await JSonConvert.DeSerializeObjectAsync<dynamic>(responseText);
    return (response.success == SUCCESS ? response.data.sid : String.Empty);
}

This worked find until I installed Reactive Extensions through NuGet.
From that point on the last line of the method simply throw a RuntimeBinderException:

{"'Newtonsoft.Json.Linq.JObject' does not contain a definition for 'success'"}

The only way to get it working now is to use this:

return (response["success"].ToString() == SUCCESS ? response["data"]["sid"].ToString() : String.Empty);

I tried another JSon library (JsonFX2.0) but I'm getting a RuntimeBinderException as well:

{"'ExpandoObject' does not contain a definition for 'success'"}

The json returned by the service looks like this:

{
  "data": {
    "sid": "sK7gyGm1kfEUc"
  },
  "success": true
}

I've tried removing the Reactive Extensions references, but that doesn't help.

So what happened here?

Update

I created a new project in VS2013 and copied the source code from the original solution. That's all the code in the solution as it was just a playground solution.

I then added the JSON.NET library using NuGet (as before), ran the solution and it simply works as expected. I then added the reactive extensions libraries through NuGet as before and the solution still worked as expected. I did not change the source code at any point (as I did not use the reactive extensions in code yet in the original solution)

So I have no idea what caused it in the original solution (which still doesn't work)

Update 2

I was running the working version of the code multiple times and at some point without changing anything the same RuntimeBinderException started popping up again.

I've checked the response from the server, it's exactly the same as before. The irrelevant code I was talking about:

public async Task<string> LoginAsync(string username, string password)
{
    var request = new Request(hostname, ApiName.SYNO_API_AUTH, 2, ApiPath.AUTHCGI, ApiMethod.LOGIN);
    request.AddParameter("account", username);
    request.AddParameter("passwd", password);
    request.AddParameter("format", "sid");

    var responseText = await client.DownloadStringTaskAsync(request.ToString());    
    var response = await JsonConvert.DeserializeObjectAsync<dynamic>(responseText);
    return response.success == TRUE ? response.data.sid : String.Empty;
}

This is the first method that is called and now once again, the last line throws the RuntimeBinder exception. And I'm pretty confident that if I were to copy everything to a new solution it'll just work again. (which I will do)

Update 3

So now I've got the solution that stopped working. I took the entire content of Program.cs (since this is just a console app for testing) and copied it to a new solution. Added the package references through nuget and executed the app, it simply works.

So it seems that for some reason visual studio is doing something that stops it from working.

Update 4

For the solution that does not work. If I debug the solution from within Visual Studio I get the RuntimeBinderException if however, I open the bin/Debug directory and execute the program directly it runs just fine. If I run the solution from within Visual Studio without debugging it runs just fine. So I'm running into an issue when the debugger is enabled. I've also found another question with a similar problem: RuntimeBinderException when parsing json with Newtonsoft.Json

Community
  • 1
  • 1
TimothyP
  • 21,178
  • 26
  • 94
  • 142
  • Could you add the "irrelevant" code back in? The only logical explanation is that `responseText` isn't what you're expecting it to be, or that you're running a different version of `JSonConvert.DeSerializeObjectAsync`. – cwharris Dec 10 '13 at 18:13
  • It would seem the answer suggested here: http://stackoverflow.com/questions/2954531/lots-of-first-chance-microsoft-csharp-runtimebinderexceptions-thrown-when-dealin does solve the problem to some extend, allowing me to debug the app again – TimothyP Dec 11 '13 at 06:22
  • Thanks for all the updates! I ran into the same issue today, where something that had been running just fine suddenly stopped working and needed the new syntax. Removing the debugger fixed my immediate problems, and I'll looking into a more permanent fix later on :) – Rachel Mar 01 '19 at 15:17

2 Answers2

2

Since neither the Json.NET or Rx-Main packages have any mutual dependencies outside the BCL, it is hard to see the package installation as the source of problem. This is a red herring. To be absolutely sure, check there are no Rx dlls in bin output.

Either your code, or something else has changed. Did you add/remove any using statements that could introduce issues with extension methods? Are you sure the code hasn't changed at all? Are you sure the service response is the same? Did the Json.NET package version get changed?

My guess is that at some point your service stopped returning the success property, and coincidentally started returning it again when you changed the code.

James World
  • 29,019
  • 9
  • 86
  • 120
  • I'll verify all of that and get back to you. I'll also take the source and post it in a new project. The service has not changed as it's simply the API of my Synology NAS. – TimothyP Dec 10 '13 at 09:23
  • Created a new solution and copied everything, works like charm... (see updated question). It's like magic... or voodoo for that matter – TimothyP Dec 10 '13 at 10:03
2

I hit this exact issue in VS 2015.

The fix was to enable "Just My Code" in Tools > Options > Debugging > General.

Justin Slone
  • 451
  • 4
  • 5
  • For me, I agree. It looks like a fatal exception when this is thrown while debugging. Sure enough, if you just hit F10 enough it will push through it and end up working. "Just My Code" would work equivalently as it hides first chance exceptions that are caught in 3rd party code. – Andrew Arnott Aug 15 '16 at 14:44