I've had a look at a few threads but what I'm aiming for I can't seem to find.
I have the following JSON strings returned:
On success:
{"success":{"username":"key"}}
On Error:
{"error":{"type":101,"address":"/","description":"link button not pressed"}}
I need to be able to de-serialize these into a class and determine whether I've got an error or a success message to carry on doing it. Any ideas on how to achieve this?
thanks,
Adam
No need to declare a lot of tiny classes. dynamic keyword can help here.
dynamic jObj = JObject.Parse(json);
if (jObj.error!= null)
{
string error = jObj.error.description.ToString();
}
else
{
string key = jObj.success.username.ToString();
}
One option is to use http://nuget.org/packages/newtonsoft.json - you can either create your own custom class to deserialize into or use dynamic as the target type.
var result = JsonConvert.DeserializeObject<Result>(jsonString);
class Result
{
public SuccessResult success { get; set; }
public ErrorResult error { get; set; }
}
class SuccessResult
{
public string username { get; set; }
}
class ErrorResult
{
public int type { get; set; }
public string address { get; set; }
public string description { get; set; }
}
If you need just to check for success, it is possible to just check result.StartsWith("{\"success\":") to avoid unnecessary parsing. But this should only be done if you have guarantee that the JSON string will always be exactly like this (no extra whitespaces etc.) - so it is usually only appropriate if you own the JSON generation yourself.
This answer covers most options, including rolling your own parser and using JSON.Net:
Parse JSON in C#
You could also just write a regex if the format is going to be that simple...
Related
I receive some jsons that are supposed to represent a legal object of some class.
I wish to validate this is indeed so. So I deserialized the strings to see if this succeeds. This is very time consuming as the strings gets very large in some cases and there are many of them. I am therefore looking for a different approach.
I thought of creating a regExp from the class's definition and check that the jsons I receive are compatible. Is there a way to generate a regExp from a C# class?
Any other suggestions will help as well.
Thanks
Use JSON schema validator by newtonsoft , more details here
public class JsonSchemaController : ApiController
{
[HttpPost]
[Route("api/jsonschema/validate")]
public ValidateResponse Valiate(ValidateRequest request)
{
// load schema
JSchema schema = JSchema.Parse(request.Schema);
JToken json = JToken.Parse(request.Json);
// validate json
IList<ValidationError> errors;
bool valid = json.IsValid(schema, out errors);
// return error messages and line info to the browser
return new ValidateResponse
{
Valid = valid,
Errors = errors
};
}
}
public class ValidateRequest
{
public string Json { get; set; }
public string Schema { get; set; }
}
public class ValidateResponse
{
public bool Valid { get; set; }
public IList<ValidationError> Errors { get; set; }
}
I'm trying to use the Giant Bomb API. I also use Newtonsoft.Json to deserialize the response object. I've a problem when I try to convert the response to classes. I've a problem with something who looks like an array. I don't understand what it exactly is and which using ref i should use to make it work ...
Here is the syntax : public ApiSearchResult[] results { get; set; }
Here is the tutorial : http://social.technet.microsoft.com/wiki/contents/articles/26920.winrt-using-giant-bomb-api-to-get-games-information.aspx
After looking at the documentation, it appears that ApiSearchResult is supposed to be Result. Try changing public ApiSearchResult[] results { get; set; } to
public Result[] results { get; set; }.
I am going crazy... I am missing something and I can't see what?!?!
I have created a property called "GAME_SETTINGS" inside the gameSparks admin area and have included this in it:
{
"AppVersionIOS": 1,
"AppVersionAndroid": 1
}
I am then trying to retrieve it inside Unity like this:
new GameSparks.Api.Requests.GetPropertyRequest().SetPropertyShortCode("GAME_SETTINGS").Send((response) => {
if (!response.HasErrors) {
Debug.Log("Setting Achieved: "+response.JSONString);
} else {
Debug.Log("Error Getting Settings");
}
});
I can see that I am getting the settings in my Debug.Log:
Setting Achieved: {"#class":".GetPropertyResponse","property":{"AppVersionIOS":1,"AppVersionAndroid":1},"requestId":"XXXXXXXXXXXXXXX","scriptData":null}
My question is though... How do I get the properties AppVersionIOS and AppVersionAndroid inside an Dictionary so I can call on them from other scripts...
Really hoping for help in this matter and thanks in advance :-)
I actually work for GameSparks and noticed your question so set up an account to answer you.
The property values returned in the JSON are of nullable type : https://msdn.microsoft.com/en-us/library/1t3y8s4s.aspx
Best practice is to parse the values before they are cached in a Dictionary or otherwise.
The following code should allow you to get those properties, then you may store them in a dictionary as you see fit.
public void GetProperties()
{
new GameSparks.Api.Requests.GetPropertyRequest()
.SetPropertyShortCode("GAME_SETTINGS")
.Send((response) =>
{
if (!response.HasErrors)
{
print(response.JSONString);
int androidProperty = (int)response.Property.GetInt("AppVersionAndroid");
int IOSProperty = (int)response.Property.GetInt("AppVersionIOS");
print("AndroidProperty:" + androidProperty);
print("IOSProperty:" + IOSProperty);
}
else
{
Debug.LogWarning(response.JSONString);
}
});
}
Hopefully this solves your problem. If you have any other questions please feel free to head to our website and log a ticket with us.
Regards, Patrick.
Notice: This answer assumes that the API doesn't have a way of converting this into a nice object which you can easily manipulate / parse, so it converts it itself using some class. It's however very likely that your API offers such a function somewhere, so you'd be better be looking in the documentation again. I guess it's somewhere near https://api.gamesparks.net/#getpropertyrequest .
You have the JSON document already, all you have to do is parse it. That'd be easier in a JavaScript file than in C#, but you can also use the JsonUtils class there, see http://docs.unity3d.com/Manual/JSONSerialization.html . Let http://json2csharp.com/ convert that JSON to a class layout for you and you get
public class Property
{
public int AppVersionIOS { get; set; }
public int AppVersionAndroid { get; set; }
}
public class RootObject
{
public string __invalid_name__#class { get; set; }
public Property property { get; set; }
public string requestId { get; set; }
public object scriptData { get; set; }
}
Now just take the string and serialize it into an RootObject.
new GameSparks.Api.Requests.GetPropertyRequest().SetPropertyShortCode("GAME_SETTINGS").Send((response) => {
if (!response.HasErrors) {
Debug.Log("Setting Achieved: "+response.JSONString);
//Serialization
var info = JsonUtility.FromJson<RootObject>(response.JSONString);
//Print the AppVersionIOS property
Debug.Log("App Version iOS: " + info.Property.AppVersionIOS);
} else {
Debug.Log("Error Getting Settings");
}
});
You might need some mofication in the data types of your class (e.g. make object scriptData to string scriptData if there can be an actual string in it), but that should be it. Have fun.
I'm doing a query and get as result something like this, which i put into a Hashtable
{"success":"true", "result":[{"type":"email", "address":"aaasd#asd.com"},{"type":"email", "address":"aaasddee#dse.com"}]}
then i do
return hashtable["result"];
so I only have this left
[{"type":"email", "address":"aaasd#asd.com"},{"type":"email", "address":"aaasddee#dse.com"}]
but my problem is that I don't know how to iterate through every object from "result" to fill my own objects. I was searching for a solution but the only answer I found was to use
foreach(DictionaryEntry entry in searchResult) {
//do something<br>
}
When I iterate through the Hashtable like this I can only use the properties entry.Key and entry.Value but I can't say which value for a specific key I need. Any suggestions are welcome.
You can get it using deserialising using JSON.NET as shown below :-
var result = JsonConvert.DeserializeObject<dynamic>(searchResult);
You can create your class like below :-
public class RootObject
{
public string type { get; set; }
public string address { get; set; }
}
For more information :-
http://james.newtonking.com/json/help/index.html?topic=html/SerializingJSON.htm
Create a class that matches the signature of the result collection like:
public class Result
{
public string Type { get; set; }
public string Address { get; set; }
}
Then use Json.NET to parse the result node into a List<Result>. There is plenty of documentation online on how to use the Json.NET library.
Hope that helps,
Rob
I am working with an API that returns data in JSON format (as far as I can tell, this is my first time working with a true API or JSON). I read a bunch about working with JSON in C#, and eventually got the Newtonsoft.Json library. Unfortunately, I am having a hard time converting the response I am receiving into a C# class following the examples that exist in the Newtonsoft documentation.
Here is an example of the data returned by this API:
{"name":{"id":1,"name":"name","pID":1,"revisionDate":1390580000000}}
And heres what I have so far:
public class apiDataObject
{
public long id {get; set;}
public string name { get; set; }
public int pID { get; set; }
public long revisionDate { get; set; }
}
public long getID()
{
try
{
data = WebRequest.Create(baseURL);
retData = data.GetResponse().GetResponseStream();
}
catch (Exception exception)
{
outputBox.AppendText(Environment.NewLine + exception.ToString());
}
retDataReader = new StreamReader(retData);
returnedData = retDataReader.ReadToEnd();
outputBox.AppendText(returnedData);
apiDataObject test = new apiDataObject();
JsonConvert.PopulateObject(returnedData, test);
return test.id;
}
I have also tried replacing the JsonConvert.PopulateObject(returnedData, test) with:
apiDataObject test = JsonConvert.DeserializeObject<apiDataObject>(returnedData)
The problem is that my "test" object is always empty after the code finishes. I have stepped through the code, and everything works great until I get to the lines where the test object is created, and supposedly populated. I also tried the inbuilt Microsoft libraries and had the exact same issue. I am honestly stumped, I have spent 2 or 3 hours looking at these few lines of code and tons of documentation and samples of the Newtonsoft.Json library, but simply cant figure out where I've gone wrong here. Any help would be greatly appreciated.
From the JSON you posted, its actually a dictionary type: I changed your method to show you, I tested it out and it works.
public long GetID()
{
var testDict = new Dictionary<string, apiDataObject>();
var returnedData = "{\"name\":{\"id\":1,\"name\":\"name\",\"pID\":1,\"revisionDate\":1390580000000}}";
JsonConvert.PopulateObject(returnedData, testDict);
return testDict["name"].id;
}
Running your original code throws an exception telling you that it doesn't know what to do with the first "name".
Just in case anyone ever comes across this in a search, I figured out an alternative solution to working with this type of data as well. The Newtonsoft.Json library contains a function called DeserializeObject. So for the sample data of:
{"name":{"id":1,"name":"name","pID":1,"revisionDate":1390580000000}}
You can create an object that looks like:
public class Name
{
public int id { get; set; }
public string name { get; set; }
public int pID { get; set; }
public long revisionDate { get; set; }
}
public class RootObject
{
public Name name { get; set; }
}
and then use:
JsonConvert.DeserializeObject<RootObject>(returnedData);
to convert the json into the object without having to use a dictionary.
This is probably "common knowledge", considering the object code can easily be created using the json2csharp converter someone linked earlier, but I was unable to find any direct explanation about when to use the DeserializeObject function or why it should be used versus PopulateObject.