1

我有一个 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)

变成:

你喜欢 Hüsker 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 方法返回的字符串看起来很好,即使其中有特殊字符。然而,当我从 web 方法中抛出异常时,其消息中的特殊字符是不正确的。我怎样才能解决这个问题?

4

1 回答 1

1

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

您看到的修改是当使用 8 位编码解析编码为 utf-8 的文本时(即使用 8 位解码器解码 utf-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 模块以及为什么需要它,因此情况可能比我想象的要复杂。

于 2008-09-15T14:41:42.860 回答