.net Web API自动反序列化xml传参为C#实体

Program.cs

.net 8.0已经内置了XML解析器,所以直接在services.AddControllers()后调用AddXmlSerializerFormatters()即可:

services.AddControllers().AddXmlSerializerFormatters();

定义实体

需要用到几个特性:

  1. XmlRoot:xml的根节点
  2. XmlElement:xml的成员
    例:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:i="http://i.api.ei.nxyincfuyou.iih/">
<soapenv:Header/>
<soapenv:Body>
<i:apiEntry>
<i:arg0>SI0084</i:arg0>
<i:arg1>
<![CDATA[
<iihparam>
<Code_user>00000</Code_user>
<Code_dep></Code_dep>
<Code_external>IIH</Code_external>
<Data>
<Code_dep></Code_dep>
<Code_nur>00034</Code_nur>
<Sd_status>25</Sd_status>
<Date_b_in></Date_b_in>
<Date_e_in></Date_e_in>
<Date_b_out></Date_b_out>
<Date_e_out></Date_e_out>
<Date_b_update></Date_b_update>
<Date_e_update></Date_e_update>
<Pageinfos>
<Pageinfo>
<Pagesize>200</Pagesize>
<Pageindex>1</Pageindex>
<Pagecount></Pagecount>
<Recordscount></Recordscount>
</Pageinfo>
</Pageinfos>
</Data>
</iihparam>
]]>
</i:arg1>
</i:apiEntry>
</soapenv:Body>
</soapenv:Envelope>
// 根元素
[XmlRoot(ElementName = "Envelope", Namespace = "http://schemas.xmlsoap.org/soap/envelope/")]
public class H5_InpatientDataXML
{
[XmlElement(ElementName = "Header", Namespace = "http://schemas.xmlsoap.org/soap/envelope/")]
public Header Header { get; set; }
[XmlElement(ElementName = "Body", Namespace = "http://schemas.xmlsoap.org/soap/envelope/")]
public Body Body { get; set; }
}
public class Header
{
// 你可以添加更多的头信息属性,如果需要的话
}
public class Body
{
[XmlElement(ElementName = "apiEntry", Namespace = "http://i.api.ei.nxyincfuyou.iih/")]
public ApiEntry ApiEntry { get; set; }
}
public class ApiEntry
{
[XmlElement(ElementName = "arg0", Namespace = "http://i.api.ei.nxyincfuyou.iih/")]
public string Arg0 { get; set; }
[XmlElement(ElementName = "arg1", Namespace = "http://i.api.ei.nxyincfuyou.iih/")]
public CData<IihParam> Arg1 { get; set; }
}
// Arg1中的嵌套 XML
[XmlRoot(ElementName = "iihparam")]
public class IihParam
{
[XmlElement(ElementName = "Code_user")]
public string CodeUser { get; set; }
[XmlElement(ElementName = "Code_dep")]
public string CodeDep { get; set; }
[XmlElement(ElementName = "Code_external")]
public string CodeExternal { get; set; }
[XmlElement(ElementName = "Data")]
public Data Data { get; set; }
}
public class Data
{
[XmlElement(ElementName = "Code_dep")]
public string CodeDep { get; set; }
[XmlElement(ElementName = "Code_nur")]
public string CodeNur { get; set; }
[XmlElement(ElementName = "Sd_status")]
public string SdStatus { get; set; }
[XmlElement(ElementName = "Date_b_in")]
public string DateBIn { get; set; }
[XmlElement(ElementName = "Date_e_in")]
public string DateEIn { get; set; }
[XmlElement(ElementName = "Date_b_out")]
public string DateBOut { get; set; }
[XmlElement(ElementName = "Date_e_out")]
public string DateEOut { get; set; }
[XmlElement(ElementName = "Date_b_update")]
public string DateBUpdate { get; set; }
[XmlElement(ElementName = "Date_e_update")]
public string DateEUpdate { get; set; }
[XmlElement(ElementName = "Pageinfos")]
public PageInfos PageInfos { get; set; }
}
public class PageInfos
{
[XmlElement(ElementName = "Pageinfo")]
public List<PageInfo> PageInfoList { get; set; }
}
public class PageInfo
{
[XmlElement(ElementName = "Pagesize")]
public string PageSize { get; set; }
[XmlElement(ElementName = "Pageindex")]
public string PageIndex { get; set; }
[XmlElement(ElementName = "Pagecount")]
public string PageCount { get; set; }
[XmlElement(ElementName = "Recordscount")]
public string RecordsCount { get; set; }
}

这里注意,CDATA区域需要自定义序列化方式以便框架调用,CDATA类:

public class CData<T> : IXmlSerializable where T : class
{
public T Value { get; set; }
public XmlSchema GetSchema() => null;
public void ReadXml(XmlReader reader)
{
if (reader.IsEmptyElement)
{
reader.Read();
Value = null;
}
else
{
string content = reader.ReadElementContentAsString();
if (!string.IsNullOrEmpty(content))
{
var serializer = new XmlSerializer(typeof(T));
using (var stringReader = new StringReader(content))
{
Value = (T)serializer.Deserialize(stringReader);
}
}
}
}
public void WriteXml(XmlWriter writer)
{
if (Value != null)
{
var serializer = new XmlSerializer(typeof(T));
using (var stringWriter = new StringWriter())
{
serializer.Serialize(stringWriter, Value);
writer.WriteCData(stringWriter.ToString());
}
}
}
public static implicit operator CData<T>(T value)
{
return new CData<T> { Value = value };
}
public static implicit operator T(CData<T> cdata)
{
return cdata?.Value;
}
}

另外注意数据类型一般都是string,之前对于PageCount使用了int,测试时发现会报错。

Controller使用

/// <summary>
/// 获取患者的xml格式数据
/// </summary>
/// <param name="xmlData"></param>
/// <returns></returns>
[HttpPost]
[Route("TestXML")]
public async Task<IActionResult> TestXML([FromBody] H5_InpatientDataXML envelope)
{
return Ok(envelope);
}
posted @   南山有榛  阅读(17)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
点击右上角即可分享
微信分享提示