Generating newlines instead of CRLFs in Json.Net - c#

For my unix/java friends I would like to send newlines ('\n') instead of a CRLF (
'\r\n') in Json.Net. I tried setting a StreamWriter to use a newline without any success.
I think Json.Net code is using Environment.NewLine instead of calling TextWriter.WriteNewLine(). Changing Environment.NewLine is not an option because I'm running as a server and the newline encoding is based on the request.
Is there some other way to force newline for crlf?
Here's my code -
using (var streamWriter = new StreamWriter(writeStream, new UTF8Encoding(false))
{
NewLine = "\n"
})
using (var jsonWriter = new JsonTextWriter(streamWriter)
{
CloseOutput = true,
Indentation = 2,
Formatting = Formatting.Indented
})
{
// serialise object to JSON
}

After delving into the Json.Net code, I see the issue is with JsonTextWriter.WriteIndent, thanks Athari.
Instead of _writer.Write(Environment.NewLine); it should be _writer.WriteLine();.
I've posted a pull request to github. https://github.com/JamesNK/Newtonsoft.Json/pull/271

If you want to customize indentation whitespace, just override JsonTextWriter.WriteIndent:
public class JsonTextWriterEx : JsonTextWriter
{
public string NewLine { get; set; }
public JsonTextWriterEx (TextWriter textWriter) : base(textWriter)
{
NewLine = Environment.NewLine;
}
protected override void WriteIndent ()
{
if (Formatting == Formatting.Indented) {
WriteWhitespace(NewLine);
int currentIndentCount = Top * Indentation;
for (int i = 0; i < currentIndentCount; i++)
WriteIndentSpace();
}
}
}

I see several solutions here that are configuring the serializer. But if you want quick and dirty, just replace the characters with what you want. After all, JSON is just a string.
string json = JsonConvert.SerializeObject(myObject);
json = json.Replace("\r\n", "\n");

I know this is an old question but I had a hard time getting the accepted answer to work and maintain proper indented formatting. As a plus, I am also not creating an override to make this work.
Here is how I got this to work correctly:
using (var writer = new StringWriter())
{
writer.NewLine = "\r\n";
var serializer = JsonSerializer.Create(
new JsonSerializerSettings
{
Formatting = Formatting.Indented
});
serializer.Serialize(writer, data);
// do something with the written string
}
I am assuming that the code changes referenced in this question enabled the setting of NewLine on the StringWriter to be respected by the serializer.

On the wire protocol for just about everthing is that a line ends with crlf. If you feel that you really must do this, post processing is the way to go -- write it out to a string and then change the string before returning it.
Note that this is a lot of extra processing for what I would consider an actual negative. Not recommended.

result = result.Replace(#"\r\n", "\n");

Related

How to make an XML tag mandatory with a self-closing tag, using the serialiser?

I'm working on a C# program and I'm trying to serialise XML.
I have the following tag:
using System.Xml.Serialization;
...
[XmlElement("MV")]
public MultiVerse MultiVerse { get; set; }
When I don't fill in this value, the tag <MV> is not present, but I would like to get a tag <MV/> in that case:
Currently I have <HM><ID>Some_ID</ID></HM>.
I'd like to have <HM><ID>Some_ID</ID><MV/></HM>.
I already tried preceeding the line with [Required] but that didn't work, and I think that filling in the IsNullable attribute is the good approach.
Edit1, after some investigation on the internet
On the internet, there are quite some advises on modifying the XmlWriter but in my project, the whole serialisation is done as follows:
public override string ToString()
{
...
using (var stream = new StringWriter())
using (var writer = XmlWriter.Create(stream, settings))
{
var serializer = new XmlSerializer(base.GetType());
serializer.Serialize(writer, this, ns);
return stream.ToString();
}
...
}
As you can see, this is so general that I prefer not to do any modifications in here, hence I'm looking for a way to customise the [XmlElement] directive.
Edit2: XmlWriter settings:
The XmlWriter settings look as follows:
// Remove Declaration
var settings = new XmlWriterSettings
{
Indent = false,
OmitXmlDeclaration = true,
NewLineHandling = NewLineHandling.None,
NewLineOnAttributes = false,
};
Does anybody have an idea?
Thanks in advance
There is https://learn.microsoft.com/en-us/dotnet/api/system.xml.serialization.xmlelementattribute.isnullable?view=net-6.0 so e.g.
[XmlElement("MV", IsNullable=true)]
public MultiVerse MultiVerse { get; set; }
would give you, for a null value, a serialization as <MV xsi:nil="true" /> (or possibly <MV xsi:nil="true"></MV> as ensuring the short tag notation is not something the standard writers give you control over but my experience is that .NET usually uses it for empty elements so you might be lucky that your wanted serialization format is the default one .NET outputs).
This is the way I'm currently solving my issue (don't laugh):
public override string ToString()
{
string temp = base.ToString();
temp = temp.Replace(" p2:nil=\"true\"", "");
temp = temp.Replace(" xmlns:p2=\"http://www.w3.org/2001/XMLSchema-instance\"", "");
temp = temp.Replace("MV />", "MV/>");
return temp;
}
This is hidious! Does anybody have a better solution?
Thanks

