2008-09-15 79 views
1

我有一个web服务(ASMX),并且在其中有一个web方法,它执行一些工作并在输入无效时抛出异常。ASP.NET WebService在抛出异常时返回异常字符

[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在那里)

它显示了这一点:

该输入ISNA€™吨有效!

或者:

你喜欢哈斯克·杜?(ASCII#252)

变为:

你喜欢HüskerDü?

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

<?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模块设置本地化参数:

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; 

我试过disablin g这个HTTP模块,但结果是一样的。

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

回答

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()Exception之前,您所做的HtmlEncode()可能是错误的关于预期的输出编码。那么如果你没有HtmlEncode()错误信息会发生什么? (技术上说,“ASCII#252”不是很正确; ASCII有128个字符;你使用的撇号来自8位编码,例如,在你的情况下,iso-8859-1/Windows- )

你确定你已经禁用了HTTP模块吗?这行看起来可能会造成问题:

HttpContext.Current.Response.ContentEncoding = l_Enc;

...因为它是最有可能设置输出编码的8位编码(ANSI代码页当量)。

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