C# 向MessageContract WCF响应对象(MessageBodyMember)添加多个名称空间
我们的WCF设置包含以下合同:C# 向MessageContract WCF响应对象(MessageBodyMember)添加多个名称空间,c#,xml,wcf,serialization,messagecontract,C#,Xml,Wcf,Serialization,Messagecontract,我们的WCF设置包含以下合同: [ServiceContract( Namespace = Constants.Namespaces.HL7Namespace, Name = Constants.Roles.ContentRequiredDocumentManagementSystem)] // XmlSerializerFormat is needed to expose the HL7 schema fields without the "Field" suffix
[ServiceContract(
Namespace = Constants.Namespaces.HL7Namespace,
Name = Constants.Roles.ContentRequiredDocumentManagementSystem)]
// XmlSerializerFormat is needed to expose the HL7 schema fields without the "Field" suffix on each one, eg: idField
[XmlSerializerFormat]
public interface ICDARequest
{
[OperationContract(
// wsdl request action
Action = Constants.Namespaces.HL7Namespace + ":" + Constants.Interactions.RCMR_IN000029UV01 + "." + Constants.VersionType.NormativeCode + Constants.Version.InteractionVersion,
// wsdl operation name
Name = Constants.Interactions.RCMR_IN000029UV01,
// wsdl response action
ReplyAction = Constants.Namespaces.HL7Namespace + ":" + Constants.Interactions.RCMR_IN000030UV01 + "." + Constants.VersionType.NormativeCode + Constants.Version.InteractionVersion)]
SearchMessagesResponse SearchMessages(SearchMessagesRequest RCMR_IN000029UV01);
[MessageContract(
IsWrapped = false]
public class SearchMessagesResponse
{
[MessageBodyMember(
Name = State.Constants.Interactions.RCMR_IN000030UV01,
Namespace = State.Constants.Namespaces.HL7Namespace)]
public RCMR_IN000030UV01 data;
}
}
- 这些类基于使用
基于HL7v3架构生成的类李>xsd.exe
- 然后,我们修改了模式,添加了一个自定义元素,使用自定义名称空间对其进行区分,并重新生成了类
- 这很有效
[System.Xml.Serialization.XmlTypeAttribute(TypeName = "BCCDX.DistributionStatus", Namespace = "urn:bccdx.ca")]
public partial class BCCDXDistributionStatus
{
[System.Xml.Serialization.XmlElementAttribute("receivedTime", Namespace = "urn:bccdx.ca", IsNullable = false)]
public TS receivedTime{...}
}
这正是我们想要的
然后在WCF服务中,我们可以使用新类和成员:
var distStatus = new BCCDXDistributionStatus();
distStatus.receivedTime = CreateTS(locStat.MessageDownloadDate);
然后,它被序列化并通过网络发送出去,如下所示:
<distributionStatus xmlns="urn:bccdx.ca">
<receivedTime value="201702150956-0800"/>
</distributionStatus>
<RCMR_IN000030UV01 ITSVersion="XML_1.0" xmlns="urn:hl7-org:v3">
...
</RCMR_IN000030UV01>
当真正需要的是:
<RCMR_IN000030UV01 ITSVersion="XML_1.0" xmlns="urn:hl7-org:v3" xmlns:x="urn:bccdx.ca">
...
</RCMR_IN000030UV01>
...
注意带有前缀的urn:bccdx.ca
我想知道,如果可以的话,我们如何通过契约向产生的序列化消息XML添加多个名称空间,并带有前缀?我已经在web上看到了重写默认序列化程序的提示,但我不希望这样。这肯定是以前考虑过并处理过的吗?首先,我将假设,在您的服务合同中的某个地方,您正在指定使用
XmlSerializer
,例如:
[ServiceContract()]
[XmlSerializerFormat]
public interface IService1
{
[OperationContract(
// wsdl request action
Action = Constants.Namespaces.HL7Namespace + ":" + Constants.Interactions.RCMR_IN000029UV01 + "." + Constants.VersionType.NormativeCode + Constants.Version.InteractionVersion,
// wsdl operation name
Name = Constants.Interactions.RCMR_IN000029UV01,
// wsdl response action
ReplyAction = Constants.Namespaces.HL7Namespace + ":" + Constants.Interactions.RCMR_IN000030UV01 + "." + Constants.VersionType.NormativeCode + Constants.Version.InteractionVersion)]
SearchMessagesResponse SearchMessages(/* SearchMessagesRequest RCMR_IN000029UV01*/);
}
虽然您的问题中没有提到这一点,但如果您没有这样做,则类型中的[System.Xml.Serialization.xmlementAttribute(…)]
属性声明将无效,因为它们被DataContractSerializer
忽略
其次,我将假设您的RCMR_IN000030UV01
类型当前看起来像这样:
[XmlRoot(ElementName = "RCMR_IN000030UV01", Namespace = "urn:hl7-org:v3")]
public partial class RCMR_IN000030UV01
{
// The initially auto-generated code
[XmlAttribute(AttributeName = "ITSVersion")]
public string ITSVersion { get; set; }
}
public partial class RCMR_IN000030UV01
{
// The added property
[System.Xml.Serialization.XmlElementAttribute("distributionStatus", Namespace = "urn:bccdx.ca", IsNullable = false)]
public BCCDXDistributionStatus distStatus { get; set; }
}
[System.Xml.Serialization.XmlTypeAttribute(TypeName = "BCCDX.DistributionStatus", Namespace = "urn:bccdx.ca")]
public partial class BCCDXDistributionStatus
{
[System.Xml.Serialization.XmlElementAttribute("receivedTime", Namespace = "urn:bccdx.ca", IsNullable = false)]
public TS receivedTime { get; set; }
}
public class TS
{
[XmlAttribute("value")]
public DateTime Value { get; set; }
}
<RCMR_IN000030UV01 ITSVersion="1.0"
xmlns="urn:hl7-org:v3"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<distributionStatus
xmlns="urn:bccdx.ca">
<receivedTime value="2017-02-23T00:00:00-05:00"/>
</distributionStatus>
</RCMR_IN000030UV01>
当前,您的服务返回的XML如下所示:
[XmlRoot(ElementName = "RCMR_IN000030UV01", Namespace = "urn:hl7-org:v3")]
public partial class RCMR_IN000030UV01
{
// The initially auto-generated code
[XmlAttribute(AttributeName = "ITSVersion")]
public string ITSVersion { get; set; }
}
public partial class RCMR_IN000030UV01
{
// The added property
[System.Xml.Serialization.XmlElementAttribute("distributionStatus", Namespace = "urn:bccdx.ca", IsNullable = false)]
public BCCDXDistributionStatus distStatus { get; set; }
}
[System.Xml.Serialization.XmlTypeAttribute(TypeName = "BCCDX.DistributionStatus", Namespace = "urn:bccdx.ca")]
public partial class BCCDXDistributionStatus
{
[System.Xml.Serialization.XmlElementAttribute("receivedTime", Namespace = "urn:bccdx.ca", IsNullable = false)]
public TS receivedTime { get; set; }
}
public class TS
{
[XmlAttribute("value")]
public DateTime Value { get; set; }
}
<RCMR_IN000030UV01 ITSVersion="1.0"
xmlns="urn:hl7-org:v3"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<distributionStatus
xmlns="urn:bccdx.ca">
<receivedTime value="2017-02-23T00:00:00-05:00"/>
</distributionStatus>
</RCMR_IN000030UV01>
如中所述,此属性
指定目标属性、参数、返回值或类成员包含与XML文档中使用的名称空间关联的前缀
现在,您的服务应该根据需要返回根元素上带有名称空间的XML。1)是否有任何方法可以将其扩展到一个或至少可以编译的对象,而不丢失类型?2) 您说您使用了
xsd.exe
来生成类,您是否在某处应用了[XmlSerializerFormat]
?我没有在问题中看到它。谢谢,是的,我编辑了将XmlSerializerFormat
添加到原始问题中。这是一个很好的答案,所有的假设都是完全正确的(我编辑了原始问题以包含XmlSerializerFormat
声明)。我添加了建议的[xmlnamespacesdeclarations]
属性,它成功了。我同意XML在这两种情况下都是正确的,但规范的一部分就是这样。