I'm having an issue while trying to read a json in unity. I get this message "ArgumentException: JSON parse error: Invalid value.". My JSON looks like:
[{"equipo":"Boca","pj":"5","pg":"3","pp":"2"}] and it is ok in unity.
Here is my info class
[Serializable]
public class Response
{
public string equipo;
public int pj;
public int pg;
public int pp;
}
And here is the coroutine that I call in the awake function
IEnumerator RequestCorutine()
{
var req = new WWW("http://localhost/test/item.php?team=Boca");
yield return req;
print(req.text);
//var json = req.text;
string json = System.Text.Encoding.UTF8.GetString(req.bytes, 3,
req.bytes.Length - 3);
Response response = JsonUtility.FromJson<Response>(json);
print("Equipo: " + response.equipo + " PJ: " + response.pj + " PG: " +
response.pg + " PP: " + response.pp);
}
I get the error in this line: Response response = JsonUtility.FromJson<Response>(json);
I apologize for my English, is not that good. Thanks.
[{"equipo":"Boca","pj":"5","pg":"3","pp":"2"}]
should be
{"equipo":"Boca","pj":5,"pg":3,"pp":2}
because square brackets are used to declare arrays in json. You were declaring a List<Response> instead of a single Response. Also, I removed the quotes around the numbers.
Related
Dears,
I am querying Spotify API using the following code
public Spotify_Search_Result Search(string artist_name, string song_name, int limit=1) {
Spotify_Search_Result result = new Spotify_Search_Result();
string text = artist_name + "%20" + song_name;
//string text = artist_name + "+" + song_name;
//string text = artist_name + " " + song_name;
//string text = Uri.EscapeDataString(artist_name) + " " + Uri.EscapeDataString(song_name);
//string text = Uri.EscapeDataString(artist_name) + "%20" + Uri.EscapeDataString(song_name);
//string text = Uri.EscapeDataString(artist_name) + "+" + Uri.EscapeDataString(song_name);
string url = "https://api.spotify.com/v1/search";
string query = url +
"?q="+
text+
"&type=track"+
"&offset=0"+
"&limit="+
limit.ToString();
HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(query);
webRequest.Method = "GET";
webRequest.ContentType = "application/json";
webRequest.Accept = "application/json";
webRequest.Headers.Add("Authorization", "Bearer " + access_token);
String json = null;
try
{
HttpWebResponse resp = (HttpWebResponse)webRequest.GetResponse();
using (Stream respStr = resp.GetResponseStream())
{
using (StreamReader rdr = new StreamReader(respStr, Encoding.UTF8))
{
//should get back a string i can then turn to json and parse for accesstoken
json = rdr.ReadToEnd();
rdr.Close();
}
}
}
catch (Exception ex) {
Console.WriteLine("Spotify search result error: " + ex.Message + " ["+artist_name+"]-["+song_name+"]" );
}
if (json != null)
{
result = JsonConvert.DeserializeObject<Spotify_Search_Result>(json);
}
return result;
}
Problem: for certain values of artist_name and song_name this code returns no matching items.
Example: artist_name=Delta V
song_name=Il primo giorno del mondo
variable json value will be:
{
"tracks" : {
"href" : "https://api.spotify.com/v1/search?query=Delta+V+Il+Primo+Giorno+Del+Mondo&type=track&offset=0&limit=20",
"items" : [ ],
"limit" : 20,
"next" : null,
"offset" : 0,
"previous" : null,
"total" : 0
}
}
if I type same artist_name and song_name in SpotifyForDevelopers console I get a good match.
Now...where is the problem? I think it is the way I format the "text" and pass it to the API. I am not sure.
As you see from code I have tried different ways of formatting "text" variable.
Any hint on what I am doing wrong?
Thanks!
I think your code is correct and the problem could lie with the "market" parameter, i.e. songs can be available for some countries and unavailable for others.
Your example query will return the right result if you set the market to Italy (IT) but not when set to United States (US), for example (notice the added market=IT):
https://api.spotify.com/v1/search?query=elta%20V%20Il%20primo%20giorno%20del%20mondo&type=track&offset=0&limit=20&market=IT
Maybe setting the market correctly might help to reduce/avoid the issue.
I've been looking around and all of the answers I've found are either not C#, use the V2.0 API or use a method that doesn't return a valid result for videos with embedding disabled.
Here's what I'm currently using, from a response I found a while back:
public string GetYouTubeTitle(string url)
{
string id = GetArgs(url, "v", '?');
WebClient client = new WebClient();
return "YouTube Video: \"" + GetArgs(client.DownloadString("http://youtube.com/get_video_info?video_id=" + id), "title", '&') + "\"";
}
public string GetArgs(string args, string key, char query)
{
int iqs = args.IndexOf(query);
string querystring = null;
if (iqs != -1)
{
querystring = (iqs < args.Length - 1) ? args.Substring(iqs + 1) : string.Empty;
NameValueCollection nvcArgs = HttpUtility.ParseQueryString(querystring);
return nvcArgs[key];
}
return string.Empty;
}
It works perfectly the first time round, but the second video I tested returned the error: "&errorcode=150&reason=This+video+contains+content+from+Studio71_1_1.+It+is+restricted+from+playback+on+certain+sites"
My goal is just to get the title of a youtube video given the URL. But everything I'm seeing is either vague as hell or is only valid for the 2.0 API which doesn't even work anymore.
EDIT: And at some point I might want to add more to the response such as the length of the video. So I would prefer to have the API working than to just use something like get_video_info if possible.
EDIT:
For completeness and to help anyone who might be looking at this later on this is what I've got now that works like I want:
string titleurl = "https://www.googleapis.com/youtube/v3/videos?part=snippet&id=" + GetArgs(url, "v", '?') + "&key=" + apikey;
string timeurl = "https://www.googleapis.com/youtube/v3/videos?id=" + GetArgs(url, "v", '?') + "&part=contentDetails&key=" + apikey;
HttpWebRequest titlerequest = (HttpWebRequest)WebRequest.Create(titleurl);
HttpWebResponse titleresponse = (HttpWebResponse)titlerequest.GetResponse();
Stream titlestream = titleresponse.GetResponseStream();
StreamReader titlereader = new StreamReader(titlestream);
string titlejson = titlereader.ReadToEnd();
Newtonsoft.Json.Linq.JObject jObject = Newtonsoft.Json.Linq.JObject.Parse(titlejson);
string title = (string)jObject["items"][0]["snippet"]["title"];
HttpWebRequest timerequest = (HttpWebRequest)WebRequest.Create(timeurl);
HttpWebResponse timeresponse = (HttpWebResponse)timerequest.GetResponse();
Stream timestream = timeresponse.GetResponseStream();
StreamReader timereader = new StreamReader(timestream);
string timejson = timereader.ReadToEnd();
Newtonsoft.Json.Linq.JObject jObjectTime = Newtonsoft.Json.Linq.JObject.Parse(timejson);
string time = ParseTime((string)jObjectTime["items"][0]["contentDetails"]["duration"]);
if (title.Length > 0 && time.Length > 0 && time != "0")
return "YouTube Video: \"" + title + "\" (" + time + ")";
else return error; //error is a preset generic error string
It's probably not the cleanest code around, but it's doing what I want. So I don't really mind.
You can get the video title by using the YouTube Data API v3:
You need to get your API key from Here:
Make a GET request to this URL as described in the documentation:
https://www.googleapis.com/youtube/v3/videos?part=snippet&id=v2AC41dglnM,kTHNpusq654&key=YourAPIKeyHere
Parse the response you get with something like Json.NET:
try this:
First you need to install VideoLibrary on your visual studio package manager :
**Install-Package VideoLibrary**
using VideoLibrary;
Let's make a function to get the YouTube video title:
public string getTitle (string url){
YouTube ytb = YouTube.Default; //starting point for YouTube actions
var vid = ytb.GetVideo(url); // gets a Video object with info about the video
string ttl = vid.Title;//get video Title
return ttl;
}
I have managed to store data, but I can't retrieve it and i would be so grateful if someone could just help me get at least 1 example working.
First I am storing data when the user signs up:
public void SetupNewParseMember(ParseUser user)
{
ParseObject gameScore = new ParseObject("GameScore");
gameScore["cash"] = 500;
gameScore["playerName"] = user.Username;
gameScore["HighestCash"] = 500;
gameScore["GamesPlayed"] = 0;
Task saveTask = gameScore.SaveAsync();
}
This works fine, I can see the data in parse and all seems ok..
The problem is when i try to retrieve the objects.
public void SetupMainScreen(ParseUser user)
{
var query = ParseObject.GetQuery("GameScore").WhereEqualTo("playerName", user.Username);
query.FindAsync().ContinueWith(t =>
{
IEnumerable<ParseObject> results = t.Result;
List<ParseObject> resultsList = results.ToList();
DealWithResults(resultsList, user);
});
}
public void DealWithResults(List<ParseObject> resultsList, ParseUser me)
{
userGamesPlayed = resultsList[1].Get<int>("GamesPlayed");
userHighestCash = resultsList[2].Get<int>("HighestCash");
userCash = resultsList[3].Get<int>("Cash");
WelcomeText.text = "Welcome, " + me.Username + "\n" +
"Cash: $" + userCash + "\n" +
"Highest Cash: $" + userHighestCash + "\n" +
"Games Played: " + userGamesPlayed;
}
First I tried just making changes to the unity ui from inside the Query but that did not work, So i made an outside function and passed the results to it that way, and that still does not work?
I tried to debug what i was getting in the list with this:
foreach (var res in resultsList)
{
Debug.Log("Class Name = " + res.ClassName + "| Keys are: " + res.Keys);
}
But all it returned was:
Class Name = GameScore| Keys are: System.Collections.Generic.Dictionary`2+KeyCollection[System.String,System.Object]
Can anyone offer any insights?
EDIT2:
ok so first i found results list and its contents
http://i.imgur.com/IKcBbey.png
Then if i open it, it seems to be null ref?
http://i.imgur.com/VmSpi9c.png
But if i go digging, i found the info i need all the way down here
http://i.imgur.com/1Wwu5uc.png
Now just need to work out how to get it?
As there is only one set of data it is always accessible through resultsList[0]. What you want is:
double cash = (double)resultsList[0]["cash"];
string playerName = (string)resultsList[0]["playerName"];
double highestCash = (double)resultsList[0]["HighestCash"];
int gamesPlayed = (int)resultsList[0]["GamesPlayed"];
Though you probably want to check that resultsList is not null and contains one element before you try to dereference it.
Also as your ParseObject appears to be a Dictionary you might find this MSDN page useful.
Ended up solving it.. Much different to the examples...
I had to make a coroutine that called a function on callback to access the variables outside of the query.
I called it with
StartCoroutine(SetupMainScreen(me, DealWithResults));
then called this.
public IEnumerator SetupMainScreen(ParseUser user, Action<GameScore> callback)
{
var query = ParseObject.GetQuery("GameScore").WhereEqualTo("playerName", user.Username).FirstOrDefaultAsync();
while (!query.IsCompleted)
{
yield return null;
}
if (query.IsFaulted || query.IsCanceled)
{
Debug.Log("Getting of GameScores faulted or cancelled...");
}
else
{
var obj = query.Result;
if (obj != null)
callback(new GameScore(obj.Get<int>("cash"),obj.Get<string>("playerName"),obj.Get<int>("HighestCash"),obj.Get<int>("GamesPlayed")));
}
}
public void DealWithResults(GameScore gs)
{
WelcomeText.text = "Welcome, " + gs.Username + "\n" +
"Cash: $" + gs.Cash + "\n" +
"Highest Cash: $" + gs.HighestCash + "\n" +
"Games Played: " + gs.GamesPlayed;
}
And i just made a class to hold the objects.. Hopefully this helps someone else.
Below is my code,
List<string> modified_listofstrings = new List<string>();
string sJSON = "";
System.Web.Script.Serialization.JavaScriptSerializer jSearializer =
new System.Web.Script.Serialization.JavaScriptSerializer();
resulted_value = final_resulted_series_name + ":" + period_name + ":" + period_final_value;
modified_listofstrings.Add(resulted_value);
json_resultedvalue = JsonConvert.SerializeObject(resulted_value);
modified_listofstrings.Add(json_resultedvalue);
sJSON = jSearializer.Serialize(modified_listofstrings);
return sJSON;
But on following line ,
sJSON = jSearializer.Serialize(modified_listofstrings);
I am getting an error as Cannot implicitly convert type string to system.collection.generic.list
Let me fix your approach - instead of building JSON strings using your data, and then putting them into a list and trying again to serialize that, what you should do is build your data structure and then serialize it in one go.
Since I couldn't figure out the structure of the data in your post, here is an example with a different format:
public struct Person
{
public string Name;
public int Age;
public List<string> FavoriteBands;
}
The easiest way to serialize it is to use Newtonsoft JSON. If you have an object called person, then you would serialize it using
string json = JsonConvert.SerializeObject(person);
Now suppose you have a list of these objects i.e. List<Person> people = GetTheListFromSomewhere();, then you would serialize it using
string json = Newtonsoft.Json.JsonConvert.SerializeObject(people);
Go ahead and try it!
resulted_value = final_resulted_series_name + ":" + period_name + ":" + period_final_value;
This is not a valid JSON. It must have key, value format separated by comma. I guess it should be:
resulted_value = "{series_name : \"" + final_resulted_series_name + "\",period_name: \"" + period_name + "\",period_final_value: \"" + period_final_value + "\"}";
so the result should be something like this:
{series_name: "whatever_series_name_is", period_name:
"whatever_period_name_is",period_final_value:
"whatever_period_final_value_is"}
heres my JSON
var postData =
"{ \"registration_ids\": [ \"" + pushNotificationState.RegistrationId + "\" ], "+
"\"data\": {\""+ pushNotificationState.NotificationData.NotificationData + "\"}";
registration Id and notification data are variables. I'm getting a 400 response from the GCM sever saying JSON is incorrect format. Can anyone pick where I have gone wrong?
Cheers
You have one open { but have two close }.
var postData = "{ \"registration_ids\": [ \"" + pushNotificationState.RegistrationId + "\" ], " + "\"data\": \""+ pushNotificationState.NotificationData.NotificationData + "\"}";
Use some Json tools, instead of creating your string by hand. Otherwise you'd have problems if some of string variables contain {,}," etc.
var json = JsonConvert.DeserializeObject(
new {
registration_ids = new[] { pushNotificationState.RegistrationId },
data = pushNotificationState.NotificationData.NotificationData
});
var postData = "{ \"registration_ids\": [ \"" + pushNotificationState.RegistrationId + "\" ]}, "+
"\"data\": {\""+ pushNotificationState.NotificationData.NotificationData + "\"}";
Try replacing it with that.
You can use the below code to create the request object, then convert to json.
public class GCMRequest
{
public GCMRequest()
{
data = new PayLoad();
}
public List<string> registration_ids;
public PayLoad data;
}
public class PayLoad
{
public string key;
}
you can create the request as below
GCMRequest req = new GCMRequest();
List<string> tokens = new List<string>();
// .. fill the tokens to the 'tokens' list
req.registration_ids = tokens;
req.data.key = "Hi, how are you"; // message you want to send
string json = new JavaScriptSerializer().Serialize(req);
Hope this will help.