使用SoapCore时如何让WSDL包含返回类型的自定义命名空间?
在ASP.NET Core服务中使用SoapCore库提供SOAP端点时,期望返回类型的消息体带有特定命名空间,但生成的WSDL始终缺失XML契约中定义的命名空间。
当前代码配置如下:
Program.cs中的SOAP端点定义
(app as IApplicationBuilder).UseSoapEndpoint(typeof(IDummyService), (opt) => { opt.Path = "/DummyService.svc"; opt.Binding = new BasicHttpBinding(); opt.SoapSerializer = SoapSerializer.XmlSerializer; });
服务契约定义
[ServiceContract(Namespace = "DummyServiceNamespace")] public interface IDummyService { [OperationContract] DummyDataResponse GetDummyData(); }
数据类型定义
[XmlType("DummyDataResponse")] [XmlRoot("DummyDataResponse")] public class DummyDataResponse { [XmlElement(Form = XmlSchemaForm.Qualified, Namespace = "http://www.ech.ch/xmlns/eCH-0020-f/3", Order = 0)] public DeliveryType Delivery { get; set; } } [Serializable] [XmlType("deliveryType", Namespace="http://www.ech.ch/xmlns/eCH-0020-f/3")] public class DeliveryType { [XmlAttribute(AttributeName = "Test")] public string Test { get; set; } }
当前生成的WSDL中,DeliveryType被归入服务的命名空间下,期望它能拥有独立的schema,目标命名空间为http://www.ech.ch/xmlns/eCH-0020-f/3,示例如下:
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" targetNamespace="http://www.ech.ch/xmlns/eCH-0020-f/3" version="3.0" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:ech20="http://www.ech.ch/xmlns/eCH-0020-f/3"> <xsd:complexType name="deliveryType"> <xsd:attribute name="Test" type="xsd:string"/> </xsd:complexType> </schema>
请问这种需求是否可以实现?
可以实现,需要调整类型的XML序列化配置并修改SoapCore的端点设置,具体操作如下:
完善数据类型的命名空间声明
给DummyDataResponse显式指定目标命名空间,确保根类型与嵌套类型的命名空间配置统一:[XmlType("DummyDataResponse", Namespace = "http://www.ech.ch/xmlns/eCH-0020-f/3")] [XmlRoot("DummyDataResponse", Namespace = "http://www.ech.ch/xmlns/eCH-0020-f/3")] public class DummyDataResponse { [XmlElement(Form = XmlSchemaForm.Qualified, Namespace = "http://www.ech.ch/xmlns/eCH-0020-f/3", Order = 0)] public DeliveryType Delivery { get; set; } }配置SoapEndpoint的序列化命名空间
在端点配置中添加XmlSerializerNamespaces,显式注册目标命名空间的前缀,让SoapCore生成WSDL时识别并分离独立schema:var xmlNamespaces = new XmlSerializerNamespaces(); xmlNamespaces.Add("ech20", "http://www.ech.ch/xmlns/eCH-0020-f/3"); (app as IApplicationBuilder).UseSoapEndpoint(typeof(IDummyService), (opt) => { opt.Path = "/DummyService.svc"; opt.Binding = new BasicHttpBinding(); opt.SoapSerializer = SoapSerializer.XmlSerializer; opt.XmlSerializerNamespaces = xmlNamespaces; });验证结果
启动服务后访问/DummyService.svc?wsdl,此时DeliveryType会被归入http://www.ech.ch/xmlns/eCH-0020-f/3命名空间的独立schema块中,与预期结构一致。
关键注意点:SoapCore使用XmlSerializer模式时,命名空间的分离依赖于类型上XmlType/XmlRoot属性的Namespace参数,必须确保所有需要独立命名空间的类型都显式指定该值,同时通过XmlSerializerNamespaces注册前缀,才能触发WSDL生成对应的独立schema。
内容的提问来源于stack exchange,提问作者Daniel

