0

All, trying to create a custom JsonConverter that changes the decimal seperator based on the culture passed as a parameter while serializing to a Json(similar to this).
Sample Console Application:

using System;
using Newtonsoft.Json;
using System.Collections.Generic;
using System.Globalization;

namespace TestJsonConverter
{
    class Program
    {

        class FormattedDecimalConverter : JsonConverter
        {
            private CultureInfo cultureinput;
            public FormattedDecimalConverter(CultureInfo culture)
            {
                this.cultureinput = culture;
            }
            public override bool CanConvert(Type objectType)
            {
                return (
                        objectType == typeof(decimal) ||
                        objectType == typeof(double) ||
                        objectType == typeof(float));
            }
            public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
            {
                var strValue = Convert.ToString(value, cultureinput);//String
                var doublevalue = Convert.ToDouble(strValue, cultureinput);//ConvertToDouble
                double doublevalueusingparse;
                Double.TryParse(strValue, NumberStyles.Any, cultureinput, out doublevalueusingparse);//TryParseToDouble


                writer.WriteValue(strValue);
                writer.WriteValue(doublevalue);
                writer.WriteValue(doublevalueusingparse);
            }
            public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
            {
                throw new NotImplementedException();
            }
        }
        static void Main(string[] args)
        {
            List<double> values = new List<double> { 1.02 };

            var converter = new FormattedDecimalConverter(CultureInfo.GetCultureInfo("nl-BE"));
            string json = JsonConvert.SerializeObject(values, converter);

            Console.WriteLine(json);
            Console.ReadLine();
        }
    }
}


Produces the following output:
["1,02",1.02,1.02]

Question: How to retain the comma seperator while writing the value as double? Writing the string produces a comma but while writing as a double its writer with a period.
Thanks in advance

SriramN
  • 432
  • 5
  • 19
  • 1
    `1.02` is the "native" number value and any culture specific way of saving data would require corresponding loading code (i.e. your JSON is no longer representing data in a standard way for numbers). What problem are you trying to solve? – crashmstr Sep 21 '20 at 13:41
  • 2
    Good luck deserializing `[1,02]` in any other client application (is that a single value `1.02` or 2 array items `[ 1, 2 ]` ?). Culture are used mainly to display thing in a readable way for users, not for API consumers. – Cid Sep 21 '20 at 13:45
  • The only way this could be implemented would be to write as a string. You then need code to handle loading that string back into a number when deserializing. No other code without something to handle this would not load the value as a number or would need to manually parse it with the correct culture code. – crashmstr Sep 21 '20 at 14:02
  • @Cid, its a single value 1.02 – SriramN Sep 21 '20 at 14:49
  • 1
    XML does not have numbers, so everything has to be strings. In that case, C# gets in your way - you *should* be saving without culture specific formatting! In JSON, a number should be a number. – crashmstr Sep 21 '20 at 14:57
  • 1
    The JSON you are trying to generate is **malformed** according to the [JSON spec](https://json.org/). See [German culture - get double number from JSON with a comma](https://stackoverflow.com/a/28405144/3744182), of which I reckon this is a duplicate, agree? You can serialize doubles as localized *strings*, although I don't recommend it. See [How to localize when JSON-serializing?](https://stackoverflow.com/q/4721143/3744182). – dbc Sep 21 '20 at 15:25
  • And since, in the JSON standard, the comma is already used as an array separator, using a comma separator to serialize `new double [] { 1.2 }` would generate JSON that is indistinguishable from an array of two values `new double [] { 1, 2 }` which shows why this would be a bad idea. – dbc Sep 21 '20 at 15:31
  • @crashmstr, I a generic conversion of xml to json. I would like to add a parameter culture that can be configured for serialized Json. Example json output expected : {"Sample": {"Text": "Sample", "Double": 10,12}}. But what is currently created is {"Sample": {"Text": "Sample", "Double": "10,12"}}. I dont want the double value to be a string in the json created. – SriramN Sep 21 '20 at 15:37
  • @dbc, will check these links. the output is just to show the different values to compare, the actual json thats created is a valid one. – SriramN Sep 21 '20 at 15:40
  • 2
    `{"Sample": {"Text": "Sample", "Double": 10,12}}` is simply not well-formed JSON. Upload it to https://jsonlint.com/ and you will get a parse error *`Error: Parse error on line 4: Expecting 'STRING', got 'NUMBER'`*. There is no way you will be able to parse that with any JSON parser. But if you have an example of well-formed JSON you want to create, then we should be able to help. – dbc Sep 21 '20 at 15:41
  • Or if you are really doing JSON to XML conversions you may have an [XY problem](https://meta.stackexchange.com/q/66377). If you can show us how you are doing the conversion, maybe we can help with that. – dbc Sep 21 '20 at 15:43
  • {"Sample": {"Text": "Sample", "Double": 10,12}} -I see that this is an invalid json. Thanks @dbc. So if I have to send a json to consumer with a culture that uses comma as a double seperator, the only option is to send it with a '.' seperator or as a string with comma seperator. Both can be incorrect as the '.' can be a thousandsseperator in the consumer's culture and a string for a double is not right as well. Am I getting this right? What are the options here for this. – SriramN Sep 21 '20 at 15:52
  • 2
    *What are the options here for this* - if you need to generate well-formed JSON those are the options. If your consumer requires `{"Text": "Sample", "Double": 10,12}` then it is not actually using a JSON parser, it is using something different. Best I can recommend is to check the documentation for the consumer to find out its actual requirements and confirm it really requires malformed JSON. – dbc Sep 21 '20 at 15:56
  • If you really do need to generate malformed JSON use `WriteRawValue()` as shown in [How to deserialize dodgy JSON (with improperly quoted strings, and missing brackets)?](https://stackoverflow.com/a/46797460/3744182). – dbc Sep 21 '20 at 15:56

1 Answers1

0

As passing the double value with a comma in a Json will result in an invalid Json, the better options are to transfer the double value as a string like {"Sample": {"Text": "Sample", "Double": "10,12"}} or transfer it with a period. Will choose the string option here. Thanks for all the clarifications.

SriramN
  • 432
  • 5
  • 19