2012-05-04 9 views
0

私はソフトウェアプロジェクトの移行段階としてWCFインターフェイスを使用して既存のASMX Webサービスをラップして時間を節約しています。これは、System.Stringを返す1つの関数を除いてうまく機能します。WCFが返しましたSystem.IO.Streamが文字化けしました

元の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= 

だから、結果の出力が文字化けしている(再び、私は(メッセージのエンコードによって引き起こされる、と思う)?)

メソッドは、OperationContractを持つ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> 

なぜ出力が文字化けしているのか、または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); 
} 
+0

テキスト 'MDIwMTA0MTVEQkQ4MDBEN0UxNzU3Nzc4N0E2MjY5Nzg ='はbase64でエンコードされた値の '02010415DBD800D7E17577787A626978'です。 – empi

+0

あなたのWCFサービスインターフェイスに関する詳細を投稿できますか?少なくともメソッド定義。私は実際にasmxを使用して文字列またはxmlを返すことができ、WCFを使用することができない理由を理解できません(xmlは文字列ではありませんか?)。 – empi

+0

更新していただきありがとうございますが、私の2番目の質問に答えることができますか?文字列を返すだけの理由はありませんか? – empi

答えて

0

だから私はいくつかの戻り値の型の周りいじっ、これはと何私ができるまでです:私は基本的に新しいルート要素内のすべての応答をラップ

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; 

。これは、「htmlエンコード」ではなく、エンベロープ内のリテラルXMLをSOAPに渡します。私の必要なことはしていますが、私はそれが厄介であると感じます。しかし私は私の必要性に合った他の解決策を見いだせなかったので、これを最終的な解決策として提示します。

0

使用basicHttpBindingの代わりに、wsHttpBinding。

+0

私は;-)です(更新された質問を参照してください) – Nebula

1

私はこの声明に同意することはできません。

これは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> 

更新

ちょうどそれは、次のテストを実行し、respone.FunctionResultの値をチェックしてください動作するように、XMLの標準的な方法だことを確実にするために:あなたの関数は、文字列を返す場合

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

私はあなたを保証します、私は横たわっていません。更新された質問をご覧ください。 – Nebula

+0

@Nebula:私はあなたが嘘をついていると言っているわけではありません:)私はあなたが生成/作成する場合、正しい結果を得なければならないと言っています。 – empi

+0

ああ、今私は問題を見る。実際、このサービスは従来のASP Webサイトで使用されています。私はこれがギャップが存在するところだと思います。すべてのメッセージを手書きで書かなければならないため、使用できるフレームワークはありません。 – Nebula

1

、それはそれがあるべきであることが普通ですコード化される。

文字列の代わりにXmlNodeを返すように関数を宣言してみてください。

+0

XmlNodeは平文をweelとして含むことができますか?だから親要素なし? – Nebula

+0

私の最初の応答に追加する;私は必ずしもそれが脱出されるのが普通だとは思わない。少なくとも私にこのエスケープを無効にするオプションを与えていない限り。多分そのような選択肢がありますか?その場合、私はまだこれを得ることができないためにこれを行う方法として学びたいと思います。 – Nebula

+0

@Nebula、エスケープを無効にするオプションがわかりません。 SOAPメッセージ内の文字列はエスケープする必要がありますが、これは呼び出し側に透過的でなければなりません。ノードの内容を抽出するXML APIは自動的に文字列をエスケープします。 – Joe

関連する問題