I'm trying to get an entry of a json array into a messagebox but i can't seem to get the entry it always gives me
Newtonsoft.Json.JsonReaderException: 'Unexpected character encountered while parsing value: C. Path '', line 0, position 0.'
No matter what i do here is the json i use:
[
{
"code": 200,
"token": "yourtokenhere",
"id": "youridhere",
"user": "user",
"message": "Successfully connected"
}
]
Here is what i got so far:
string json = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\zero.json";
login fetch = new login();
Newtonsoft.Json.JsonConvert.PopulateObject(json, fetch);
MessageBox.Show(fetch.user);
And here is the C# class i made:
class login
{
public string code;
public string token;
public string id;
public string user;
public string message;
}
Thanks in advance!
EDIT: The full code is available here
Your problem is two-fold.
One issue is that you want to deserialize an array into an object. Other answers here already have addressed this issue.
The other issue, the one responsible for the error in your question, is that you used the Newtonsoft.Json.JsonConvert.PopulateObject method incorrectly. Look at its documentation:
public static void PopulateObject(
string value,
Object target
)
Parameters
value
Type: SystemString
The JSON to populate values from.
target
Type: SystemObject
The target object to populate values onto.
Note that this method expects the Json string data as first argument, not a file path!
So what happens in your code is the variable json gets assigned a file path to your Json file (string json = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\zero.json";). The string variable json will now have a content like #"C:\Users\UserName\AppData\Roaming\zero.json".
Your code passes this string as json data to the PopulateObject() method. But since this string is not json data (it's just the file path), PopulateObject() fails. (Note that the error message complains about the json data starting unexpectedly with a C.)
One possibility of implementing what you want to do is to first read the Json file content into a string, and then pass this to the Json deserializer (in the same way as demonstrated by the other answers):
string filePath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\zero.json";
string json = File.ReadAllText(filePath);
List<login> fetch = Newtonsoft.Json.JsonConvert.DeserializeObject<List<login>>(json);
JSON data is an array and you are trying to deserialize it into an object.
Try below code:
List<login> fetch = Newtonsoft.Json.JsonConvert.DeserializeObject<List<login>>(json);
Please check
JsonConvert.DeserializeObject
Related
I'm trying to Parse two objects sent via Express to my unity client into c# objects.
Here I am sending the search results of a mongoose.model.find
res.send({account: accountData, score: scoreData})
Over in my Unity client this is the function that grabs the data above from my node.js server. I recieve the information here as the www.downloadHandler.text
using (UnityWebRequest www = UnityWebRequest.Post(hostURL + "Login", loginForm))
{
yield return www.SendWebRequest();
if (www.result != UnityWebRequest.Result.Success)
{
Debug.Log("Error Sending Login Detail: " + www.error);
}
else
{
if (www.responseCode == 200)
{
Debug.Log(www.downloadHandler.text);
thisUser = username;
menu.LoginPassed();
leaderboard.LoadPlayerScoreData(www.downloadHandler.text);
}
else
{
Debug.Log("Login Unsuccessful. Reason: " + www.downloadHandler.text);
}
}
}
}
for reference here is the output of the Debug.Log(www.downloadHandler.text) so we can see what we are working with:
{
"account":[
{
"_id":"62fc40709bc9c241c7f650cd",
"username":"BaggyJ",
"password":"12345",
"email":"#hotmail",
"hhs":0,
"level":1,
"xp":0,
"currency":0,
"premiumCurrency":0,
"__v":0
}
],
"score":[
{
"_id":"62fb4efe6e3a942138405b3e",
"username":"BaggyJ",
"score":420,
"__v":0
}, // ...
]
}
Here I am recieving the information as intended, the account data contains the player account informaton and the score data is an array of the players best scores. So far so good!
The next step obviously, is to parse this information into a usable C# object. I attempted to do this in the same way I had previously accomplished in this project.
I will show you here the solution for this I'm using that does not work, and an example of the solution when it does work.
Firstly, what I have thats not working:
I created two C# serialized classes to represent the information.
[System.Serializable]
public class DataPackage
{
public string account;
public string score;
}
And
[System.Serializable]
public class DataPackages
{
public DataPackage[] dataPackages;
}
Finally, I use the JSON Utility function to parse the data string included above
public DataPackages ParseData(string jsonText)
{
DataPackages dataPackages = JsonUtility.FromJson<DataPackages>("{\"dataPackages\":" + jsonText + "}");
return dataPackages;
}
If I attempt to use the above code the dataPackages.dataPackages object is always null.
The function is meant to result in an object with two strings, the first to represent the account data and the second to represent the score data.
These two string will then be parsed a second time into their final C# objects for use.
It is worth noting here that the parsing tools for account data and score data are built the same way and function as expected. I will include one below for reference:
[System.Serializable]
public class ScorePacket
{
public string username;
public string score;
}
[System.Serializable]
public class ScorePackets
{
public ScorePacket[] scorePackets;
}
public ScorePackets ParseScore(string jsonText)
{
ScorePackets scorePackets = JsonUtility.FromJson<ScorePackets>("{\"scorePackets\":" + jsonText + "}");
return scorePackets;
}
The above code will return an c# object where I can access its data as such: scorePackets.scorePackets[0].score
Any insight into why I cannot accomplish this with DataPackages would be greatly appreciated!
EDIT
So I've gotten it a little closer but not quite.
I have replaced:
DataPackages dataPackages = JsonUtility.FromJson<DataPackages>("{\"dataPackages\":" + jsonText + "}");
With:
DataPackages dataPackages = JsonUtility.FromJson<DataPackages>("{\"dataPackages\":[" + jsonText + "]}");
This successfully creates a C# object with the correct fields HOWEVER both of these field are empty.
Debug.Log(dataPackages.dataPackages[0].score)
Debug.Log(dataPackages.dataPackages[0].account)
Both return empty strings.
Edit#2
We are getting so close I can taste it.
So in addition to the above changes I have also made the following change to my node.js server:
res.send({account: accountData.toString(), score: scoreData.toString()})
Now if I:
Debug.Log(dataPackages.dataPackages[0].score.ToString());
Debug.Log(dataPackages.dataPackages[0].account.ToString());
My output is:
[object Object],[object Object],[object Object],[object Object],[object Object]
[object Object]
.ToString() failed to get the json text for these objects
I figured it out!
I needed to change the way I declared my DataPacket class from containing strings to containing object arrays.
[System.Serializable]
public class DataPackage
{
public AccountPacket[] account;
public ScorePacket[] score;
}
Solved my problems
I have designed a report using the Community Designer, and, during design I used a JSON string as my data source. I understand I can point a different datasource when instantiating my report during runtime, but I couldn't find any information on whether I can pass a linearised JSON string to the report as a new datasource to prepare the report from. I'm using the open source version of FastReport.
The beginning of the report itself (I can post the rest of the file, but it's only the layout, and I'm not sure it pertains to this case):
<?xml version="1.0" encoding="utf-8"?>
<Report ScriptLanguage="CSharp" ReportInfo.Created="09/02/2021 15:21:14" ReportInfo.Modified="09/02/2021 16:09:54" ReportInfo.CreatorVersion="2021.3.28.0">
<Dictionary>
<JsonDataSourceConnection Name="Connection" ConnectionString="rijcmlqX8KZxth3MD10DNCoulBzT/ufTygbxgOYbNZVv0BNypI...uvs">
<JsonTableDataSource Name="JSON" DataType="FastReport.Data.JsonConnection.JsonParser.JsonArray" Enabled="true" TableName="JSON">
Right now this is what I have:
Report report = new Report();
report.Load("reportTemplate.frx");
report.Prepare();
var reportExport = new FastReport.Export.Image.ImageExport();
report.Export(reportExport, "report.jpeg");
By running this, I get the exact same report that I had using the Json string I provided when designing the report. On https://programmer.ink/think/using-fastreport-report-report-tool-to-generate-report-pdf-document.html they mention you can use report.LoadFromString(string) to pass either a Base64 or a UTF-8 Json string to be used as a datasource for the report. However, when I pass the linearised json:
Vehicle fullVehicleInfo = await _vehicleDataService.GetFullVehicleInfoAsNoTracking(_vehicleListingViewModel.SelectedVehicle);
ReportObject ro = new(fullVehicleInfo, DateTime.Now.AddMonths(-1), DateTime.Now);
var x = ro.ConvertToJson();
Report report = new Report();
report.Load("reportTemplate.frx");
report.LoadFromString(x);
report.Prepare();
var reportExport = new FastReport.Export.Image.ImageExport();
report.Export(reportExport, "report.jpeg");
The Json created from ro.ConvertToJson is the very same I pasted on the report creation wizard. Yet, I get a The input is not a valid Base-64 string as it contains a non-base 64 character, more than two padding characters, or an illegal character among the padding characters. exception, whereas if I convert that string to Base64 first and pass the encoded string, I get a Cannot load the file. Unknown file format exception.
In https://www.fast-report.com/en/blog/57/show/, they say I must "register" my application data, however, they are using a List<JsonObject>, while my report uses a single JsonObject with listed properties, so I don't think how that fits my situation.
I did try, though, passing a List<ReportObject> consisting of the single ReportObject and calling report.RegisterData(z, "JSON") (after removing the original datasource on the designer, but now I get a The name "JSON" does not exist on the current context, followed by the name of the field trying to access the property.
Just in case, this is an example of the JSON I'm using:
{
"DataInício": "02/08/2021",
"DataFim": "02/09/2021",
"Marca": "Renault",
"Modelo": "Kwid Zen 1.0",
"Placa": "TES-7E15",
"Quilometragem": "1789,00 km",
"PróximoLicenciamento": "08/2021",
"ÚltimoAbastecimento": "25/08/2021",
"ÚltimaManutenção": "28/08/2021",
"ManutençãoJsons": [
{
"KM": "1687,0 km",
"Custo": "R$ 50,00",
"DataHora": "28/08/2021",
"Motorista": "TESTE ARMANDO DE SALLES",
"TipoReparo": "Preventivo",
"TipoManutenção": "Revisão",
"ÁreaManutenção": "Pneus"
}
],
"ViagemJsons": [
{
"Motorista": "TESTE ARMANDO DE SALLES",
"KMInicial": "1569,0 km",
"KMFinal": "1789,0 km",
"Saída": "23/08/2021",
"Entrada": "02/09/2021"
}
],
"AbastecimentoJsons": [
{
"KM": "1,0 km",
"Motorista": "TESTE ARMANDO DE SALLES",
"ValorTotal": "R$ 10,00",
"Litragem": "10,0 l",
"ValorPorLitro": "1,000 R$/l",
"DataHora": "25/08/2021",
"Posto": "carr",
"Combustível": "Gasolina Aditivada",
"FormaPagamento": "Dinheiro"
}
]
}
Is there a way to directly pass a Json string as a datasource to the report?
Also, mind that creating a report using the ReportObject and passing it as a business object works flawlessly, but I still would like to know if I could pass it as a simple Json string.
Yes, you can do it here is a sample code:
static void Main(string[] args)
{
RegisteredObjects.AddConnection(typeof(JsonDataSourceConnection));
JsonDataSourceConnection jsonDataSourceConnection = new JsonDataSourceConnection();
jsonDataSourceConnection.ConnectionString = "Json=Ww0KICB7DQogICAgIk1hbmFnZXJJZCI6IDIzMTcsDQogICAgIkRlc2NyaXB0aW9uIjogIk51bWJlciBvZiBDYWxscyIsDQogICAgIkNvZGUiOiAiUGhvbmUiLA0KICAgICJDb3VudCI6ICIwIiwNCiAgICAiSGVhZGluZyI6ICJTYWxlcyBDYWxsIENvZGUiDQogIH0sDQogIHsNCiAgICAiTWFuYWdlcklkIjogMjMxNywNCiAgICAiRGVzY3JpcHRpb24iOiAiTnVtYmVyIG9mIENhbGxzIiwNCiAgICAiQ29kZSI6ICJTYWxlcyBDYWxsIFR5cGUxIiwNCiAgICAiQ291bnQiOiAiMCIsDQogICAgIkhlYWRpbmciOiAiU2FsZXMgQ2FsbCBDb2RlIg0KICB9LA0KICB7DQogICAgIk1hbmFnZXJJZCI6IDIzMTcsDQogICAgIkRlc2NyaXB0aW9uIjogIk51bWJlciBvZiBDYWxscyIsDQogICAgIkNvZGUiOiAiU2FsZXMgQ2FsbCB0eXBlMiIsDQogICAgIkNvdW50IjogIjAiLA0KICAgICJIZWFkaW5nIjogIlNhbGVzIENhbGwgQ29kZSINCiAgfSwNCiAgew0KICAgICJNYW5hZ2VySWQiOiAyMzE3LA0KICAgICJEZXNjcmlwdGlvbiI6ICJOdW1iZXIgb2YgQ2FsbHMiLA0KICAgICJDb2RlIjogIlNhbGVzIENhbGwgdHlwZSAzIiwNCiAgICAiQ291bnQiOiAiMCIsDQogICAgIkhlYWRpbmciOiAiU2FsZXMgQ2FsbCBDb2RlIg0KICB9LA0KICB7DQogICAgIk1hbmFnZXJJZCI6IDIzMTcsDQogICAgIkRlc2NyaXB0aW9uIjogIk51bWJlciBvZiBDYWxscyIsDQogICAgIkNvZGUiOiAiU2FsZXMgQ2FsbCBUeXBlIDQiLA0KICAgICJDb3VudCI6ICIwIiwNCiAgICAiSGVhZGluZyI6ICJTYWxlcyBDYWxsIENvZGUiDQogIH0sDQogIHsNCiAgICAiTWFuYWdlcklkIjogMjMxNywNCiAgICAiRGVzY3JpcHRpb24iOiAiTnVtYmVyIG9mIENhbGxzIiwNCiAgICAiQ29kZSI6ICJTYWxlcyBDYWxsIHR5cGUgNSIsDQogICAgIkNvdW50IjogIjAiLA0KICAgICJIZWFkaW5nIjogIlNhbGVzIENhbGwgQ29kZSINCiAgfSwNCiAgew0KICAgICJNYW5hZ2VySWQiOiAyMzE3LA0KICAgICJEZXNjcmlwdGlvbiI6ICJOdW1iZXIgb2YgQ2FsbHMiLA0KICAgICJDb2RlIjogIlNhbGVzIENhbGwgVHlwZSA2IiwNCiAgICAiQ291bnQiOiAiMCIsDQogICAgIkhlYWRpbmciOiAiU2FsZXMgQ2FsbCBDb2RlIg0KICB9LA0KICB7DQogICAgIk1hbmFnZXJJZCI6IDIzMTcsDQogICAgIkRlc2NyaXB0aW9uIjogIk51bWJlciBvZiBDYWxscyIsDQogICAgIkNvZGUiOiAiU2FsZXMgQ2FsbCBUeXBlIDciLA0KICAgICJDb3VudCI6ICIwIiwNCiAgICAiSGVhZGluZyI6ICJTYWxlcyBDYWxsIENvZGUiDQogIH0NCl0=;JsonSchema=eyJ0eXBlIjoiYXJyYXkiLCJpdGVtcyI6eyJ0eXBlIjoib2JqZWN0IiwicHJvcGVydGllcyI6eyJNYW5hZ2VySWQiOnsidHlwZSI6Im51bWJlciJ9LCJEZXNjcmlwdGlvbiI6eyJ0eXBlIjoic3RyaW5nIn0sIkNvZGUiOnsidHlwZSI6InN0cmluZyJ9LCJDb3VudCI6eyJ0eXBlIjoic3RyaW5nIn0sIkhlYWRpbmciOnsidHlwZSI6InN0cmluZyJ9fX19;Encoding=utf-8";
jsonDataSourceConnection.CreateAllTables();
Report report = new Report();
report.Dictionary.Connections.Add(jsonDataSourceConnection);
report.Prepare();
report.Design();
}
I wanted to add language support into my new project. I thought of creating a config file, similar to json.
So this is an example file:
{
"LabelTextMainMenu": "This is the main Label",
"LabelTextName": "Please enter your name"
}
Now what I want to reach is this (Classname not existing):
LangConfig config = File.ReadAllText(path/to/language/config);
public string LabelName
{
get {config.LabelTextName}
}
Before I'd write this "LangConfig"-Class myself, i'd like to know if there's something that works in the way I want it?
You can deserialize the config file to typed object via Json.Net (or equivalent package).
Below is the sample implementation :
var configData = File.ReadAllText(path/to/language/config.config);
LangConfig config = JsonConvert.DeserializeObject<LangConfig>(configData);
with the typed object, the properties can be accessed as
public string LabelName
{
get {config.LabelTextName}
}
I'm trying so scrape some info from a JSON response but it fails; I think it may have to do with the way I'm making use of a library I'm new to.
Below is the JSON instance that I'm trying to get data from;
{
"profileChanges":[
{
"changeType":"fullProfileUpdate",
"profile":{
"stats":{
"attributes":{
"allowed_to_receive_gifts":true,
"allowed_to_send_gifts":true,
"ban_history":{},
//This is what I'm trying to scrape the EpicPCKorea string
"current_mtx_platform":"EpicPCKorea",
"daily_purchases":{},
"gift_history":{},
"import_friends_claimed":{},
"in_app_purchases":{
"fulfillmentCounts":{
"2E5AC9924F2247325BBB22AC9AF9965B":1
},
"receipts":[
"EPIC:543a35e70dde4e0aaf56a9e0b76c8f67"
]
},
"inventory_limit_bonus":0,
"mfa_enabled":false,
"monthly_purchases":{},
"mtx_affiliate":"",
"mtx_purchase_history":{},
"weekly_purchases":{}
}
},
"updated":"2018-12-06T14:37:27.797Z",
}
}
],
"profileChangesBaseRevision":31,
"serverTime":"2018-12-30T18:44:35.451Z"
}
Here, my code in C#;
//str4 is the json response that I just posted up.
dynamic json = JsonConvert.DeserializeObject(str4);
string platform = json.profileChanges.profile.stats.attributes.current_mtx_platform;
But it doesn't work at all.
I debugged it and found out this Exception:
'Newtonsoft.Json.Linq.JArray' does not contain a definition for 'profile'
What am I doing wrong and how can I fix it?
As mentioned in the comments under your question, profileChanges is an array so you need to specify which item in the array to access.
Are you sure the the below does not work? It works for me...
string platform = json.profileChanges[0].profile.stats.attributes.current_mtx_platform;
I'm trying to parse the info from a json object obtained via api, but in this request, I'm trying to get just one variable. I just want to get the summonerLevel variable.
{
"test": {
"id":107537,
"name":"test",
"profileIconId":785,
"summonerLevel":30,
"revisionDate":1440089189000
}
}
I've been trying to it with this code and I know that if I write
p.summonerLevel = (int)(obj.test.summonerLevel)
it will work, but the problem is that test is not a static name, and it will be changing within each request I do. Any good example on how to do it?
Thanks
WebClient c = new WebClient();
string data = c.DownloadString("https://las.api.pvp.net/api/lol/las/v1.4/summoner/by-name/"+summonerName+"?api_key=<api-key>");
dynamic obj = JsonConvert.DeserializeObject(data);
p.summonerLevel = (int)(obj.tempName.summonerLevel);
Something like this?
int summonerLevel= (int)JObject.Parse(data).First.First["summonerLevel"];