【问题标题】:Accept UTF-8 encoded strings in ASP.NET WebService在 ASP.NET WebService 中接受 UTF-8 编码的字符串
【发布时间】:2012-12-04 14:40:11
【问题描述】:

我有一个看起来像这样的 ASP.NET WebService:

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

第三方应用程序应调用此 Web 服务。但是,此应用程序将字符串编码为 UTF-8,并且所有变音符号都替换为“??”。我可以查看通话,特殊字符的格式很好:

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

当我简单地在 webservice 方法中打印字符串时,这会产生以下输出:

?? - ?? - ??

这是一个测试

如何配置 WebService 以接受 UTF-8 编码的字符串?

更新

Fiddler 还告诉我 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 调用。 StreamReaders 编码设置为 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 编码。

【问题讨论】:

  • 只是一个技术点,但加密不是正确的形容词。由于 UTF-8 只是一个字符集,编码会更准确。
  • 当然你是对的,很抱歉混淆了:)

标签: asp.net web-services unicode encoding utf-8


【解决方案1】:

最后发现在接受 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";
}

感谢您的帮助!

【讨论】:

  • 很高兴听到你修复了它,我想知道为什么它不回退到从 xml 读取编码属性。我非常确定任何自动过程都会正确处理,因为所有信息都在那里,只有手动覆盖才会搞砸。
  • 确切的原因,我问这个问题的原因......我不知道,为什么 SOAP 消息(通常是 XML 消息)没有像 XML 文件那样被解析。但是...感谢您的帮助:-)
  • 对自定义 SoapExtension 做了同样的事情。在ProcessMessage 方法中,我在反序列化之前附加了"charset=UTF-8"
【解决方案2】:

试试这个:-

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

注意:-

字符串从不包含任何 utf-* 或任何其他编码

【讨论】:

  • 字符串(或 System.Strings)是 unicode 字符集(msdn.microsoft.com/en-us/library/system.string.aspx)。也许我可以通过这种方式从 UTF-8 编码的字符串中获取字节,但是在这个字符串中,元音变音已经被替换了。我已经更新了问题。
【解决方案3】:

SOAP 调用在某处被解码为 ASCII - 每个变音符号为 2 个字节,设置了高位,解码为 ASCII 时变为??

所以,这样的事情正在发生:

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

要确认是否确实发生了这种情况,您应该比较 stringA == "Ä - Ö - Ü" 而不是在某处打印。

我想您可以先在项目范围内搜索“ASCII”,然后在找到任何东西时从那里开始工作。

你也可以试试

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

Web.config 文件中的&lt;system.web&gt; 标记下。

【讨论】:

  • 有趣的地方!感谢您的研究。我试图解码请求输入流并更新问题(更新 2)。同样在整个解决方案中搜索 ASCII 也没有给出任何匹配项。
【解决方案4】:

我遇到了同样的问题。 Asmx Web 服务将我的 UTF-8 转换为 ASCII,或者说是??????。你的帖子对我帮助很大。 我找到的解决方案是将 SOAP 协议的版本从 1.1 更改为 1.2 我的意思是:

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>

问题解决了。

【讨论】:

    猜你喜欢
    • 2015-02-07
    • 2014-06-09
    • 2013-06-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多