Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/wcf/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# WCF返回的System.IO.Stream已乱码_C#_Wcf_Stream_Iis 6 - Fatal编程技术网

C# WCF返回的System.IO.Stream已乱码

C# WCF返回的System.IO.Stream已乱码,c#,wcf,stream,iis-6,C#,Wcf,Stream,Iis 6,为了节省时间,我在我的软件项目中将现有的带有WCF接口的ASMXWebService包装为一个过渡阶段。除了一个返回System.String的函数外,它工作得很好 原始ASMX服务根据给定的参数返回文本或XML。这在ASMX中不是问题。在WCF中,返回值(如果是XML)会像这样转义:gml它应该在哪里。请看下面的肥皂 请求 POST http://someuri.org/WebServices/Utils.svc HTTP/1.1 Content-Type: text/xml; charset

为了节省时间,我在我的软件项目中将现有的带有WCF接口的ASMXWebService包装为一个过渡阶段。除了一个返回System.String的函数外,它工作得很好

原始ASMX服务根据给定的参数返回文本或XML。这在ASMX中不是问题。在WCF中,返回值(如果是XML)会像这样转义:
gml
它应该在哪里
。请看下面的肥皂

请求

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>
这在一定程度上有效

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,带有操作合同,服务托管在IIS6中,具有以下ABC:

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

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);
}

使用basicHttpBinding而不是wsHttpBinding

我不能同意这种说法:

这在ASMX中不是问题。在WCF中,返回值(如果是XML)为 像这样转义:
gml
它应该在哪里

我使用以下方法创建了一个服务:

[OperationContract]
string GetXml(string str);

public string GetXml(string str)
{
    return "<gml>" + str + "</gml>";
}
结果是:

<gml>test</gml>

如果函数返回一个字符串,则应该对其进行编码是正常的


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

因此,我尝试了一些返回类型,这就是我能想到的:

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编码”。虽然它满足了我的需要,但我觉得很尴尬。然而,我发现没有其他解决方案适合我的需要,所以我提出这作为最终解决方案

文本
MDIwMTA0MTVEQkQ4MDBEN0UxNzU3Nzc4N0E2MjY5Nzg=
02001415dbd800d7e17577787a626978
的base64编码值。能否在WCF服务界面上发布详细信息-至少方法定义。我真的不明白为什么使用asmx可以返回字符串或xml,而使用WCF则无法返回(xml不只是字符串吗?)。感谢您的更新,但您能否回答我的第二个问题?为什么不能返回字符串?因为DoStuff()方法也可以返回xml数据。变量中的这个XML字符串可能看起来像“data”,但在返回的SOAP信封中看起来像“gmldata/gml”。这就是我想解决的实际问题。您知道如何更改流的编码吗?从64位到8位?为什么要检查SOAP消息?你必须在这么低的水平上处理它吗?WCF必须对特殊的XML字符进行编码,才能以XML消息的形式发送,这是一种标准和预期的行为。我向你们保证,我没有撒谎。请看更新的问题。@Nebula:我不是说你在撒谎:)我是说,如果你生成/创建wcf客户端,你应该会得到正确的结果。啊,现在我看到问题了。实际上,该服务是由一个经典的ASP网站使用的。我想这就是存在差距的地方。我们必须手工编写所有的信息,所以没有框架可以使用。@Nebula:你说的经典ASP是什么意思?添加Web参考(而不是服务参考)也可以。我希望我正确理解您的问题。经典ASP是ASP.Net之前的技术。在那里,您不能简单地添加对webservices的引用,因为与ASP.Net相反,它本机不受支持。我更新的问题是否给了您解决这个问题的灵感,而无需添加额外的XML元素?XmlNode是否能够像weel一样包含纯文本?因此,没有父元素?添加到我的第一个响应中;我不一定认为逃跑是正常的。至少在没有给我一个禁用转义的选项的情况下。也许有这样的选择?在这种情况下,我想学习如何做到这一点,因为到目前为止我还无法获得它。@Nebula,我不知道有什么选项可以禁用转义。SOAP消息中的字符串需要转义,但这对调用方来说应该是透明的——任何提取节点内容的XML API都会自动取消对字符串的转义。是的,我也希望如此。然而,用于ASP Classic的XML API似乎并没有为我们做到这一点(我的同事写了这篇文章,我在VBS方面没有受过很好的培训)
[OperationContract]
string GetXml(string str);

public string GetXml(string str)
{
    return "<gml>" + str + "</gml>";
}
var client = new MyWcfServiceClient();
var result = client.GetXml("test");
<gml>test</gml>
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);                    
        }
    }            
}
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;