2008-09-15 127 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模塊以及爲什麼需要它,所以情況可能比我想象的要複雜。