Diacritic Marks not render correctly in Web App wh

2019-08-14 14:32发布

问题:

I have an MVC 4 application that I'm localizing. All the built-in resourcing and Model attributed content is appearing fine, but where I localized content written for JQuery the encoding appears wrong. Here is an example of how things render, note the red boxes... they should be the same word.

The problem appears to revolve around the below line of code in my View:

$("#FirstName").Watermark("@Resources.ApplicantGivenNameWatermark");

This JQuery essentially takes in a string and then writes it to the input when no other value has been supplied. Here is an abstract of that code:

$.fn.Watermark = function (text) {
    return this.each(
        function () {
            var input = $(this);
            map[map.length] = { text: text, obj: input };

            //Similar removal process lies here, this one also removes the style

            function insertMessage() {
                if (input.val().length == 0 || input.val() == text) {
                    input.val(text);
                    input.addClass("watermark");
                } else
                    input.removeClass("watermark")
            }

            input.focus(clearMessage);
            input.blur(insertMessage);
            input.change(insertMessage);

            insertMessage();
        }
    );
};

Any ideas on how to resolve this would be appreciated. As a side note, I've been able to reliably recreate this in a wide range of browsers.

回答1:

Try to put this at the begin of the function:

text=$('<span>'+text+'</span>').text();


回答2:

The problem is that Razor is built for outputting HTML, not Javascript. By default, it will encode all your strings with HTML entities - which aren't appropriate for Javascript strings.

You could use @Html.Raw(Model.YourString), but that will give you other problems, such as not escaping quotation marks etc. (the standard Razor output does that by "accident").

If you're using .NET 4.0/MVC 3, you can use AjaxHelper's JavaScriptStringEncode, which returns an IHtmlString (meaning Razor won't entity-encode it) but also does the proper Javascript-specific escaping (including line breaks in the source string, which the standard Razor encoding won't "fix"):

$("#FirstName").Watermark(
   "@Ajax.JavaScriptStringEncode(Resources.ApplicantGivenNameWatermark")");

(Yeah, it turns rather verbose... but does have the advantage of fixing the problem at its root, rather than working around it through jQuery - you could of course make a helper with a short name which called JavaScriptStringEncode.

Note that it's also a static method on HttpUtility - easier to call from a custom helper than making an instance of AjaxHelper, but note that unlike AjaxHelper, the method on HttpUtility returns a simple string, so you'll need to wrap it in an HtmlString to avoid HTML encoding.