首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> 關於.NET

WCF 分散式開發常見錯誤 (30):期望的初始元素是 'Binary'

     編輯:關於.NET

錯誤現象

調試 WCF 4.0 自定義綁定 ByteStreamMessageEncodingBindingElement 時,客戶端拋出異常:

Start element 'Binary' expected(期望的初始元素是 'Binary')。Found 'SayHello'.

環境與配置

// 自定義綁定構建
ByteStreamMessageEncodingBindingElement byteStream = new ByteStreamMessageEncodingBindingElement();
HttpTransportBindingElement transport = new HttpTransportBindingElement();
transport.AuthenticationScheme = System.Net.AuthenticationSchemes.Anonymous;
transport.HostNameComparisonMode = HostNameComparisonMode.StrongWildcard;
CustomBinding binding = new CustomBinding(byteStream, transport);

服務操作定義:

[ServiceContract]
public interface IWCFService {
    [OperationContract]
    void SayHello(byte[] b);
}

public class WCFService : IWCFService {
    public void SayHello(byte[] b) { /* ... */ }
}

根因分析

ByteStreamMessageEncoding 要求 SOAP 訊息 Body 的根節點必須為 <Binary>,預設 WCF 以操作名(此處為 SayHello)作為根節點,導致序列化不符合編碼器預期的 Schema。

解決方案:改用訊息契約與 BodyWriter

  1. 將服務契約改為訊息契約,操作簽名統一為 Message 型別:
[ServiceContract]
public interface IWCFService {
    [OperationContract(Action = "*", ReplyAction = "*")]
    Message UpLoad(Message request);
}
  1. 實現自定義 BodyWriter,在 OnWriteBodyContents 中顯式寫入 <Binary> 節點:
class ByteStreamBodyWriter : BodyWriter {
    private readonly string _filePath;
    public ByteStreamBodyWriter(string filePath) : base(false) { _filePath = filePath; }

    protected override void OnWriteBodyContents(XmlDictionaryWriter writer) {
        writer.WriteStartElement("Binary");
        // 寫入位元組流資料 ...
        writer.WriteEndElement();
    }
}
  1. 客戶端構造請求訊息時使用該 BodyWriter:
Message request = Message.CreateMessage(
    MessageVersion.Soap12WSAddressing10,
    "*",
    new ByteStreamBodyWriter(filePath)
);
proxy.UpLoad(request);

關鍵點總結

  • 嘗試將方法名改為 "Binary" 無效,因 SOAP 仍會附加額外後綴,難以精確控制根節點名稱。
  • ByteStreamMessageEncodingBindingElement 僅能搭配 CustomBinding 使用,且強制要求資料包裹在 <Binary> 節點下。
  • WCF 透過 BodyWriter 抽象類暴露訊息序列化管線,是控制 SOAP Body 結構的唯一正規途徑。

參考資源

《WCF 技術內幕》關於訊息序列化機制章節。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved