3

I need to remove some newline characters from some string values while serializing to JSON -- i.e. during c# object to JSON conversion. How can this be done?

public static string ToJson(this object value)
{
  //Serializing C# Object to Json which gives me below mentioned JSON.
  return JsonConvert.SerializeObject(value);
}

Below is my sample JSON:

{
    "PolicyHolderInfo": {
        "ActionDate": "20190912",
        "EmployeeCode": "EPL2",
        "LocalEntityCode": "K",
        "PolicyHolderCode": "1YAAAAC",
        "Name1": "monoliability PDL\n",
        "Name2": "test\n",
        "Street1": "-",
        "Street2": "-",
        "City": "-",
        "PostCode": "-",
        "Subdivision": "01",
        "FMEPaymentFrequency1": "00",       
        "Reference": "C00-AAC"
    },
    "PolicyHolderTrailerInfo": {
        "RecordCode": "Z",
        "CountryCode": "KSA",
        "SourceIndicator": "EPLC",
        "RecordSequence": 0,
        "LinkNumber": 0,
        "RecordType": "Z",
        "ReturnCode": null,
        "Reference": "1-AC"
    },
    "SourceSystemDate": "2019-09-17T17:48:31.3543314+08:00"
}

The Name1 and Name2 has newline character \n. I tried many options to remove those \n. Instead of looping through every value, I am just trying to replace globally if any new line characters present. None of the below options are working?

C#:

var str1 = JsonConvert.ToString(value);
var str2 = value.Replace(System.Environment.NewLine, string.Empty);
Regex regex_newline = new Regex("(\r\n|\r|\n)");
var str3 = regex_newline.Replace(value, "");
var str4 = value.Replace("\n", string.Empty);  

The 'value' in above code is json mentioned in the sample.

Govind
  • 979
  • 4
  • 14
  • 45
  • 1
    Note that the regex will match carriage return + newline, as opposed to string literal `"\n"`, which is what it seems you want to do. – ProgrammingLlama Sep 18 '19 at 07:17
  • 1
    Why are you converting the JSON to string `str1 = JsonConvert.ToString(value)` when JSON is already a string? – phuzi Sep 18 '19 at 07:19
  • @phuzi I just tried different options which one is work out. var str1 = JsonConvert.ToString(value); just to see how it is escaping. – Govind Sep 18 '19 at 07:21
  • @John yes i am trying to replace "Abc \n" to "Abc" where "\n" contains in JSON i just want to replace with empty. – Govind Sep 18 '19 at 07:22
  • 1
    That's not actually a newline character. The [JSON standard](https://json.org/) requires that newline characters be escaped using the `\n` character sequence. Are you trying to replace the escape sequence by searching for an actual newline? On the other hand replacing all instances of the pair of characters `\n` seems iffy. – dbc Sep 18 '19 at 07:23
  • @dbc I am getting json from other 3rd party, \n present in some of the fields of source json . When I try to create flat file using the values \n automatically goes to nextline. So I want to remove \n before I create flat file. – Govind Sep 18 '19 at 07:30
  • 1
    Do you want to remove newlines while serializing or deserializing? if you want to remove newlines while deserializing use `ReplacingStringConverter` from [this answer](https://stackoverflow.com/a/38384977/3744182) to [running a transformation on a Json DeserializeObject for a property](https://stackoverflow.com/q/38351661/3744182) and replace `"\n"` with `""`. – dbc Sep 18 '19 at 07:33
  • @dbc while serializing (i.e.) i want to do from c# object to Json conversion – Govind Sep 18 '19 at 07:56
  • 1
    If this happens "while serializing to JSON"... why not just trim the original properties on the objects this json is generated from, _before_ generating the json? Or even better, put auto-trim in these properties' setters and getters, since a line break has no place in a name anyway. Also, none of your code shows that serialisation process. Just your attempts at fixing it _afterwards_. – Nyerguds Sep 18 '19 at 10:09
  • 1
    Side note, if you want to search for a literal string `\n` in c#, you need to put it in as `"\\n"`. – Nyerguds Sep 18 '19 at 10:15
  • @Nyerguds I haved edited the question to add serialization code. – Govind Sep 18 '19 at 10:21

1 Answers1

4

You can modify the logic of ReplacingStringConverter from this answer to running a transformation on a Json DeserializeObject for a property to remove \n characters while serializing string value(s).

First, define the following converter:

public class ReplacingStringWritingConverter : JsonConverter
{
    readonly string oldValue;
    readonly string newValue;

    public ReplacingStringWritingConverter(string oldValue, string newValue)
    {
        if (string.IsNullOrEmpty(oldValue))
            throw new ArgumentException("string.IsNullOrEmpty(oldValue)");
        if (newValue == null)
            throw new ArgumentNullException("newValue");
        this.oldValue = oldValue;
        this.newValue = newValue;
    }

    public override bool CanConvert(Type objectType)
    {
        return objectType == typeof(string);
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }

    public override bool CanRead { get { return false; } }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        var s = ((string)value).Replace(oldValue, newValue);
        writer.WriteValue(s);
    }
}

Then you can serialize your root data model as follows:

var settings = new JsonSerializerSettings { Converters = { new ReplacingStringWritingConverter("\n", "") } };
var newJson = JsonConvert.SerializeObject(root, Formatting.None, settings); 

The converter works when serializing both typed data models with a fixed schema and LINQ to JSON freeform JSON captured in a JToken hierarchy.

(As an aside, I believe your value.Replace() is failing because JSON string values never actually contain newline characters. Instead, as specified by the JSON standard, a newline character must be replaced by the two-character escape sequence \n. Thus value.Replace("\n", string.Empty) fails, as the \n in your code is the c# escape sequence for an actual newline character -- which is not present.)

Demo fiddle here.

dbc
  • 104,963
  • 20
  • 228
  • 340
  • It worked.. before accepting this answer, can you please tell what is the use of JToken. I have my own c# class object. Can I user that instead of JToken. var root = JsonConvert.DeserializeObject(GetJson()); – Govind Sep 18 '19 at 09:41
  • 1
    @Govind - `JToken` is like `XDocument` for JSON, it represents arbitrary free-form JSON without a predefined schema. See: [JSON.NET: Why Use JToken--ever?](https://stackoverflow.com/q/38211719/3744182). I used it to load and save your JSON because you did not include a typed data model in your question. The converter works when serializing a typed data model also. – dbc Sep 18 '19 at 15:47