CoreWCF接收MTOM格式XOP:Include附件的实现难题
问题描述
我正在使用.NET 6和CoreWCF开发SOAP服务,需要接收供应商指定格式的SOAP消息,该消息包含元数据及通过MTOM发送的文件附件。
当我将请求类的属性设为字节数组时,可正常接收以下格式的文件:
<parent> <child> <attachment>cid:mycontentid</attachment> </child> </parent>
但供应商采用引用http://www.w3.org/2004/08/xop/include命名空间的<xop:Include>元素发送文件,格式如下:
<parent xmlns:xop="http://www.w3.org/2004/08/xop/include"> <child> <attachment> <xop:Include href="cid:mycontentid"/> </attachment> </child> </parent>
尝试接收该格式文件时,无论如何设置,对应属性始终为null。我当前的Attachment/Include类代码如下:
public class Attachment { //WSDL looks right, but deserializes to null //[XmlElement(ElementName = "Include", Namespace="http://www.w3.org/2004/08/xop/include")] //public Include Include { get; set; } //WSDL looks right, but deserializes to null //[XmlElement(ElementName = "Include", Namespace="http://www.w3.org/2004/08/xop/include")] //public byte[] Include { get; set; } //WSDL looks wrong, only accepts <attachment>cid:...<attachment> public byte[] Include { get; set; } } public class Include { [XmlAttribute(AttributeName="href", Namespace="http://www.w3.org/2004/08/xop/include")] public byte[] Href { get;set; } }
相关文档较少,我陷入困境,请问如何用CoreWCF(或原WCF,我可适配)实现该需求?
解决方案
1. 修正类结构与序列化属性
调整你的实体类,让序列化器正确识别XOP命名空间的Include元素,注意href是字符串类型(仅为附件的cid引用,不是字节数组):
using System.Xml.Serialization; public class Attachment { [XmlElement(ElementName = "Include", Namespace = "http://www.w3.org/2004/08/xop/include")] public XopInclude Include { get; set; } } public class XopInclude { [XmlAttribute(AttributeName = "href", Namespace = "http://www.w3.org/2004/08/xop/include")] public string Href { get; set; } }
2. 启用MTOM绑定配置
CoreWCF必须启用MTOM才能解析XOP格式的请求,在代码或配置文件中设置绑定:
var binding = new BasicHttpBinding(BasicHttpSecurityMode.None); binding.MessageEncoding = WSMessageEncoding.Mtom; // 根据业务需求调整大小限制 binding.MaxReceivedMessageSize = 10485760; // 10MB binding.ReaderQuotas.MaxArrayLength = 10485760;
3. 提取附件字节数组
如果需要直接获取附件的二进制内容,可在服务方法中通过OperationContext手动提取匹配的附件:
public void ProcessRequest(MyRequest request) { var requestMessage = OperationContext.Current.RequestContext.RequestMessage; foreach (var attachment in requestMessage.Attachments) { // 去除cid前缀,匹配附件ID var targetCid = request.Child.Attachment.Include.Href.Replace("cid:", ""); if (attachment.ContentId == targetCid) { using var stream = new MemoryStream(); attachment.ContentStream.CopyTo(stream); byte[] fileBytes = stream.ToArray(); // 处理文件内容 } } }
关键注意事项
- 不要将
href属性定义为byte[],它只是MTOM附件的标识字符串。 - 必须确保服务绑定启用MTOM,否则CoreWCF无法识别XOP格式的请求结构。
- 修正后的类结构会生成符合标准的WSDL,确保与供应商的请求契约匹配。
内容的提问来源于stack exchange,提问作者Chris Disley
相关产品推荐
相关产品推荐