How to unescape unicode in JSON.NET

I have JSON with parts in Unicode like { "val1": "\u003c=AA+ \u003e=AA-"}
How can I convert this to JSON which does not have Unicode formatting?
{"val1": "<=AA+ >=AA-"}
Json.NET unescapes Unicode sequences inside JsonTextReader, so you can adopt the same approach as is used in this answer to How do I get formatted JSON in .NET using C#? by Duncan Smart to reformat your JSON without unnecessary escaping by streaming directly from a JsonTextReader to a JsonTextWriter using JsonWriter.WriteToken(JsonReader):
public static partial class JsonExtensions
{
// Adapted from this answer https://stackoverflow.com/a/30329731
// To https://stackoverflow.com/q/2661063
// By Duncan Smart https://stackoverflow.com/users/1278/duncan-smart
public static string JsonPrettify(string json, Formatting formatting = Formatting.Indented)
{
using (var stringReader = new StringReader(json))
using (var stringWriter = new StringWriter())
{
return JsonPrettify(stringReader, stringWriter, formatting).ToString();
}
}
public static TextWriter JsonPrettify(TextReader textReader, TextWriter textWriter, Formatting formatting = Formatting.Indented)
{
// Let caller who allocated the the incoming readers and writers dispose them also
// Disable date recognition since we're just reformatting
using (var jsonReader = new JsonTextReader(textReader) { DateParseHandling = DateParseHandling.None, CloseInput = false })
using (var jsonWriter = new JsonTextWriter(textWriter) { Formatting = formatting, CloseOutput = false })
{
jsonWriter.WriteToken(jsonReader);
}
return textWriter;
}
}
Using this method, the following code:
var json = #"{ ""val1"": ""\u003c=AA+ \u003e=AA-""}";
var unescapedJson = JsonExtensions.JsonPrettify(json, Formatting.None);
Console.WriteLine("Unescaped JSON: {0}", unescapedJson);
Outputs
Unescaped JSON: {"val1":"<=AA+ >=AA-"}
Demo fiddle here.
I tried the following in Linqpad and it worked.
var s = #"{ ""val1"": ""\u003c=AA+ \u003e=AA-""}";
System.Text.RegularExpressions.Regex.Unescape(s).Dump();

how to serialize a YamlDocument to yaml string

I use YamlDotnet and I have a YamlDocument. Now I want to convert it to his yaml text representation in memory but I don't see how to achieve that.
var yaml = new YamlDocument(new YamlMappingNode());
yaml.Add("one", "other")
var text = yaml.ToYamlText()
and I should get in text something like :
one: "other"
I tried zith Serializer class but with no success
ok so I found the solution in unit test of the source code :
var yaml = new YamlDocument(new YamlMappingNode());
yaml.Add("one", "other");
var yamlStream = new YamlStream(yaml);
var buffer = new StringBuilder();
using (var writer = new StringWriter(buffer))
{
yamlStream.Save(writer);
yamlText = writer.ToString();
}
Anyway, I have now another problem, I need all my values to be surrounded by double quotes. In another application I was using a QuoteSurroundingEventEmitter : ChainedEventEmitter with an object graph selrialization. But with yamlStream.Save() I don't see how to implement this mecanism

