how to Convert string into Json using Newton Json library - json

sorry for the silly question, but i am stuck converting for example the following result from a method into Json
public string Test(string input) {
return "Name:" + input;
}
to look like this
{"Name":"Mike"}
Update:
Darin fixed first problem now i am using this way but it is not working
StringBuilder sb = new StringBuilder();
StringWriter sw = new StringWriter(sb);
using(JsonWriter jsonWriter = new JsonTextWriter(sw)) {
jsonWriter.Formatting = Formatting.Indented;
jsonWriter.WritePropertyName("Name");
jsonWriter.WriteValue("Mike");
}
I get
'{"Name":{"m_MaxCapacity":2147483647,"Capacity":16,"m_StringValue":"\\"Name\\": \\"Mike\\"","m_currentThread":0}}';

You could use the JavaScriptSerializer class:
public string Test(string input)
{
var serializer = new JavaScriptSerializer();
return serializer.Serialize(new { Name = input });
}
Example usage:
string json = Test("Mike"); // json = {"Name":"Mike"}
UPDATE:
Didn't notice you wanted a solution using the Json.NET library. Here's one:
string json = JsonConvert.SerializeObject(new { Name = input });

Related

Spring - Return Raw JSON without double serialization

I know there are other posts similar to this, but I haven't found any that help me find a solution for this particular case.
I am trying to return a HashMap<String, Object> from my Controller.
The Object part is a JSON string, but its being double serialized and not returned as a raw JSON string, thus not ending up with extra quotations and escape characters.
Controller function:
#RequestMapping(method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
public HashMap<String, Object> heartbeat(){
String streamInfo = service.getStreamInfo();
String streamCursorInfo = service.getStreamCursorInfo();
String topicInfo = service.getTopicInfo();
String greeting = "This is a sample app for using Spring Boot with MapR Streams.";
HashMap<String, Object> results = new HashMap();
results.put("greeting", greeting);
results.put("streamInfo", streamInfo);
results.put("streamCursorInfo", streamCursorInfo);
results.put("topicInfo", topicInfo);
return results;
}
Service function:
private String performCURL(String[] command){
StringBuilder stringBuilder = new StringBuilder();
try{
ProcessBuilder processBuilder = new ProcessBuilder(command);
Process p = processBuilder.start();
BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream()));
String line = null;
while((line = reader.readLine()) != null){
stringBuilder.append(line);
}
}
catch(Exception e){
LOGGER.error(ExceptionUtils.getRootCauseMessage(e));
}
return stringBuilder.toString();
}
The cURL command I run already returns a raw JSON string. So im just trying to add it to the HashMap to be returned in the heartbeat response.
But every time I run this, my output looks like:
{
"greeting": "This is a sample app for using Spring Boot with MapR Streams.",
"streamCursorInfo": "{\"timestamp\":1538676344564,\"timeofday\":\"2018-10-04 02:05:44.564 GMT-0400 PM\",\"status\":\"OK\",\"total\":1,\"data\":[{\"consumergroup\":\"MapRDBConsumerGroup\",\"topic\":\"weightTags\",\"partitionid\":\"0\",\"produceroffset\":\"44707\",\"committedoffset\":\"10001\",\"producertimestamp\":\"2018-10-03T05:57:27.128-0400 PM\",\"consumertimestamp\":\"2018-09-21T12:35:51.654-0400 PM\",\"consumerlagmillis\":\"1056095474\"}]}",
...
}
If i return only the single string, such as streamInfo then it works fine and doesnt add the extra quotes and escape chars.
Can anyone explain what im missing or need to do to prevent this double serialization?
Instead of returning a HashMap, create an object like this:
public class HeartbeatResult {
private String greeting;
... //other fields here
#JsonRawValue
private String streamCursorInfo;
... //getters and setters here (or make the object immutable by having just a constructor and getters)
}
With #JsonRawValue Jackson will serialize the string as is. See https://www.baeldung.com/jackson-annotations for more info.
streamCursorInfo is a string, not an object => the serialization will escape the " character.
If you are able to return the object containing the data, it will work out of the box. If what you have is just a String, I suggest to serialize it to JsonNode and add it in your response
ObjectMapper objectMapper = new ObjectMapper();
JsonNode streamCursorInfo = objectMapper.readTree(service.getStreamInfo())
results.put("streamCursorInfo", streamCursorInfo);

How to access nested JSON with array in firebase

I want to access a JSON of this structure in firebase
The structure
{
"questions":{
"English":{
"English_2002":[
{
"correct_ans":"A",
"OptionA":"a coder",
"OptionB":"a hacker",
"OptionC":"a writer",
"OptionD":"a programmer",
"Question":"Who build software"
},
{},
{}
],
"English_2003":[],
}
}
}
I want this structure. In the subject structure, other subjects will come after I exhaust 9 years of English.
My confusion is how to logically get each subject since firebase will only accept the root name questions.
Please I may sound dumb, but I have a very long questions thread almost 55000 lines. Because firebase accept one JSON tree.
Sorry i wasn't very clear i was asking from the stack phone app:
I have a question json tag of the structure above; my question is how will i be able to access the object subject like "english":{
// then accessing the first english array "english":[]
//since am now using firebase.
}
initially each array was individual json file, i have to recreate them into one for firebase sake. this is how i was parsing it then.
public class QuestionParser {
Context context;
public QuestionParser(Context c) {
this.context = c;
}
public ArrayList<Question> getJsonFromUrl(String url, String arrayName)
{
ArrayList<Question> arrayofQuestion = new ArrayList<>();
return arrayofQuestion;
}
// Processing question from JSon file in res > raw folder
public ArrayList<Question> parseQuestionJson(int rawJsonFileId, String arrayName) {
ArrayList<Question> questionList = new ArrayList<>();
String jsonstr = null;
try {
InputStream in = context.getResources().openRawResource(rawJsonFileId);
BufferedReader br = new BufferedReader(new InputStreamReader(in));
StringBuilder sb = new StringBuilder();
String line = null;
while ((line = br.readLine()) != null) {
sb.append(line + "\n");
}
jsonstr = sb.toString();
Log.d("REEEEADDD" + this.toString(), jsonstr);
//System.out.println(jsonstr);
} catch (Exception e) {
Log.e("Buffer Error", "Error converting result " + e.toString());
}
// If the JSON string is empty or null, then return early.
if (TextUtils.isEmpty(jsonstr)) {
return null;
}
try {
JSONObject jsonObject = new JSONObject(jsonstr);
JSONArray jsonArray = jsonObject.getJSONArray(arrayName);
JSONObject jobject;
for (int i = 0; i < jsonArray.length(); i++) {
// TEST
jobject = jsonArray.getJSONObject(i);
String ans = jobject.getString("correct_answer");
String graphic_name = jobject.getString("question_image");
String optionA = jobject.getString("optiona");
String optionB = jobject.getString("optionb");
String optionC = jobject.getString("optionc");
String optionD = jobject.getString("optiond");
String questionNo = jobject.getString("question_number");
String question = jobject.getString("question");
questionList.add(new Question(questionNo, graphic_name, question, optionA, optionB, optionC, optionD, ans));
Log.d("DDD" + this.toString(), String.valueOf(questionList.get(i)));
}
Log.i("ONE QUESTION", questionList.get(50).getQuestion());
} catch (Exception e) {
Log.e("JSON Parser", "Error parsing data " + e.toString());
}
return questionList;
}
}
So how can i parse it from firebase because initially, if a student chooses question and year i passes those value as parameter and use them for parsing. but in firebase now i have access to only root firebase name in the get reference e method
To access for example "correct_ans":"A" you would query your firebase like so:
your.firebase.domain/questions/English/English_2002/0/correct_ans
Notice that each level in the json object is represented by a / and the key you want to access whereas in case of an array you simple add the array index. JSON's simple structure also allows simple REST like access

Is it possible to use JsonReaderWriterFactory to convert XML to JSON without using DataContractJsonSerializer?

