調試 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。
Message 型別:[ServiceContract]
public interface IWCFService {
[OperationContract(Action = "*", ReplyAction = "*")]
Message UpLoad(Message request);
}
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();
}
}
Message request = Message.CreateMessage(
MessageVersion.Soap12WSAddressing10,
"*",
new ByteStreamBodyWriter(filePath)
);
proxy.UpLoad(request);
ByteStreamMessageEncodingBindingElement 僅能搭配 CustomBinding 使用,且強制要求資料包裹在 <Binary> 節點下。BodyWriter 抽象類暴露訊息序列化管線,是控制 SOAP Body 結構的唯一正規途徑。《WCF 技術內幕》關於訊息序列化機制章節。