I was using using Newtonsoft.Json; to convert json to Objects in Unity like this:
var response = JsonConvert.DeserializeObject<Response<string>>(jsonData);
I don't know what I've changed in project but it stopped to work properly on iPad and iPhone devices. It currently works well on macOS while I am running the project on Unity. Where should I look? What can I do? Any suggesstions?
I tried to do this convertion in also JsonUtility but it did not work in macOS too.
Class Example:
using System;
using Newtonsoft.Json;
[Serializable]
public class Response<T>
{
[JsonProperty("status")]
public bool Status { get; set; }
[JsonProperty("data")]
public T Data { get; set; }
public Response()
{ }
public Response(bool status, T data)
{
Status = status;
Data = data;
}
}
and the example json is:
{"status":true,"data":"someStringValue"}
Related
In My code, I am trying to receive an API containing a JSON body containing data, I have designed a DataInfo Model class and used the [FromBody] function to translate the data.
My issue is that the data being pulled which I have formatted to be ints and doubles, is being pulled as a series of 0s
My Data Info Model Class:
public class DataInfo
{
[JsonProperty("ID")]
public int JId { get; set; }
[JsonProperty("Temp")]
public double JTemperature { get; set; }
[JsonProperty("Humidity")]
public double JHumidity { get; set; }
[JsonProperty("WindSpeed")]
public double JWindSpd { get; set; }
[JsonProperty("SoilMoisture")]
public double JSM { get; set; }
}
}
My Api Controller:
[HttpPatch("update")]
public async Task<ActionResult<Device>> Update([FromBody] DataInfo data)
{
var dev = await _dbContext.Device.Where(x => x.Id == data.JId).FirstOrDefaultAsync();
if (dev == null)
{
return BadRequest("no device found");
}
dev.Humidity = data.JHumidity;
dev.Temp = data.JTemperature;
dev.WindSpeed = data.JWindSpd;
dev.SoilMoisture = data.JSM;
dev.DateTime = DateTime.Now;
_dbContext.SaveChanges();
return Ok(dev);
}
My JsonBody:
{
"ID":"1",
"Temp":"37",
"Humidity":"42",
"WindSpeed":"12",
"SoilMoisture":"14"
}
I also Used this JSON body and got the same result:
{
"data":{
"ID":"1",
"Temp":"37",
"Humidity":"42",
"WindSpeed":"12",
"SoilMoisture":"14"
}
}
When I run the API call in postman, I receive a 400 error with the text that correlates to an invalid Device ID, when I had it send the Device ID and other data points within the class, all were returned as 0s.
The API call is going to the correct controller, however the JSON data seems only to be exsisting as 0s even though I assign it with the JsonPropertyName or JsonProperty assignment in the model class.
I found the issue to be in My Using inputs. I was including Newtonsoft which was conflicting with system.
using BlazorApp1.Data;
using BlazorApp1.Models;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.WebUtilities;
using Microsoft.EntityFrameworkCore;
//using Newtonsoft.Json;
using System.Net;
using System.Text;
using System.Text.Json;
using System.Text.Json.Serialization;
I am playing around with Blazor right now. And I found a strange behaviour and I am not quite sure, if it's my, Azure's or Blazor's (it's still experimental, so it's possible) fault. My project is ASP.NET core hosted (on Azure, but I already told that).
I've got the following model:
namespace MyProject.Shared
{
public class Emoji
{
public List<string> UnicodeCharacters { get; set; }
public string Description { get; set; }
public Emoji()
{
UnicodeCharacters = new List<string>();
}
}
}
The following controller:
namespace MyProject.Server.Controllers
{
[Route("api/[controller]")]
public class EmojiPickerController : Controller
{
[HttpGet("[action]")]
public IEnumerable<Emoji> GetEmojis()
{
var emojis = new List<Emoji>();
var emoji = new Emoji();
emoji.Description = "Foo";
emoji.UnicodeCharacters.Add("Bar");
return emojis;
}
}
}
And finally my component:
namespace MyProject.Client.Classes
{
public class EmojiPicker : BlazorComponent
{
[Inject]
protected HttpClient Http { get; set; }
public List<Emoji> Emojis = new List<Emoji>();
protected override async Task OnInitAsync()
{
var emojiArray = await Http.GetJsonAsync<Emoji[]>("api/EmojiPicker/GetEmojis");
Emojis = emojiArray.ToList<Emoji>();
}
}
}
Everything works just fine when I launch it locally. I've got the object in my view and can do stuff with it (e.g. printing "foo" and "bar" on the screen ;)).
But it's not like that on my Azure WebApp. It just doesn't work:
The WeatherCast sample works btw on both platforms. Any ideas?
Okay, after restarting my Azure application everything works just fine. Weird.
I am struggling with a subject that has a lot of variants, but I can't seem to find one that works for me, and I think it's because of the way that my JSON array is.
I'm not an expert in C# or JSON, but I already manage to "almost" get this to work. I need to get hand with the class that the JSON will deserialize to.
When I run the code I dont get an error, just a nulls in the xKisokData var.
The JSON data that I am getting. Their are these two different ones.
"{\"Event\": \"sConnection\",\"data[device]\": \"fb16f550-2ef1-11e5-afe9-ff37129acbf4\",\"data[mode]\": \"customer\",\"data[starttime]\": \"2015-07-22T16:07:42.030Z\",\"data[endtime]\": \"\"}"
"{\"Event\": \"Log\",\"data[id]\": \"2015-07-22T16:07:23.063Z\",\"data[messages][0][source]\": \"server\",\"data[messages][0][message]\": \"Server is listening on port 1553\"}"
The code I have so far:
// Read in our Stream into a string...
StreamReader reader = new StreamReader(JSONdataStream);
string JSONdata = reader.ReadToEnd();
JavaScriptSerializer jss = new JavaScriptSerializer();
wsKisokData[] xKisokData = jss.Deserialize<wsKisokData[]>(JSONdata);
My Class:
namespace JSONWebService
{
[DataContract]
[Serializable]
public class KisokEvent
{
public string eventTrigger { get; set; }
}
[DataContract]
[Serializable]
public class KisokData
{
public string data { get; set; }
}
[DataContract]
[Serializable]
public class wsKisokData
{
public KisokEvent KDEvent { get; set; }
public List<KisokData> KDData { get; set; }
}
}
I am sure that I don't understand the Deserialize process. Thanks for the help.
EDIT:
I put the JSON in the top part right from the debugger, here is the strings.
{
"Event": "sConnection",
"data[device]": "fb16f550-2ef1-11e5-afe9-ff37129acbf4",
"data[mode]": "customer",
"data[starttime]": "2015-07-22T16:07:42.030Z",
"data[endtime]": ""
}
{
"Event": "Log",
"data[id]": "2015-07-22T16:07:23.063Z",
"data[messages][0][source]": "server",
"data[messages][0][message]": "Server is listening on port 1553"
}
I would HIGHLY recommend using the json.net package off nuget instead.
You can generate template classes (models) for it by pasting the json into http://json2csharp.com/
Then use said models to convert the json into a c# object (deserializing) by doing a
var jsonStructure = JsonConvert.DeserializeObject<model>(json)
And query as if it was just a standard object
foreach (var x in jsonStructure.KDData)
{
doAction(x.data);
}
// for example
I'm working on a custom add in for excel, I want it to get a list of projects from a remote web service. The JSON is coming back from the web servive to excel, but I'm having trouble turning the JSON into objects in C#.
Here is the AddIn code:
using Microsoft.Office.Tools.Ribbon;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Text.RegularExpressions;
using System.Diagnostics;
using System.Web;
namespace TestAddIn
{
class Project
{
static string currentProject;
static List<Project> validProjects;
public int id { get; set; }
public string name { get; set; }
public int svar_reserved_space { get; set; }
// Set the current project we're working on
internal static void setCurrentProject(string path)
{
Match match = Regex.Match(path, #"^[A-Za-z]:\\(\w+)");
Project.currentProject = match.Groups[1].Value;
foreach (Project validProject in validProjects)
{
RibbonDropDownItem dropDown = Globals.Ribbons.Ribbon1.Factory.CreateRibbonDropDownItem();
dropDown.Label = validProject.name;
if (validProject.name.Equals(Project.currentProject))
{
Globals.Ribbons.Ribbon1.projectComboBox.Items.Add(dropDown);
}
}
}
// Connect to a web service and get a list of valid projects
internal static void getValidProjects()
{
string url = "http://192.168.118.128/projects/json";
WebRequest webRequest;
webRequest = WebRequest.Create(url);
Stream objStream;
objStream = webRequest.GetResponse().GetResponseStream();
StreamReader objReader = new StreamReader(objStream);
string sLine = objReader.ReadLine();
Debug.WriteLine("begin: " + sLine);
validProjects = JsonConvert.DeserializeObject<List<Project>>(sLine);
Debug.WriteLine("end");
}
}
}
When using this json:
[{"Project":{"id":1,"name":"test1","svar_reserved_space":2}},{"Project":{"id":2,"name":"test2","svar_reserved_space":0}}]
I get two Project objects in validProjects but the id and svar_reserver_space are 0, and the name is null. Thoguhts?
This is the easiest with some addins/nuget magic:
Install web essentials in Visual studio
Add the nuget package newtonsoft.json
Copy the JSON output string
Paste JSON as class
And use this code:
WebClient wc = new WebClient();
string json = wc.DownloadString("http://192.168.118.128/projects/json");
var a = JsonConvert.DeserializeObject<YourGeneratedMainClass>(json);
Where YourGeneratedMainClass is a class generated by pasting the json as classes.
If you use the method above, you will probably see that it has a parent object
public class Project
{
public int id { get; set; }
public string name { get; set; }
public int svar_reserved_space { get; set; }
}
public class Parent
{
public Project Project { get; set; }
}
More about it in these two S.O. questions:
Json.net deseralize to a list of objects in c# .net 2.0
Deserialized Object Has All Values Set to Null
I would suspect you need the JSON to look like:
[{"id":1,"name":"test1","svar_reserved_space":2},{"id":2,"name":"test2","svar_reserved_space":0}]
In order to use the default Json deserialization.
I am making a Winamp plugin with the single function of sending the details of the song being played over HTTP to a webpage.
It works like this: Winamp song event triggered -> check for new song -> publish to webpage using PubNub (C# API).
So far I got to the stage where everything works exactly as it is supposed to, except for the PubNub code which doesn't serialize the object I'm passing for publishing into JSON. All I keep getting in the PubNub console is a mere {} - an empty JSON object.
A little background on the project structure:
I am using Sharpamp which is a custom library that enables making Winamp plugins with C#. I am also using the PubNub C# API. The gen_notifier_cs project is the C++ plugin wrapper created by Sharpamp. notifier_cs is where all my code resides. The two other projects are self explanatory I assume. I have referenced the PubNub API in notifier_cs, and also have referenced Sharpamp in both notifier_cs and PubNub API.
So, the objects that need to get serialized are of a class Song as defined in Sharpamp:
public class Song
{
public string Title { get; internal set; }
public string Artist { get; internal set; }
public string Album { get; internal set; }
public string Year { get; internal set; }
public bool HasMetadata { get; internal set; }
public string Filename { get; internal set; }
}
So let's say if I have a song object with song data in it, I would go pubnub.publish("winamp_pipe", song); to publish it and PubNub will automatically serialize the data into JSON. But that's just not working in my solution.
To test why it wasn't serializing, I copied that class to the example code file in the PubNub API. Visual Studio changed the class to this (notice the public Song() method):
public class Song
{
public Song() // VS added this method
{
return; // I added this otherwise it would not compile
}
public string Album { get; set; }
public string Artist { get; set; }
public string Filename { get; set; }
public bool HasMetadata { get; set; }
public string Title { get; set; }
public string Year { get; set; }
}
On the same example file I initiated a default song object with some values:
Song song = new Song();
song.Album = "albumname";
song.Artist = "artistname";
song.HasMetadata = true;
song.Title = "songtitle";
song.Year = "2012";
And published it: pubnub.publish("winamp_pipe", song); and it worked! I got the JSON object in the PubNub channel!
{"Album":"albumname","Artist":"artistname","Filename":null,"HasMetadata":true,"Title":"songtitle","Year":"2012"}
So, I tried replacing the "new" Song class with the original one defined in Sharpamp. I tried adding another class definition in the notifier_cs project but that clashes with the one in Sharpamp which I have to rely on. I have been trying so many things as far as I could come up with. Needless to say none prevailed. Still, all I get is an empty JSON object.
This is the code that does the serializing, within the publish method in the PubNub API. I will remind you this code works with the PubNub example files but not with my project:
DataContractJsonSerializer serializer = new DataContractJsonSerializer(objectToSerialize.GetType());
serializer.WriteObject(ms, objectToSerialize);
ms.Position = 0;
using (StreamReader reader = new StreamReader(ms))
{
return reader.ReadToEnd();
}
I have been pulling out my hair for the last day. I know this post is super long but I appreciate your input nonetheless.
Publishing Data: PubNub and C# Winamp Song Class
You already have the data stored in a winamp_song object instance. If you attempt to serialize the winamp_song object instance, it will fail. The serialization will fail if you pass in the winamp_song as the instance has non-serializable members. The best way to proceed is for you to create a Song class that you own and define. Define the member values in the Song class which will be delivered via PubNub. This way you can populate directly the values that are needed to publish to your subscribers.
Song song = new Song();
song.Album = winamp_song.Album;
song.Artist = winamp_song.Artis;
song.HasMetadata = winamp_song.HasMetadata;
song.Title = winamp_song.Title;
song.Year = winamp_song.Year;
When you receive the Song data publish even on your subscriber, you will be able to receive deserialized data, populating the values into a new Song class instance.
Song Class Defined Below
public class Song {
public Song() { return; }
public string Album { get; set; }
public string Artist { get; set; }
public string Filename { get; set; }
public bool HasMetadata { get; set; }
public string Title { get; set; }
public string Year { get; set; }
}
PubNub is the best method for communicating with installed copies of your Winamp plugin.
Well, my "solution", since I am only using one class (the Song class, defined in the Sharpamp library) to publish values by, is manually constructing a JSON string:
pubnub.publish("winamp_pipe", "{\"Album\": \""+song.Album+"\",\"Artist\": \""+song.Artist+"\",\"HasMetadata\": \""+song.HasMetadata.ToString()+"\",\"Title\": \""+song.Title+"\",\"Year\": \""+song.Year+"\",\"Filename\": \""+song.Filename+"\"}");
It is not a solution to the problem itself but it serves the purpose of publishing the information as a JSON object (as long as you don't have any special characters that break the JSON structure in your data).
I am not marking this as an answer because it is not a solution to the real problem, only a temporary workaround...