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

含DOCTYPE的cXML无法通过C#接口提交,求解决方案

解决带DOCTYPE声明的cXML在Asp.Net Core中反序列化时的400错误

问题背景

通过VS的「粘贴特殊内容->XML转类」功能基于Coupa测试文件生成了cXML的C#实体类,结构无问题。但在Swagger提交包含<!DOCTYPE>声明的XML请求时,接口返回400错误,提示「xml字段是必填项」;移除DOCTYPE声明后请求正常。

需求限制:无法预先剔除DOCTYPE声明,且需要保留完整XML内容存入本地文件;由于DOCTYPE与cXML根元素为同级关系,无法通过添加DocType对象解决。

问题原因

Asp.Net Core默认的XML模型绑定器无法将包含DOCTYPE的完整XML文档映射到XElement参数——XElement仅代表XML元素节点,不包含DOCTYPE这类文档级元数据,导致绑定失败,触发必填字段验证错误。

解决方案

放弃直接使用XElement作为请求参数,改为接收原始字符串或请求流,完整获取包含DOCTYPE的XML内容,再手动解析为cXML实体类,同时保存完整XML到本地。

修改后的代码示例

方式1:接收原始字符串

[HttpPost(Name = "PostPurchaseOrder")]
public ContentResult Post([FromBody] string xmlContent)
{
    // 保存完整XML到本地文件
    System.IO.File.WriteAllText(@"C:\your\storage\path\cxml_request.xml", xmlContent);

    cXML cxml = new cXML();
    var serializer = new XmlSerializer(typeof(cXML));
    // 配置XmlReader允许解析DTD,避免DOCTYPE被忽略
    var readerSettings = new XmlReaderSettings { DtdProcessing = DtdProcessing.Parse };
    
    using (var stringReader = new StringReader(xmlContent))
    using (var xmlReader = XmlReader.Create(stringReader, readerSettings))
    {
        cxml = (cXML)serializer.Deserialize(xmlReader);
    }

    // 执行后续业务逻辑
    return Content("请求处理完成");
}

方式2:直接读取请求流

如果担心字符串处理的性能问题,可直接读取请求体流:

[HttpPost(Name = "PostPurchaseOrder")]
public async Task<ContentResult> Post()
{
    // 读取完整请求体内容
    using var streamReader = new StreamReader(Request.Body);
    var xmlContent = await streamReader.ReadToEndAsync();

    // 保存完整XML到本地文件
    System.IO.File.WriteAllText(@"C:\your\storage\path\cxml_request.xml", xmlContent);

    cXML cxml = new cXML();
    var serializer = new XmlSerializer(typeof(cXML));
    var readerSettings = new XmlReaderSettings { DtdProcessing = DtdProcessing.Parse };
    
    using (var stringReader = new StringReader(xmlContent))
    using (var xmlReader = XmlReader.Create(stringReader, readerSettings))
    {
        cxml = (cXML)serializer.Deserialize(xmlReader);
    }

    // 执行后续业务逻辑
    return Content("请求处理完成");
}

关键注意事项

  • 必须设置XmlReaderSettings.DtdProcessing = DtdProcessing.Parse,否则XmlReader会默认忽略或拒绝处理DOCTYPE声明,导致解析异常。
  • 保存文件时注意路径权限,确保应用程序有写入目标目录的权限。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 14:40:24