Removing formatting (\t\r) from a Stream Reader

I'm importing an .sql file that I created with SQLExplorer into my .NET program using StreamReader (which will eventually be passed through OdbcConnection, fyi.) The problem is that when I use the ReadToEnd() method it not only imports the SQL itself, but it imports all of the formatting. So the string is littered with \r and \t and the like.
I've been looking at both using split or possibly regex to break the string down and remove the unwanted bits and pieces. But before throwing a bunch of effort into that I wondered if there was perhaps something I'm missing in the StreamReader class? Is there a way to tell it to just ignore the formatting characters?
Here's the code I have right now:
public static Object SQLQueryFileCall(String SQLQueryFileName){
string SQLQuery = "";
string directory = System.IO.Path.GetDirectoryName( System.Reflection.Assembly.GetExecutingAssembly().Location);
SQLQueryFileName = directory + "\\" + SQLQueryFileName;
//read in the file and pass to ODBC, return a Object[] of whatever comes back...
try{
using (StreamReader myStreamReader = new StreamReader(SQLQueryFileName)) {
SQLQuery = myStreamReader.ReadToEnd();
Console.WriteLine(SQLQuery);
}
}
catch (Exception e){
//Find the error
Console.WriteLine("File could not be read:");
string error = e.Message;
MessageBox.Show(error);
return null;
}
}
Feel free to offer any advice you might have on the code, seeing as I'm pretty new.
But yeah, mostly I'm just hoping there's a method in the StreamReader class that I'm just not understanding. I've gone to Microsoft's online documentation, and I feel I've given it a good look, but then again, I'm new and perhaps the concept skipped over my head?
Any help?
NOTE: There are multiple \t that are in the middle of some of the lines, and they do need to be removed. Hence using trim would...be tricky at least.
Well, myStreamReader.ReadToEnd(); will get you everything. The easiest way to get rid of most unneeded whitespace is to read it line-by-line and then simply .Trim() every line.
using (StreamReader myStreamReader = new StreamReader(SQLQueryFileName))
{
string line;
List<string> lines = new List<string();
while ((line = myStreamReader.ReadLine()) != null)
lines.Add(line.Trim());
SQLQuery = string.Join("\n", lines);
Console.WriteLine(SQLQuery);
}
SQL, by definition, shouldn't have a problem with whitespaces like tabs and newlines throughout code. Verify that your actual SQL is correct first.
Also, blindly stripping whitespace could potentially have an impact on textual data contained within your script; what happens if you have a string literal that contains a tab character?
using (StreamReader myStreamReader = new StreamReader(SQLQueryFileName))
{
while ((line = myStreamReader.ReadLine()) != null)
{
Console.WriteLine(line.Trim().Replace(#"\t"," ")
}
}
If it is a display and not content issue I think you could use WPF and a RichTextBox.
SQLQuery = Regex.Replace(SQLQuery, #"\t|\n|\r", "");
Better to use as you could remove content of SQL insertions:
using (StreamReader reader = new StreamReader(fileName))
{
String line;
List<string> lines = new List<string();
while ((line = myStreamReader.ReadLine()) != null)
SQLQuery += line.Trim() + "\n";
}
This is what helped me in 2020, incase if someone is looking for this
using (StreamReader sr = new StreamReader(stream))
{
return Regex.Replace(sr.ReadToEnd().Trim(), #"\s", "");
}

Reading iso-8859-1 rss feed C# WP7

I'm trying to read a rss feed which uses the iso-8859-1 encoding.
I can get all elements fine, the problem is when I put it in a textblock it will not show all characters. I'm not sure what i'm doing wrong. i've tried a few solutions I found on google but this didn't work for me. I must be missing something.. It's also the first time I really work with anything other than utf-16. I never had to convert anything before.
The app works as follows I downloadstring async(WebClient). So when that is called I get a string containing the complete rss feed.
I have tried getting the bytes, then encoding.convert.. But I must be missing something.
Like this is a sample
WebClient RSS = new WebClient();
RSS.Encoding = Encoding.GetEncoding("ISO-8859-1");
RSS.DownloadStringCompleted += new DownloadStringCompletedEventHandler(RSS_DSC);
RSS.DownloadStringAsync(new Uri("some rss feed"));
public void RSS_DSC(object sender, DownloadStringCompletedEventArgs args)
{
_xml = XElement.Parse(args.Result);
foreach(XElement item in _xml.Elements("channel").Elements("item"))
{
feeditem.title = item.Element("title").Value;
// + all other items
}
}
I've tried this aswell
private void RSS_ORC(object sender, OpenReadCompletedEventArgs args)
{
Encoding e = Encoding.GetEncoding("ISO-8859-1");
Stream ez = args.Result;
StreamReader rdr = new StreamReader(ez, e);
XElement _xml = _xml = XElement.Parse(rdr.ReadToEnd());
feedlist = new List<Code.NewsItem>();
XNamespace dc = "http://purl.org/dc/elements/1.1/";
foreach (XElement item in _xml.Elements("channel").Elements("item"))
{
Code.NewsItem feeditem = new Code.NewsItem();
feeditem.title = item.Element("title").Value;
feeditem.description = item.Element("description").Value;
feeditem.pubdate = item.Element("pubDate").Value;
feeditem.author = item.Element(dc + "creator").Value;
feedlist.Add(feeditem);
}
listBox1.ItemsSource = feedlist;
}
Though titles contain characters that are not displayed well either. Like.. I can get the encoding to partially work. Instead of having these characters: the square with a question mark, a question mark or the singe square.
Don't get me wrong I'm a total beginner on this. But the solutions that has been posted on the web do not solve it for me.
Note that I removed the encoding part because it wasn't working :/
If someone would be able to help me that would be amazing.
You can specify an encoding by setting encoding before calling client.DownloadStringAsync:
webClient.Encoding = Encoding.GetEncoding("iso-8859-1")
In your code sample you do not create the XML doc anywhere. Are some code missing? You should initialize it with something like:
var xml = XDocument.Load((string)args.Result);
If it helps, you can use:
var myString = HttpUtility.HtmlDecode(feeditem.description);
This way every special character will be decode, you can then display myString correctly
Windows Phone 7 and Silverlight does not support other encodings such as ISO-8859-1, they only support ASCII and the Unicode encoders. For anything else you will need to use OpenReadAsync to get a stream of bytes then apply your own implementation of an encoding.
This blog might be helpful to you in creating one.
ISO-8859-1 most definitely is supported in WP7. It is the only one of the ISO-8859-* encodings that is. I use an XmlReader to deserialize RSS streams and UTF-* and ISO-8859-1 are the only encodings that are supported by that class (windows-* and ISO-8859-2 and above throw exceptions in the XmlReader c'tor).
Try using an XmlReader like this (without specifying the encoding):
using (XmlReader reader = XmlReader.Create(stream))
{
...
}
The XmlReader will get the encoding from the xml declaration in the stream.
You may still have problems displaying the upper half of the characters (above 0x80). I had this problem in feed me (my WP7 app) and used this little hack to fix things up:
public static string EncodeHtml(string text)
{
if (text == null) return string.Empty;
StringBuilder decodedText = new StringBuilder();
foreach (char value in text)
{
int i = (int)value;
if (i > 127)
{
decodedText.Append(string.Format("&#{0};", i));
}
else
{
decodedText.Append(value);
}
}
return decodedText.ToString();
}
It only works in a WebBrowser control of course, but that is the only place that I ever saw an incorrect display.
Hope this helps,
Calum
This worked for me when needing to decode the rss xml. It's generic enough so that it will support all encryption types supported by .NET
WebClient wcRSSFeeds = new WebClient();
String rssContent;
// Support for international chars
Encoding encoding = wcRSSFeeds.Encoding;
if (encoding != null)
{
encoding = Encoding.GetEncoding(encoding.BodyName);
}
else
{
encoding = Encoding.UTF8; // set to standard if none given
}
Stream stRSSFeeds = wcRSSFeeds.OpenRead(feedURL); // feedURL is a string eg, "http://blah.com"
using (StreamReader srRSSFeeds = new StreamReader(stRSSFeeds, encoding, false))
{
rssContent = srRSSFeeds.ReadToEnd();
}

Categories

Resources