You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ASP.NET Core Web API中JSON转指定SOAP XML格式实现咨询

解决ASP.NET Core中JSON转特定SOAP XML的问题

嘿,作为刚接触Web API的新手,遇到这种JSON转固定格式SOAP XML的需求确实有点挠头,不过别担心,ASP.NET Core里有挺成熟且简便的方案,我来一步步给你拆解:


最推荐的方案:基于XML序列化的模型映射

因为目标SOAP XML的结构是固定的,先定义对应C#模型并添加XML序列化特性,是最易维护、出错最少的方式。

步骤1:定义接收JSON的模型

首先处理你收到的JSON请求,ASP.NET Core会自动将JSON绑定到这个模型:

public class BookRequestJson
{
    public string Credential { get; set; } // 格式:"用户名:密码"
    public int BookId { get; set; }
    public string BookName { get; set; }
    public string BookAuthor { get; set; }
    public decimal BookPrice { get; set; }
}

步骤2:定义SOAP XML对应的模型(带命名空间特性)

重点在这里,通过XmlRoot、XmlElement、XmlType等特性,直接指定每个元素的命名空间和别名映射,解决tns:前缀的问题:

// SOAP信封根节点
[XmlRoot(ElementName = "Envelope", Namespace = "http://schemas.xmlsoap.org/soap/envelope/")]
public class SoapEnvelope
{
    [XmlElement(ElementName = "Header", Namespace = "http://schemas.xmlsoap.org/soap/envelope/")]
    public SoapHeader Header { get; set; }

    [XmlElement(ElementName = "Body", Namespace = "http://schemas.xmlsoap.org/soap/envelope/")]
    public SoapBody Body { get; set; }
}

// SOAP头部
public class SoapHeader
{
    [XmlElement(ElementName = "Credential", Namespace = "http://kkr.eu/")]
    public CredentialPro Credential { get; set; }
}

// 凭证类型(对应xsi:type="tns:CredentialPro")
[XmlType(TypeName = "CredentialPro", Namespace = "http://kkr.eu/")]
public class CredentialPro
{
    [XmlElement(ElementName = "UserName", Namespace = "http://kkr.eu/")]
    public string UserName { get; set; }

    [XmlElement(ElementName = "Password", Namespace = "http://kkr.eu/")]
    public string Password { get; set; }

    [XmlElement(ElementName = "UserID", Namespace = "http://kkr.eu/")]
    public int UserID { get; set; } // 注意你给的XML里是固定值4,按需调整
}

// SOAP主体
public class SoapBody
{
    [XmlElement(ElementName = "AddBookDetails", Namespace = "http://kkr.eu/")]
    public AddBookDetails AddBookDetails { get; set; }
}

// 书籍详情(注意BookPrice对应XML里的<tns:Price>)
public class AddBookDetails
{
    [XmlElement(ElementName = "BookId", Namespace = "http://kkr.eu/")]
    public int BookId { get; set; }

    [XmlElement(ElementName = "BookName", Namespace = "http://kkr.eu/")]
    public string BookName { get; set; }

    [XmlElement(ElementName = "BookAuthor", Namespace = "http://kkr.eu/")]
    public string BookAuthor { get; set; }

    [XmlElement(ElementName = "Price", Namespace = "http://kkr.eu/")]
    public decimal Price { get; set; }
}

步骤3:JSON数据映射到SOAP模型并序列化

接下来把JSON模型的数据转成SOAP模型,再序列化为XML:

// 1. 拆分Credential为用户名和密码(ASP.NET Core已自动绑定JSON到bookRequest)
var credParts = bookRequest.Credential.Split(':');
var userName = credParts[0];
var password = credParts[1];

// 2. 构建SOAP模型
var soapEnvelope = new SoapEnvelope
{
    Header = new SoapHeader
    {
        Credential = new CredentialPro
        {
            UserName = userName,
            Password = password,
            UserID = 4 // 固定值,按需修改
        }
    },
    Body = new SoapBody
    {
        AddBookDetails = new AddBookDetails
        {
            BookId = bookRequest.BookId,
            BookName = bookRequest.BookName,
            BookAuthor = bookRequest.BookAuthor,
            Price = bookRequest.BookPrice
        }
    }
};

