Background
If I read the W3 spec https://www.w3.org/TR/REC-xml/#sec-line-ends correctly, it is not valid to return CR LF (\r\n) or just CR inside an XML element value (i.e. to represent a newline). It must be just LF.
There are some references to the DataContractSerializer "handling this automatically", and I can see that what it does is a replacement as follows: \r\n => 
\n
(i.e. the CR has been escaped to its character entity, leaving only the LF).
However, if my WCF service response (WCF uses DataContractSerializer) serialises a string containing CRLF to 
\n
as above, some (non Windows) client applications (not in my control) fail to deserialise the XML because "it is not valid XML" (their claim). They claim that \n
is valid but not 
\n
.
Whether or not it really is valid XML is not the issue - the clients cannot be recoded, but the service can, so I need to do something on the service side to convert \r\n => \n
.
My issue - if I manually remove CR, WCF service response seems to put it back in!
So in the class that is serialised to make the response to a WCF method call, I did a simple replace within strings, as follows using an extension method:
[DataMember(IsRequired = true, Order = 3)]
public string Address
{
get { return Data.Address.MakeXmlSafe(); }
internal set { }
}
public static string MakeXmlSafe(this string source)
{
if (string.IsNullOrEmpty(source))
return source;
// In XML it is not valid to return CR LF (\r\n) or just CR (\r) as a newline. It must be just LF (\n).
return source.Replace("\r\n", "\n").Replace("\r", "\n");
}
(FYI, the service is .NET Framework 4.6)
Debugging the service, I can see the replacement being made correctly. HOWEVER, if I check the response in a tool such as SOAPUI, or WCF Service Trace Viewer Tool (SvcTraceViewer.exe) the newlines are represented as CR LF (\r\n).
For sanity, I also tested that manually serialising with DataContractSerializer preserves the LF with no CR, and it does:
I don't know if the tools (being Windows applications) are automatically replacing LF with CR LF, in order to render it. Or is WCF doing a replacement after DataContractSerializer? If so, what can I do to guarantee the conversion \r\n => \n
(and not \r\n => 
\n
)?