How to convert object to json with jsonconvert - without - key-quotations - c#

I use jsonconvert to convert simple objects to json like
JsonConvert.SerializeObject(new { label = "MyLabel1" });
to
{ "label":"MyLabel1" }
but i want to get the keys without quotation like
{ label: "MyLabel1"}
is there a way to convert objects to json withoud "key"-quotations by using jsonconvert?

Any library that expects JSON or actual JavaScript notation for creating objects (which is a superset of JSON) should work fine with quotes.
But if you really want to remove them, you can set JsonTextWriter.QuoteName to false. Doing this requires writing some code that JsonConvert.SerializeObject() uses by hand:
private static string SerializeWithoutQuote(object value)
{
var serializer = JsonSerializer.Create(null);
var stringWriter = new StringWriter();
using (var jsonWriter = new JsonTextWriter(stringWriter))
{
jsonWriter.QuoteName = false;
serializer.Serialize(jsonWriter, value);
return stringWriter.ToString();
}
}

I complement answer #svick. For save format you need use StringBuilder for StringWriter.
static string SerializeWithoutQuote(object value)
{
var builder = new StringBuilder();
var serializer = JsonSerializer.Create();
var stringWriter = new StringWriter(builder);
using (var jsonWriter = new JsonTextWriter(stringWriter))
{
jsonWriter.Formatting = Formatting.Indented;
jsonWriter.QuoteName = false;
serializer.Serialize(jsonWriter, value);
return builder.ToString();
}
}

Related

How to convert json format string to json in c#

Am getting json formatted string which is stored in database, now i want to convert it into json format. How can i convert it Please help.
var labelnames = #"{'LabelName':'LabelName1','IsHeader':true},{'LabelName':'LabelName2','IsHeader':false},{'LabelName':'LabelName3','IsHeader':true},{'LabelName':'LabelName4','IsHeader':false}";
I want to convert above code to proper json format
This is an invalid JSON format, moreover it does not have surrounding array brackets []. Ideally you should fix this at source.
You could do a simple replace
MyLabels = JsonConvert.DeserializeObject<List<Label>>(labelnames = "[" + labelnames.Replace("'", "\"") + "]")
However this may throw an error if any of the values also contain a '.
Therefore, you could create a custom JsonTextReader
using (var sw = new StringReader("[" + labelnames + "]"))
using (var reader = new MyJsonTextReader(sw))
{
JsonSerializer ser = new JsonSerializer();
MyLabels = ser.Deserialize<List<Label>>(reader);
}
class MyJsonTextReader : JsonTextReader
{
public override char QuoteChar { get; protected set; } = '\'';
public MyJsonTextReader(TextReader r) : base(r){}
}
class Label
{
public string LabelName;
public bool IsHeader;
}
dotnetfiddle

How to change the value of a StringBuilder Parsing through JArray

I have struggled to finish this task, please if anyone can give me a hint I would be so thankful.
My main task is to get data from database using (FOR JSON AUTO) which is working :)
select filed1, field2, field3 from table FOR JSON AUTO;
And then after connecting to Data base I use the StringBuilder() to build a Json Array of objects which is working :)
var jsonResult = new StringBuilder();
if(!r.HasRows)
{
jsonResult.Append("[]");
}
else
{
while(r.Read())
{
jsonResult.Append(r.GetValue(0).ToString());
}
// JArray array = JArray...
}
After that I am trying to change the value of filed1 for each object inside the Json Array
JArray array = JArray.Parse(jsonResult.ToString());
foreach (JObject obj in array.Children<JObject>())
{
foreach (JProperty singleProp in obj.Properties())
{
string name = singleProp.Name;
string value = singleProp.Value.ToString();
if(name.ToString() == "field1")
{
Int64 newID = 1234;
value = newID.ToString();
}
}
}
This is working but My BIG QUESTION is how can I get it changed inside the jsonResult?
You simply have to replace the value that you want to update. Since StringBuilder has a .Replace inbuilt method, you can implement that method.
`JArray arr = JArray.Parse(jsonResult.ToString());
foreach (JObject obj in arr.Children<JObject>())
{
foreach(JProperty singleProp in obj.Properties())
{
string name = singleProp.Name;
string value = singleProp.Value.ToString();
if (name.ToString().Equals("field1")) //good practice
{
Int64 newID = 1234;
jsonResult.Replace(value, newID.ToString());//replacing old value with new value and directly updates jsonResult
}
//not necesssary, explanation is given below
var jsonElement = JsonSerializer.Deserialize<JsonElement>(jsonResult.ToString());
result = JsonSerializer.Serialize(jsonElement, options);
}
}`
And for better formatting, I used JsonSerializer so that your output will look like json object rather than whole string without any lines.
` var options = new JsonSerializerOptions()
{
WriteIndented = true
};
var result = ""
while loop{
jsonResult.Append(r.GetValue(0).ToString());
(Above code)
}
`

