Skip to main content

CodeSOD: A JSON Serializer

3 months 2 weeks ago

Carol sends us today's nasty bit of code. It does the thing you should never do: serializes by string munging.

public string ToJSON() { double unixTimestamp = ConvertToMillisecondsSinceEpoch(time); string JSONString = "{\"type\":\"" + type + "\",\"data\":{"; foreach (string key in dataDict.Keys) { string value = dataDict[key].ToString(); string valueJSONString; double valueNumber; bool valueBool; if (value.Length > 2 && value[0].Equals('(') && value[value.Length - 1].Equals(')')) //tuples { char[] charArray = value.ToCharArray(); charArray[0] = '['; charArray[charArray.Length - 1] = ']'; if (charArray[charArray.Length - 2].Equals(',')) charArray[charArray.Length - 2] = ' '; valueJSONString = new string(charArray); } else if ((value.Length > 1 && value[0].Equals('{') && value[value.Length - 1].Equals('}')) || (double.TryParse(value, out valueNumber))) //embedded json or numbers { valueJSONString = value; } else if (bool.TryParse(value, out valueBool)) //bools { valueJSONString = value.ToLower(); } else //everything else is a string { valueJSONString = "\"" + value + "\""; } JSONString = JSONString + "\"" + key + "\":" + valueJSONString + ","; } if (dataDict.Count > 0) JSONString = JSONString.Substring(0, JSONString.Length - 1); JSONString = JSONString + "},\"time\":" + unixTimestamp.ToString() + "}"; return JSONString; }

Now, it's worth noting, C# already has some pretty usable JSON serialization built-ins. None of this code needs to exist in the first place. It's parsing across a dictionary, but that dictionary is itself constructed by copying properties out of an object.

What's fun in this is because everything's shoved into the dictionary and then converted into strings (for the record, the dictionary stores objects, not strings) the only way they have for sniffing out the type of the input is to attempt to parse the input.

If it starts and ends with a (), we convert it into an array of characters. If it starts and ends with {} or parses as a double, we just shove it into the output. If it parses as a boolean, we convert it to lower case. Otherwise, we throw ""s around it and put that in the output. Notably, we don't do any further escaping on the string, which means strings containing " could do weird things in our output.

The final delight to this is the realization that their method of handling appending will include an extra comma at the end, which needs to be removed. Hence the if (dataDict.Count > 0) check at the end.

As always, if you find yourself writing code to generate code, stop. Don't do it. If you find you actually desperately need to start by building a syntax tree, and only then render it to text. If you find yourself needing to generate JSON specifically, please, I beg you, just get a library or use your language's built-ins.

[Advertisement] Plan Your .NET 9 Migration with Confidence
Your journey to .NET 9 is more than just one decision.Avoid migration migraines with the advice in this free guide. Download Free Guide Now!
Remy Porter

EU Lawmakers Push To Ban Plant-Based Food Terms

3 months 2 weeks ago
An anonymous reader quotes a report from The Guardian: MEPs voted on Wednesday by 355 in favor to 247 against to reserve names such as "steak", "burger" and "sausage" exclusively for products derived from meat, a longstanding demand of farm unions. In order to come into effect, the idea would have to be approved by a majority of the EU's 27 member states, which is far from certain. The vote is a victory for the French centre-right MEP Celine Imart, who drafted the amendment to legislation intended to strengthen the position of farmers in the food supply chain. Imart, who is also a cereals farmer in north-west France, said: "A steak, an escalope or a sausage are products from our livestock, not laboratory art nor plant products. There is a need for transparency and clarity for the consumer and recognition for the work of our farmers." She argues the proposal is in line with EU rules that already ban the use of terms such as "milk" and "yoghurt" for non-dairy products. The European parliament rejected a ban on meaty names for plant-based products in 2020, but the 2024 elections shifted the parliament to the right, bringing in more lawmakers who seek close ties with farmers. Opposition was led by Green MEPs, who decried what they saw as a populist move to rename plant-based foods. "Veggie burgers, seitan schnitzel and tofu sausage do not confuse consumers, only rightwing politicians," Thomas Waitz, an Austrian Green MEP, said after the vote. "This tactic is a diversion and a pathetic smokescreen. No farmer will earn more money or secure their future with this ban."

Read more of this story at Slashdot.

BeauHD