I recently got a question from a customer on how one can add custom headers to NETCF app. There is a lot of documentation on how to do this using OperationContextScope and IDispatchMessageInspector on the desktop side, but neither is supported on CF 3.5 itself.
The trick on NETCF is to use the Message class, and the Message.Headers.Add() method to add new custom headers to the outgoing message.
Below is an outline of the steps that you could use in conjunction with NetcfSvcUtil.exe that generates a proxy to talk to the service.
public override void WriteObject(System.Xml.XmlDictionaryWriter writer, object graph) { if (this.info.IsWrapped) { this.serializer.Serialize(writer, graph); } else { this.WriteObjectContent(writer, graph); } } public override void WriteObjectContent(System.Xml.XmlDictionaryWriter writer, object graph) { System.IO.MemoryStream ms = new System.IO.MemoryStream(); System.Xml.XmlWriterSettings settings = new System.Xml.XmlWriterSettings(); settings.OmitXmlDeclaration = true; System.Xml.XmlWriter innerWriter = System.Xml.XmlDictionaryWriter.Create(ms, settings); this.serializer.Serialize(innerWriter, graph); innerWriter.Close(); ms.Position = 0; System.Xml.XmlReader innerReader = System.Xml.XmlDictionaryReader.Create(ms); innerReader.Read(); writer.WriteAttributes(innerReader, false); if ((innerReader.IsEmptyElement == false)) { innerReader.Read(); for ( ; ((innerReader.NodeType == System.Xml.XmlNodeType.EndElement) == false); ) { writer.WriteNode(innerReader, false); } } innerReader.Close(); }
public override void WriteObject(System.Xml.XmlDictionaryWriter writer, object graph) { if (this.info.IsWrapped) { this.serializer.Serialize(writer, graph); } else { this.WriteObjectContent(writer, graph); } }
public override void WriteObjectContent(System.Xml.XmlDictionaryWriter writer, object graph) { System.IO.MemoryStream ms = new System.IO.MemoryStream(); System.Xml.XmlWriterSettings settings = new System.Xml.XmlWriterSettings(); settings.OmitXmlDeclaration = true; System.Xml.XmlWriter innerWriter = System.Xml.XmlDictionaryWriter.Create(ms, settings); this.serializer.Serialize(innerWriter, graph); innerWriter.Close(); ms.Position = 0; System.Xml.XmlReader innerReader = System.Xml.XmlDictionaryReader.Create(ms); innerReader.Read(); writer.WriteAttributes(innerReader, false); if ((innerReader.IsEmptyElement == false)) { innerReader.Read(); for ( ; ((innerReader.NodeType == System.Xml.XmlNodeType.EndElement) == false); ) { writer.WriteNode(innerReader, false); } } innerReader.Close(); }
protected TRESPONSE Invoke<TREQUEST, TRESPONSE>(CFInvokeInfo info, TREQUEST request) { … CFContractSerializerInfo customHeaderSerializerInfo = new CFContractSerializerInfo(); customHeaderSerializerInfo .MessageContractType = typeof( string ); customHeaderSerializerInfo .IsWrapped = info.RequestIsWrapped; customHeaderSerializerInfo .ExtraTypes = info.ExtraTypes; customHeaderSerializerInfo .UseEncoded = info.UseEncoded; msg.Headers.Add( System.ServiceModel.Channels.MessageHeader.CreateHeader( "myHeader", "http://tempuri.org", "myData", this.GetContractSerializer( customHeaderSerializerInfo ) ) ); return this.getResult<TRESPONSE>(this.getReply(msg), info); }
protected TRESPONSE Invoke<TREQUEST, TRESPONSE>(CFInvokeInfo info, TREQUEST request)
{ …
CFContractSerializerInfo customHeaderSerializerInfo = new CFContractSerializerInfo(); customHeaderSerializerInfo .MessageContractType = typeof( string ); customHeaderSerializerInfo .IsWrapped = info.RequestIsWrapped; customHeaderSerializerInfo .ExtraTypes = info.ExtraTypes; customHeaderSerializerInfo .UseEncoded = info.UseEncoded; msg.Headers.Add( System.ServiceModel.Channels.MessageHeader.CreateHeader( "myHeader", "http://tempuri.org", "myData", this.GetContractSerializer( customHeaderSerializerInfo ) ) );
return this.getResult<TRESPONSE>(this.getReply(msg), info);
}