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