I need a generic routine that takes any valid XML and converts it to JSON without knowing the underlying data type. I know that this is easily done with Json.Net and I also know how to do it with the DataContractJsonSerializer but our organisation doesn't use Json.Net and the DataContractJsonSerializer needs a Data Contract enabled object type.
My working code using Json.Net:
XmlDocument document = new XmlDocument();
document.LoadXml(xml);
string jsonText = JsonConvert.SerializeXmlNode(document);
The code I'd like to be able to use, using JsonReaderWriterFactory instead of Json.Net:
string jsonText = string.Empty;
MemoryStream stream = new MemoryStream();
StreamWriter streamWriter = new StreamWriter(stream);
streamWriter.Write(xml);
streamWriter.Flush();
stream.Position = 0;
using (XmlDictionaryWriter xmlWriter = JsonReaderWriterFactory.CreateJsonWriter(stream))
{
object someObject = new object();
DataContractJsonSerializer serializer = new DataContractJsonSerializer(someObject.GetType());
serializer.WriteObject(stream, someObject);
xmlWriter.Flush();
jsonText = Encoding.Default.GetString(stream.GetBuffer());
}
Is there a way around this?
Too bad the Json.Net isn't an option - we've used it for years now, and it's fantastic. Short of native parsing and json generation by hand, there's not a lot of fast ways to do this.
Check out the code from this link:
http://www.phdcc.com/xml2json.htm (See section "XmlToJSON C# code", should be fairly quick)
This code could easily be adapted to a class or even extension to convert an XML Document (or even just xml string being parsed into an XML document, then returning the json.
Another approach to consider could be the following. It specifies using anonymous types assuming you don't have control of the objects that could be deserialized from XML (and you don't want to manage those separate types).
Convert the XML into an anonymous type (probably through the
Use the JavascriptSerializer to serialize the anonymous object into the json
The code sample below shows this techinique:
using System;
using System.Collections.Generic;
using System.Dynamic;
using System.Linq;
using System.Text;
using System.Xml.Linq;
using System.Data.Entity.Design.PluralizationServices;
using System.Globalization;
namespace Scratch
{
class Program
{
static void Main(string[] args)
{
string xml = "<root><student><id>1</id></student><student><id>2</id></student></root>";
string json = XmlToJson(xml);
Console.WriteLine(json);
Console.ReadKey(true);
}
// Using JavaScriptSerializer
static string XmlToJson(string xml)
{
var obj = GetAnonymousType(xml);
var serializer = new System.Web.Script.Serialization.JavaScriptSerializer();
return serializer.Serialize(obj);
}
// Adapted from: http://www.codeproject.com/Tips/227139/Converting-XML-to-an-dynamic-object-using-ExpandoO
static dynamic GetAnonymousType(string xml, XElement node = null)
{
node = string.IsNullOrEmpty(xml) ? node : XDocument.Parse(xml).Root;
IDictionary<String, dynamic> result = new ExpandoObject();
var pluralizationService = PluralizationService.CreateService(CultureInfo.CreateSpecificCulture("en-us"));
node.Elements().AsParallel().ForAll(gn =>
{
var isCollection = gn.HasElements
&& (gn.Elements().Count() > 1
&& gn.Elements().All(e => e.Name.LocalName.ToLower() == gn.Elements().First().Name.LocalName)
|| gn.Name.LocalName.ToLower() == pluralizationService.Pluralize(gn.Elements().First().Name.LocalName).ToLower());
var items = isCollection ? gn.Elements().ToList() : new List<XElement>() { gn };
var values = new List<dynamic>();
items.AsParallel().ForAll(i => values.Add((i.HasElements) ? GetAnonymousType(null, i) : i.Value.Trim()));
result[gn.Name.LocalName] = isCollection ? values : values.FirstOrDefault();
});
return result;
}
}
}

Json file generation using Javascript serializer

I need to generate the following json files using Javascript serializer,
1. {"components":[{"name":"AA"}]}
2. {"customfield_10222":[{"name":"xxx"},{"name":"yyyy"}]} // this custom field represents the additional notification persons.
I have to achieve this scenario using the below coding,
public List<AdditionalUsers> AdditionalNotification = new List<AdditionalUsers>();
public List<ComponentsDetails> Component = new List<ComponentsDetails>();
class AdditionalUsers
{
public string name;
}
class ComponentsDetails
{
public string name;
}
string[] a=new string[2]{"XXX","YYY"};
foreach (string additionalUser in a)
{
AdditionalNotification.Add(new AdditionalUsers() { name =additionalUser });
}
Component.Add(new ComponentsDetails() { name = "AA" });
var subFields = new Dictionary<string, object>();
subFields.Add("components", Component); // represents 1 json file
subFields.Add("customfield_10222", AdditionalNotification); // represents 2 json file
JavaScriptSerializer serializer = new JavaScriptSerializer();
string json = serializer.Serialize((Object)subFields);
Console.WriteLine(json);
The result like this
{
"components":[{"name": "AA"}],
"customfield_10222":[{"name":"XXX"},{"name":"YYY"}]
}

MVC C# to Json correct way to format url in string array?

I'm trying to understand correct way to handle backslashes in urls within a string array that are returned via Json...I have commented the goal below
public JsonResult PhotosByListingId(int id)
{
var pics = _listingRepository.GetById(id).ListingPhoto.ToList();
List<string> l = new List<string>();
foreach(var p in pics)
{
//l.Add("albums\\/album1\\/" + p.PhotoName); //nope
//l.Add(#"albums\/album1\/" + p.PhotoName); //nope
l.Add("albums/album1/" + p.PhotoName); //????? nope
}
string[] s = l.ToArray();
return Json(s, JsonRequestBehavior.AllowGet);
//needs to be this..THE GOAL
// ["albums\/album1\/10k.jpg","albums\/album1\/10l.jpg","albums\/album1\/10y.jpg"]
//but is returning this?
// ["albums/album1/10k.jpg","albums/album1/10l.jpg","albums/album1/10y.jpg"]
}
You could try string.Replace:
public JsonResult PhotosByListingId(int id)
{
var pics = _listingRepository.GetById(id).ListingPhoto.ToList();
List<string> l = new List<string>();
foreach(var p in pics)
{
l.Add("albums/album1/".Replace("/", "\\/") + p.PhotoName);
}
string[] s = l.ToArray();
return Json(s, JsonRequestBehavior.AllowGet);
}
Because the javascript serialiser is converting the slashes, you could implement serialisation yourself and modify the generated JSON:
public string CustomSerialised()
{
string test = "/This/That/The other/";
List<string> arr = new List<string>();
arr.Add(test);
arr.Add(test);
arr.Add(test);
System.Web.Script.Serialization.JavaScriptSerializer s = new System.Web.Script.Serialization.JavaScriptSerializer();
return s.Serialize(arr).Replace("/","\\/");
}
This can be navigated to using the standard routing pattern when used within a controller.