WCF 返回 System.IO.Stream 乱码

本文关键字:Stream 乱码 IO System 返回 WCF | 更新日期: 2023-09-27 18:33:14

我正在使用 WCF 接口包装现有的 ASMX Web 服务,作为软件项目中的过渡阶段,以节省时间。除了一个返回System.String的函数外,这工作得很好。

原始 ASMX 服务返回文本或 XML,具体取决于给定的参数。这在 ASMX 中不是问题。在 WCF 中,返回的值(如果是 XML(被转义,如下所示:&lt;gml&gt;<gml>的位置。请参阅下面的 SOAP。

请求

POST http://someuri.org/WebServices/Utils.svc HTTP/1.1
Content-Type: text/xml; charset=utf-8
SOAPAction: http://www.someuri.org/IUtils/Function
Content-Length: 283
Accept: */*
User-Agent: Mozilla/4.0 (compatible; Win32; WinHttp.WinHttpRequest.5)
Host: foo.bar.org
Connection: Keep-Alive
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
    <s:Body>
        <Function xmlns="http://www.someri.org/">
            <type>...</type>
            <input1>...</input1>
            <input2>...</input2>
            <input3>true</input3>
        </Function >
    </s:Body>
</s:Envelope>

响应

HTTP/1.1 200 OK
Date: Fri, 04 May 2012 11:40:01 GMT
Server: Microsoft-IIS/6.0
X-Powered-By: ASP.NET
X-AspNet-Version: 2.0.50727
Cache-Control: private
Content-Type: text/xml; charset=utf-8
Content-Length: 2070
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
    <s:Body>
        <FunctionResponse xmlns="http://www.crotec.nl/">   
            <FunctionResult>&lt;gml&gt;data&lt;/gml&gt;</FunctionResult>
        </FunctionResponse>
    </s:Body>
</s:Envelope>

一些谷歌搜索让我返回了一个System.IO.Stream对象。

string result = DoStuff(arg1, arg2, arg3);            
byte[] bin = Encoding.UTF8.GetBytes(result);
WebOperationContext.Current.OutgoingResponse.ContentType = "text/plain";
return new System.IO.MemoryStream(bin);

这在一定程度上有效。

string result =  "02010415DBD800D7E17577787A626978";
byte[] bin = {48,50,48,49,48,52,49,53,68,66,68,56,48,48,68,55,69,49,55,53,55,55,55,56,55,65,54,50,54,57,55,56};

但是,SOAP 消息中返回的结果是:

MDIwMTA0MTVEQkQ4MDBEN0UxNzU3Nzc4N0E2MjY5Nzg=

所以结果输出是乱码(再次,我认为,由消息编码(?

该方法是带有操作协定的 attr,服务托管在具有以下 ABC 的 IIS6 中:

<service name="WebServices.BeheerUtils" behaviorConfiguration="Services.ServiceBehavior">
    <!-- Service Endpoints -->
    <endpoint address="" binding="basicHttpBinding" contract="WebServices.IUtils"/>
    <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
</service>

知道为什么输出是乱码或如何防止HTML编码吗?

接口

[OperationContract]
System.IO.Stream Function(string type, string input1, string input2, string input3);

实现

public new System.IO.Stream Function(string type, string input1, string input2, string input3)
{
    // Call the old ASMX method
    string result = DoStuff(type, input1, input2, input3, true);
    byte[] bin = Encoding.UTF8.GetBytes(result);
    WebOperationContext.Current.OutgoingResponse.ContentType = "text/plain";
    return new System.IO.MemoryStream(bin);
}

WCF 返回 System.IO.Stream 乱码

如果您的函数返回一个字符串,那么对其进行编码是正常的。

您可以尝试声明函数以返回XmlNode而不是字符串。

我不能同意这个说法:

这在 ASMX 中不是问题。在 WCF 中,返回的值(如果为 XML(为 转义像:&lt;gml&gt;应该<gml>的地方.

我创建了一个带有方法的服务:

[OperationContract]
string GetXml(string str);
public string GetXml(string str)
{
    return "<gml>" + str + "</gml>";
}

然后,我使用生成的 WCF 客户端调用该服务:

var client = new MyWcfServiceClient();
var result = client.GetXml("test");

结果是:

<gml>test</gml>

更新

只是为了确保您这是xml行为的标准方式,请执行以下测试并检查respone.FunctionResult的值:

public class FunctionResponse
{
    public string FunctionResult { get; set; }
}
public void Test()
{
    var serialized = @"<?xml version=""1.0"" encoding=""UTF-8""?>
<FunctionResponse>   
    <FunctionResult>&lt;gml&gt;data&lt;/gml&gt;</FunctionResult>
</FunctionResponse>";
    var ser = new XmlSerializer(typeof(FunctionResponse));
    using (var stringReader = new StringReader(serialized))
    {
        using (var xmlReader = new XmlTextReader(stringReader))
        {
            var response = ser.Deserialize(xmlReader);                    
        }
    }            
}

使用 basicHttpBinding 而不是 wsHttpBinding。

所以我摆弄了一些返回类型,这就是我能做的:

string result = DoStuff(type, input1, input2, input3, true);
XDocument d = new XDocument();
XDocument basis = new XDocument(new XElement("result"));
// Load the result into a XDocument, add the result as a value of the wrapper element if the format is invalid    
try
{
    d = XDocument.Parse(result);
    basis.Root.Add(d.Root);
}
catch (Exception)
{
    basis.Root.Value = result;
}    
// Return the XElement
return basis.Root;

我基本上将所有响应包装在一个新的根元素中。这给了我 SOAP 包络中的文字 XML,而不是"html 编码"。虽然它满足了我的需要,但我觉得很尴尬。但是,我发现没有其他解决方案适合我的需求,因此我将其作为最终解决方案。