How can I add elements to a JSON array without adding "?

I'm developing a library with C#, .NET Framework 4.0 and Newtonsoft.Json 6.0.8.
I'm trying to create my own serializer:
public static string Serialize(List<Models.Codes> codes)
{
if (codes == null)
throw new ArgumentNullException("codes");
if (codes.Count == 0)
throw new ArgumentOutOfRangeException("codes");
StringWriter sw = new StringWriter();
JsonTextWriter writer = new JsonTextWriter(sw);
writer.WriteStartArray();
foreach (Models.Codes code in codes)
writer.WriteValue(CodesSerializer.Serialize(code));
writer.WriteEndArray();
return sw.ToString();
}
public static string Serialize(Models.Codes code)
{
if (code == null)
throw new ArgumentNullException("code");
StringWriter sw = new StringWriter();
JsonTextWriter writer = new JsonTextWriter(sw);
writer.WriteStartObject();
writer.WritePropertyName("Code");
writer.WriteValue(code.Code);
writer.WritePropertyName("BatchId");
writer.WriteValue(code.BatchId);
writer.WritePropertyName("ProductId");
writer.WriteValue(code.ProductId);
writer.WritePropertyName("CodeLevel");
writer.WriteValue(code.CodeLevel);
writer.WritePropertyName("CommisioningFlag");
writer.WriteValue(code.CommisioningFlag);
writer.WritePropertyName("Timespan");
writer.WriteValue(code.Timespan);
if (!string.IsNullOrWhiteSpace(code.Username))
{
writer.WritePropertyName("Username");
writer.WriteValue(code.Username);
}
if (!string.IsNullOrWhiteSpace(code.Source))
{
writer.WritePropertyName("Source");
writer.WriteValue(code.Source);
}
if (!string.IsNullOrWhiteSpace(code.Reason))
{
writer.WritePropertyName("Reason");
writer.WriteValue(code.Reason);
}
writer.WriteEndObject();
string text = sw.ToString();
return text;
}
But it generates a string like this:
[\"{\\\"Code\\\":\\\"81861400008000002386\\\",\\\"BatchId\\\":5,\\\"ProductId\\\":7,\\\"CodeLevel\\\":1,\\\"CommisioningFlag\\\":1,\\\"Timespan\\\":null}\",
Have you notices the extra " before {?
How can I don't put that "?
I think the problem is that I am adding a value to an array inside the loop:
writer.WriteStartArray();
foreach (Models.Codes code in codes)
writer.WriteValue(CodesSerializer.Serialize(code));
writer.WriteEndArray();
I have changed writer.WriteValue(CodesSerializer.Serialize(code)); with writer.WriteRaw(CodesSerializer.Serialize(code)); and now it doesn't write ", but now I need to write JSON value delimiter and I can't use writer.WriteValueDelimiter();.
How can I add elements to a JSON array without adding "?
I have found the solution. I have to use writer.WriteRawValue():
writer.WriteStartArray();
foreach (Models.Codes code in codes)
writer.WriteRawValue(CodesSerializer.Serialize(code));
writer.WriteEndArray();

c# XML serialisation of child class - remove xmlns:p1 and p1:type attributes from root node

Using the bog-standard System.Xml.Serialization.XmlSerializer, I am serializing an object who's class inherits from another. Inspecting the resulting XML, the root node is being given the attributes "p1:type" and "xmlns:p1":
<ApiSubmission ApiVersion="1" CustId="100104" p1:type="OrderConfirmationApiSubmission"
xmlns:p1="http://www.w3.org/2001/XMLSchema-instance">
...
</ApiSubmission>
Is there a nice way to remove these attributes?
So I came upon this same issue ~5 years after this question was originally asked and was disappointed that no one had answered. After searching around I cobbled something together that allows me to strip out the type attribute in a derived class.
internal static string SerializeObject(object objectToSerialize, bool OmitXmlDeclaration = true, System.Type type = null, bool OmitType = false, bool RemoveAllNamespaces = true)
{
XmlSerializer x;
string output;
if (type != null)
{
x = new XmlSerializer(type);
}
else
{
x = new XmlSerializer(objectToSerialize.GetType());
}
XmlWriterSettings settings = new XmlWriterSettings() { Indent = false, OmitXmlDeclaration = OmitXmlDeclaration, NamespaceHandling = NamespaceHandling.OmitDuplicates };
using (StringWriter swriter = new StringWriter())
using (XmlWriter xmlwriter = XmlWriter.Create(swriter, settings))
{
x.Serialize(xmlwriter, objectToSerialize);
output = swriter.ToString();
}
if (RemoveAllNamespaces || OmitType)
{
XDocument doc = XDocument.Parse(output);
if (RemoveAllNamespaces)
{
foreach (var element in doc.Root.DescendantsAndSelf())
{
element.Name = element.Name.LocalName;
element.ReplaceAttributes(GetAttributesWithoutNamespace(element));
}
}
if (OmitType)
{
foreach (var node in doc.Descendants().Where(e => e.Attribute("type") != null))
{
node.Attribute("type").Remove();
}
}
output = doc.ToString();
}
return output;
}
I use this and [XmlInclude] the derived class in the base class. Then OmitType and RemoveAllNamespaces. Essentially the derived class is then treated as if it were the base class.

Dynamic Objects in WCF not possible?

When building a response in WCF (json), im pretty sure it's not possible to use completely dynamic objects, but just wanted to double check here first.
An ideal response would look something like:
"userTypes" :
{
"BartSimpson" :
{
"url" : "foo",
"desc" : "bar"
},
"LisaSimpson" :
{
"url" : "foo",
"desc" : "bar"
}
}
In 'compiled' code, the above could be performed by the following architecture (slightly pseudocode):
public class Character{
string url {get;set;}
string desc{get;set;}
}
public class UserTypes{
public Character BartSimpson{get;set;}
public Character LisaSimpson{get;set;}
}
But my main goal is that BartSimpson and LisaSimpson are not 'compiled' so I could have any number of Character classes, with any name / identifer in the response.
Add the following using at the top of your service implementation class (make sure that you also add the proper references in your project):
using Newtonsoft.Json;
using System.Dynamic;
using System.IO;
using System.Text;
You may try this simple method which outputs the dynamic result:
public string GetData()
{
dynamic d = new ExpandoObject();
dynamic bartSimpson = new ExpandoObject();
dynamic lisaSimpson = new ExpandoObject();
bartSimpson.url = "foo";
bartSimpson.desc = "bar";
lisaSimpson.url = "foo";
lisaSimpson.desc = "bar";
d.userTypes = new ExpandoObject();
d.userTypes.BartSimpson = bartSimpson;
d.userTypes.LisaSimpson = lisaSimpson;
var s = JsonSerializer.Create();
var sb = new StringBuilder();
using (var sw = new StringWriter(sb))
{
s.Serialize(sw, d);
}
return sb.ToString();
}
To go one more step further (you'll just have to pass Bart and Lisa in the comaSeparatedNames value), you could do:
public string GetData(string comaSeparatedNames)
{
string[] names = comaSeparatedNames.Split(',');
dynamic d = new ExpandoObject();
dynamic dNames = new ExpandoObject();
foreach (var name in names)
{
dynamic properties = new ExpandoObject();
properties.url = "foo";
properties.desc = "bar";
((IDictionary<string, object>)dNames).Add(name, properties);
}
((IDictionary<string, object>)d).Add("userTypes", dNames);
var s = JsonSerializer.Create();
var sb = new StringBuilder();
using (var sw = new StringWriter(sb))
{
s.Serialize(sw, d);
}
// deserializing sample
//dynamic dummy = new ExpandoObject();
//var instance = s.Deserialize(new StringReader(sb.ToString()),
// dummy.GetType());
//var foo = instance.userTypes.BartSimpson.url;
return sb.ToString();
}
Note: I've also provided the lines (commented) for deserialization.

Categories

Resources