2012-12-04 65 views
1

UTF-8編碼字符串我有一個ASP.NET的WebService,看起來是這樣的:接受在ASP.NET的WebService

[WebMethod] 
public static void DoSomethingWithStrings(string stringA, string stringB) 
{ 
    // and so on 
} 

的第三方應用程序應調用此WebService。然而,這個應用程序將字符串編碼爲UTF-8,所有的元音變爲'??'。我可以查看呼叫,而特殊字符格式以及:

<?xml version="1.0" encoding="utf-8" ?> 
<!-- ... --> 
<SoapCall> 
    <DoSomethingWithStrings> 
     <stringA>Ä - Ö - Ü</stringA> 
     <stringB>This is a test</stringB> 
    </DoSomethingWithStrings> 
</SoapCall> 

這產生以下輸出,當我僅僅打印該web服務方法內的字符串:

?? - ?? - ??

這是一個測試

我如何配置的WebService接受UTF-8編碼字符串?

更新

菲德勒還告訴我,HTTP請求的內容類型的字符集是UTF-8。

更新2

我嘗試下面的代碼添加到global.asax調試目的:

public void Application_BeginRequest(object sender, EventArgs e) 
{ 
    using (var reader = new System.IO.StreamReader(Request.InputStream)) 
    { 
     string str = reader.ReadToEnd(); 
    } 
} 

這讀取實際SOAP調用。 StreamReader的編碼設置爲UTF-8。 SOAP調用看起來是正確的:

<?xml version="1.0" encoding="UTF-8" ?> 
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"> 
    <SOAP-ENV:Body> 
     <DoSomethingWithStrings xmlns="http://www.tempuri.org/"> 
      <stringA>Ä - Ö - Ü</stringA> 
      <stringB>This is a test!</stringB> 
     </DoSomethingWithStrings> 
    </SOAP-ENV:Body> 
</SOAP-ENV:Envelope> 

web.config文件全球化設置正確:

<globalization requestEncoding="UTF-8" responseEncoding="UTF-8" culture="de-DE" uiCulture="de-DE" /> 

所以它看起來像是反序列化SOAP消息不使用UTF-8,但ASCII編碼。

+0

只是一個技術點,但加密不是正確的形容詞。由於UTF-8只是一個字符集,編碼會更準確。 – tomasmcguinness

+0

當然你是對的,對不起,混淆:) – Carsten

回答

2

最後事實證明接受HTTP消息中出現了問題。我實際上並不知道什麼操縱HTTP請求,但我找到了一個解決方法。雖然Fiddler向我展示了我的Application_BeginRequest中的正確內容類型(text/xml; charset=utf-8),但Request.RequestContext.HttpContext.Request.ContentType只是text/xml,導致在ASMX串行器內回退到默認(ASCII)編碼。我已將以下代碼添加到Application_BeginRequest處理程序中,現在一切正常。

if (Request.RequestContext.HttpContext.Request.ContentType.Equals("text/xml")) 
{ 
    Request.RequestContext.HttpContext.Request.ContentType = "text/xml; charset=UTF-8"; 
} 

感謝您的幫助!

+0

很高興聽到你得到它修復,我想知道爲什麼它不會從xml讀取編碼屬性。我很確定任何自動過程都能正確完成,因爲所有的信息都在那裏,只有手動控制纔會把它搞砸。 – Esailija

+0

究竟是什麼原因,爲什麼我問這個問題......我不知道爲什麼SOAP消息(通常是XML消息)得不到像XML文件一樣的解析。然而...感謝您的幫助:-) – Carsten

0

試試這個: -

byte[] bytes=Encoding.UTF8.GetBytes(yourString); 

注: -

字符串永遠不會包含任何UTF-*或其他任何編碼

+0

字符串(或System.Strings)是一組Unicode字符(http://msdn.microsoft.com/en-us/library/system.string.aspx) 。也許我可以用這種方式從UTF-8編碼的字符串中獲取字節,但在這個字符串中,Umlauts已經被替換了。我已經更新了這個問題。 – Carsten

0

SOAP調用被解碼爲ASCII地方 - 每個變音符都是2個字節,高位被設置,當解碼爲ASCI時變成??一世。

所以,這樣的事情正在發生:

byte[] bytesSentFromClient = Encoding.UTF8.GetBytes("Ä - Ö - Ü"); 
string theStringIThenReceiveInMyMethod = Encoding.ASCII.GetString(bytesSentFromClient); 
Console.WriteLine(theStringIThenReceiveInMyMethod); 
//?? - ?? - ?? 

爲了驗證這一點正在發生的事情是肯定的,你應該比較stringA == "Ä - Ö - Ü",而不是某個地方進行打印。

我想你可以先做一個項目範圍的「ASCII」搜索,然後從那裏工作,如果你發現任何東西。

您也可以嘗試

<globalization requestEncoding="utf-8" responseEncoding="utf-8"/> 

<system.web>標籤中Web.config文件。

+0

有趣的一點!感謝您的研究。我試圖解碼請求輸入流並更新了問題(更新2)。也搜索整個解決方案的ASCII不會有任何匹配。 – Carsten

0

我有同樣的問題。 Asmx web服務將我的UTF-8轉換爲ASCII,或者更好地說給??????。你的文章幫了我很多。 我發現的解決方案是從1.1至1.2 我的意思是改變SOAP協議的版本:

POST /WebService1.asmx HTTP/1.1 
Host: www.tempuri.org 
Content-Type: text/xml; charset=utf-8 
Content-Length: length 
SOAPAction: "http://www.tempuri.org/HelloWorld" 

<?xml version="1.0" encoding="utf-8"?> 
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"> 
    <soap:Body> 
    <HelloWorld xmlns="http://www.tempuri.org/"> 
     <inputParam>Привет</inputParam> 
    </HelloWorld> 
    </soap:Body> 
</soap:Envelope> 

出現了問題。但是當我將請求更改爲SOAP 1.2時:

POST /WebService1.asmx HTTP/1.1 
Host: www.tempuri.org 
Content-Type: application/soap+xml; charset=utf-8 
Content-Length: length 

<?xml version="1.0" encoding="utf-8"?> 
<soap12:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://www.w3.org/2003/05/soap-envelope"> 
    <soap12:Body> 
    <HelloWorld xmlns="http://www.tempuri.org/"> 
     <inputParam>Привет</inputParam> 
    </HelloWorld> 
    </soap12:Body> 
</soap12:Envelope> 

問題已解決。