XML 请求元素被多个父元素包裹的序列化

XML serialization where request element is wrapped up with multiple parent elements

我有一个商家账户余额请求class如下:

[Serializable]
[XmlRoot(ElementName = "accountbalance", Namespace = "", IsNullable = false)]
public class MerchantAccountBalanceRequest
{
    [XmlElementAttribute("agent")]
    public string Agent { get; set; }
    [XmlElementAttribute("agentPin")]
    public string AgentPin { get; set; }
}

这将导致以下 XML:

<accountbalance>
    <agent>aaaaaa</agent>
    <agentPin>mmmmmm</agentPin>
</accountbalance>

我能否以某种方式在我的 class 上添加一个属性,以便对于 MerchantAccountBalanceRequest 对象我将得到以下 XML:

<Envelope>
<Body>
<accountbalance>
    <agent>aaaaaa</agent>
    <agentPin>mmmmmm</agentPin>
</accountbalance>
</Body>
</Envelope>

也就是说,只用 EnvelopeBody 元素将其包裹起来。

虽然您无法通过请求 class 中的属性实现此目的,但您可以将请求包装在其他 class 中,代表 EnvelopeBody 元素:

public class MerchantAccountBalanceRequest
{
    [XmlElement("agent")]
    public string Agent { get; set; }
    [XmlElement("agentPin")]
    public string AgentPin { get; set; }
}

public class RequestBody
{
    [XmlElement("accountbalance")]
    public MerchantAccountBalanceRequest BalanceRequest { get; set; }
}

[XmlRoot(ElementName = "Envelope")]
public class RequestEnvelope
{
    [XmlElement("Body")]
    public RequestBody Body { get; set; }
}

序列化和反序列化时,从 RequestEnvelope 而不是 MerchantAccountBalanceRequest 构造您的 XmlSerializer 对象。在构造它们时,您必须设置 RequestEnvelope.BodyRequestBody.BalanceRequest 属性(您可能会将 RequestEnvelope 中的 Body 属性 初始化为新的 RequestBody 构造函数中的实例,为方便起见)。

这看起来像是某些协议中的单一请求类型,因此如果您有多个请求类型,您可以为请求创建一个 base-class(例如 RequestBase),并调整RequestBody 以便它接受可能的请求元素的选择,如下例所示:

public abstract class RequestBase
{
}

public class SomeOtherRequest : RequestBase
{
    [XmlElementAttribute("example")]
    public string Example { get; set; }
}

public class MerchantAccountBalanceRequest : RequestBase
{
    [XmlElement("agent")]
    public string Agent { get; set; }
    [XmlElement("agentPin")]
    public string AgentPin { get; set; }
}

public class RequestBody
{
    [XmlElement(ElementName = "accountbalance", Type = typeof(MerchantAccountBalanceRequest))]
    [XmlElement(ElementName = "somethingelse", Type = typeof(SomeOtherRequest))]
    public RequestBase Request { get; set; }
}