我有一个 Web 服务 (ASMX),其中有一个 Web 方法,该方法执行一些工作并在输入无效时引发异常。

[ScriptMethod]
[WebMethod]
public string MyWebMethod(string input)
{
    string l_returnVal;

    if (!ValidInput(input))
    {
        string l_errMsg = System.Web.HttpUtility.HtmlEncode(GetErrorMessage());
        throw new Exception(l_errMsg);
    }

    // some work gets done...

    return System.Web.HttpUtility.HtmlEncode(l_returnVal);
} 

回到网页上的客户端 JavaScript,在错误回调函数上,我显示我的错误:

function GetInputErrorCallback(error)
{
    $get('input_error_msg_div').innerHTML = error.get_message();
}

这非常有效,当我的 Web 方法返回(一个字符串)时,它看起来总是很完美。但是,如果我抛出的异常中的一条错误消息包含特殊字符,则它在浏览器中显示不正确。例如,如果错误消息包含以下内容:

该输入无效! (其中有 ASCII #146)

它显示这个:

该输入无效!

或者:

你喜欢 Hüsker Dü 吗? (ASCII#252)

变成:

你喜欢 Husker Dü吗?

错误消息的内容来自采用 UTF-8 编码的 XML 文件:

<?xml version="1.0" encoding="UTF-8"?>
<ErrorMessages>
   <Message id="invalid_input">Your input isn’t valid!</Message>
   .
   .
   .
</ErrorMessages>

就页面编码而言,在我的 Web.config 中,我有:

<globalization enableClientBasedCulture="true" fileEncoding="utf-8" />

我还有一个 HTTP 模块来设置 L10n 参数:

Thread.CurrentThread.CurrentUICulture = m_selectedCulture;
Encoding l_Enc = Encoding.GetEncoding(m_selectedCulture.TextInfo.ANSICodePage);
HttpContext.Current.Response.ContentEncoding = l_Enc;
HttpContext.Current.Request.ContentEncoding = l_Enc;

我尝试禁用此 HTTP 模块,但结果是相同的。

Web 服务返回的值(在 l_errMsg 变量中)在 VS 调试器中看起来很好。只是一旦客户端脚本掌握了,它就会显示不正确。我使用 Firebug 查看响应,其中的特殊字符也被破坏了。所以我觉得很奇怪,我的网络方法返回的字符串看起来很好,即使其中有特殊字符。然而,当我从 Web 方法抛出异常时,其消息中的特殊字符不正确。我怎样才能解决这个问题?

有帮助吗?

解决方案

您确定设置“fileEncoding”是您想要的,而不是“responseEncoding”吗?设置 fileEncoding 确定 Web 服务器在无法自动确定编码时将如何尝试从磁盘读取物理 .asmx/.aspx 文件。因此,将其设置为“utf-8”意味着您必须以 utf-8 保存所有 .asmx/.aspx 文件。我认为不相关。

您看到的损坏是使用 8 位编码(即,解析为 utf-8 编码的文本)时发生的。utf-8 字节流使用 8 位解码器进行解码,例如您的情况是 iso-8859-1/Windows-1252)。因此,您在 throw() 异常之前执行的 HtmlEncode() 可能对于预期的输出编码是错误的。那么如果你不 HtmlEncode() 错误消息会发生什么?

(从技术上讲,“ASCII # 252”不太正确;ASCII有128个字符;您使用的撇号来自 8 位编码,例如您的情况是 iso-8859-1/Windows-1252。)

您确定已正确禁用该 HTTP 模块吗?此行看起来可能会导致问题:

HttpContext.Current.Response.ContentEncoding = l_Enc;

...因为它很可能将输出编码设置为 8 位编码(相当于 ANSI 代码页)。

为了支持尽可能多的文化,您应该将响应编码设置为 utf-8。 这是浏览器中支持最多的 Unicode 格式(我敢说所有现代浏览器都支持它),并且 Unicode 是本地编码的唯一替代方案。也就是说,我不完全理解您正在使用什么 HTTP 模块以及为什么需要它,所以情况可能比我想象的更复杂。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top