// 3. 序列化XML并指定命名空间前缀(tns、soap等)
var serializer = new XmlSerializer(typeof(SoapEnvelope));
var namespaces = new XmlSerializerNamespaces();
// 映射前缀和命名空间,和目标XML完全一致
namespaces.Add("soap", "http://schemas.xmlsoap.org/soap/envelope/");
namespaces.Add("tns", "http://kkr.eu/");
namespaces.Add("s", "http://www.w3.org/2001/XMLSchema");
namespaces.Add("xsi", "http://www.w3.org/2001/XMLSchema-instance");

using var stringWriter = new StringWriter();
serializer.Serialize(stringWriter, soapEnvelope, namespaces);
// 添加XML声明(可选,根据外部API要求)
var finalXml = $"<?xml version=\"1.0\" encoding=\"UTF-8\"?>{stringWriter.ToString()}";

关于命名空间和tns:前缀的疑问解答

你困惑的tns:这类前缀,本质是命名空间的别名:

  • tns是我们自定义的别名,对应真实命名空间http://kkr.eu/,通过XmlSerializerNamespaces.Add("tns", "...")完成映射
  • soap前缀对应SOAP标准信封的命名空间http://schemas.xmlsoap.org/soap/envelope/
  • 模型中每个XmlElement特性的Namespace属性,指定了该元素所属的真实命名空间,序列化时会自动用你设置的前缀显示

备选方案:手动构建XML(LINQ to XML)

如果不想定义模型,也可以用LINQ to XML直接拼接XML结构,适合简单场景:

var credParts = bookRequest.Credential.Split(':');
var xDoc = new XDocument(
    new XDeclaration("1.0", "UTF-8", null),
    new XElement(XName.Get("Envelope", "http://schemas.xmlsoap.org/soap/envelope/"),
        new XAttribute(XNamespace.Xmlns + "soap", "http://schemas.xmlsoap.org/soap/envelope/"),
        new XAttribute(XNamespace.Xmlns + "tns", "http://kkr.eu/"),
        new XAttribute(XNamespace.Xmlns + "s", "http://www.w3.org/2001/XMLSchema"),
        new XAttribute(XNamespace.Xmlns + "xsi", "http://www.w3.org/2001/XMLSchema-instance"),
        // 头部
        new XElement(XName.Get("Header", "http://schemas.xmlsoap.org/soap/envelope/"),
            new XElement(XName.Get("Credential", "http://kkr.eu/"),
                new XAttribute(XName.Get("type", "http://www.w3.org/2001/XMLSchema-instance"), "tns:CredentialPro"),
                new XElement(XName.Get("UserName", "http://kkr.eu/"), credParts[0]),
                new XElement(XName.Get("Password", "http://kkr.eu/"), credParts[1]),
                new XElement(XName.Get("UserID", "http://kkr.eu/"), 4)
            )
        ),
        // 主体
        new XElement(XName.Get("Body", "http://schemas.xmlsoap.org/soap/envelope/"),
            new XElement(XName.Get("AddBookDetails", "http://kkr.eu/"),
                new XElement(XName.Get("BookId", "http://kkr.eu/"), bookRequest.BookId),
                new XElement(XName.Get("BookName", "http://kkr.eu/"), bookRequest.BookName),
                new XElement(XName.Get("BookAuthor", "http://kkr.eu/"), bookRequest.BookAuthor),
                new XElement(XName.Get("Price", "http://kkr.eu/"), bookRequest.BookPrice)
            )
        )
    )
);
var finalXml = xDoc.ToString();

不过这种方式维护性较差,结构变更时需要修改大量代码,更推荐模型序列化的方式。


内容的提问来源于stack exchange,提问作者Sabi007

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 09:57:12