0

I'm working on an email notification project, where in a preexisting Winforms screen the client can edit an email template - adding html, text, etc. A very simplified example input:

<!DOCTYPE html> 
<html>
    <head>
        <title>The Title</title>
    </head>

    <body bgcolor="#f2f2f2" style="margin: 0; padding: 0;">
        <br />
            <b>Please do not respond to this e-mail, as it is not monitored.</b>
        <br/>
        <br/>
            “Foo bar baz.
        <br/>
        <br/>
            Baz bar foo.”
        <br/>
    </body>
</html>

This is saved as a string. On the same screen, the user may then click a button which will raise a ShowDialog call on another Form. This form previews the user's html in a WebBrowser control:

this.webBrowser.DocumentText = theHtmlString;

And the results:

Winforms WebBrowser

Problem:

I am creating a WPF screen related to the Winforms screens mentioned. It too needs the ability to preview the user's html. To do so I've used an attached behavior modified from this version. Essentially, this dialog also previews the user's html in a WebBrowser control:

webBrowser.NavigateToString(theHtmlString);

However, the results aren't correct, as highlighted below:

WPF WebBrowser

If this were my own html input, I'd simply remove the offending characters and replace them with standard quotations. But since this input is from the client, how do I get WPF to render the same as Winforms?

The reason this poses an issue:

  1. In the old Winforms screen, the user creates/edits-existing email templates, previews them, is satisfied with the rendered example, saves changes.
  2. In the new WPF screen, the user exports/imports existing email templates, previews them, is dissatisfied with the rendered example and strange characters, becomes confused when the other screen still renders correctly - calls to report a "bug" in the new screen.

Simple Reproduction Example: - Credit to Eser

var encoded = WebUtility.HtmlEncode(" “ Test ” ");             //" “ Test ” "
var buf = Encoding.UTF8.GetBytes(" “ Test ” "); 
var str = Encoding.GetEncoding("Windows-1252").GetString(buf); //" “ Test †"
Community
  • 1
  • 1
OhBeWise
  • 5,350
  • 3
  • 32
  • 60
  • I don't think those quotes are valid in the Winforms side, WPF looks to be correct. They should be encoded as `“` and `”`. – Ron Beyer Oct 07 '15 at 21:05
  • @RonBeyer Your suggestion works. However, what if the user has already added the incorrect “ ” instead of `“` `”`? I'm sure I could a do a Replace on them before rendering, but it's likely that these won't be the only incorrect special characters. – OhBeWise Oct 07 '15 at 21:17
  • 2
    Special characters should be HTML encoded, if you had the plain text portions you could try to sanitize or encode it, but I'm not sure how you can detect it other than have a dictionary of special characters vs the HTML encoded strings and do a brute-force find/replace on each special character, taking care not to hit things like `<` or `>` that should be encoded in the user text, but left alone in the HTML. – Ron Beyer Oct 07 '15 at 21:20
  • 1
    `“ ”` chars doesn't have to be html-encoded. You can test it like this `var encoded = WebUtility.HtmlEncode(" “ ” ");` It seems like an charset/encoding problem. Here is a test case to regenerate it. `var buf = Encoding.UTF8.GetBytes(" “ ” "); var str = Encoding.GetEncoding("Windows-1252").GetString(buf);` – Eser Oct 07 '15 at 21:32

1 Answers1

1

Just add this meta tag to the <head> of your HTML:

<meta charset='utf-8'>

This will display the special characters correctly. I just tested your exact code with this and it works.

Dax Pandhi
  • 843
  • 4
  • 13
  • Thanks! Rarely dealing with html, I never would have thought of that. My solution was to ensure that anyone creating these templates was properly trained to use the Entity Name, Entity Number, or Hexadecimal Reference instead of copy-pasting. But this adds a nice fourth option for those who want to copy-paste / don't know where to find such special character codes. Existing errors will just have to be dealt with per case. – OhBeWise Oct 09 '15 at 15:13