.NET Core 6 Web API中XML命名空间反序列化问题咨询
.NET Core 6 Web API XML反序列化问题解决
问题场景
我在.NET Core 6 Web API中尝试反序列化如下XML报文(注意末尾的
xmlns=""):
<message xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" user="xxx" password="yyy" type="zzz" from="aaa" xmlns=""> <HeaderInfo> <Vendor>vendor</Vendor> <MessageID>1078</MessageID> <Action>new</Action> <SiteName>site</SiteName> </HeaderInfo> </message>
我的Program.cs配置如下:
var builder = WebApplication.CreateBuilder(args); // Add services to the container. builder.Services.AddControllers(); builder.Services .AddControllers() .AddXmlSerializerFormatters(); // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle builder.Services.AddEndpointsApiExplorer(); builder.Services.AddSwaggerGen();
对应的实体类定义如下:
[XmlRoot(ElementName = "message", Namespace = "http://www.w3.org/2001/XMLSchema-instance")] public class XmlDto { [XmlAttribute("user")] public string? User { get; set; } [XmlAttribute("password")] public string? Password { get; set; } [XmlAttribute("type")] public string? Type { get; set; } [XmlAttribute("from")] public string? From { get; set; } [XmlElement(ElementName = "HeaderInfo")] public HeaderInfo HeaderInfo { get; set; } [XmlElement(ElementName = "Header")] public Header Header { get; set; } [XmlElement(DataType = "string")] public string? Body { get; set; } }
目前发送报文时收到“An error occurred while deserializing input data.”错误,请问如何实现成功反序列化?另外,由于发送端不会使用这两个命名空间,我是否需要在意它们的存在?
问题原因与解决步骤
1. 修正实体类命名空间匹配
XML报文中message元素的默认命名空间是空(xmlns=""),但你给XmlRoot指定的是http://www.w3.org/2001/XMLSchema-instance,这会导致反序列化时元素匹配失败,直接报错。
修改XmlRoot的命名空间为空字符串:
[XmlRoot(ElementName = "message", Namespace = "")] public class XmlDto { // 其他属性保持不变 }
同时确保HeaderInfo类无需额外命名空间(它属于默认空命名空间):
public class HeaderInfo { public string Vendor { get; set; } public int MessageID { get; set; } public string Action { get; set; } public string SiteName { get; set; } }
2. 处理可选属性的空值
如果报文中可能缺少Header或Body元素,需将这些属性设为可空类型,避免因找不到元素抛出异常:
[XmlElement(ElementName = "Header")] public Header? Header { get; set; } // 改为可空引用类型 [XmlElement(DataType = "string")] public string? Body { get; set; } // 已为可空,保持即可
3. 关于未使用的命名空间
报文中的xmlns:xsi和xmlns:xsd是XML标准的命名空间声明,发送端仅声明未使用,无需专门处理。.NET的XmlSerializer会自动忽略未被使用的命名空间声明,不影响反序列化。
4. 确保XML报文格式完整
你提供的XML报文缺少闭合标签</HeaderInfo>和</message>,实际发送时必须保证XML格式合法,否则也会触发反序列化错误。
验证效果
修改后的实体类配合原有的AddXmlSerializerFormatters()配置,即可正常反序列化目标XML报文。
内容的提问来源于stack exchange,提问作者Tom
相关产品推荐
相关产品推荐

