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

C# .NET 5异步Web API使用XPath读取XML节点遍历异常求助

问题排查与解决方案

核心问题原因

  • XPath查询语法错误:XML中CATEGORYID的属性值为字符串类型"10",原代码中//ITEM[@CATEGORYID=10]直接和数字10做对比,XML解析器会因类型不匹配查询不到节点,需要给属性值包裹单引号。
  • 泛型集合类型不匹配:方法返回值声明为List<InsertClassDTO>,但实例化时写的是new List<AnnuncioAutoDTO>(),若二者无继承关系,代码直接编译失败,无法进入执行阶段。
  • 异步场景不符合需求:原代码全为同步写法,会阻塞Web API响应返回,无法实现先返回"ok"再处理业务的逻辑。

修复后代码示例

XML读取逻辑(适配异步场景)

public class LetturaXml
{
    public async Task<List<InsertClassDTO>> XmlToListAsync(InputDTO input)
    {
        List<InsertClassDTO> list = new List<InsertClassDTO>();
        // 用XDocument代替XmlDocument,API更友好且原生支持异步加载
        XDocument doc = await XDocument.LoadAsync(
            File.OpenRead(input.filePath), 
            LoadOptions.None, 
            CancellationToken.None);
        
        // 修复XPath语法,给属性值加单引号
        var nodeList = doc.XPathSelectElements("//ITEM[@CATEGORYID='10']");

        foreach (var item in nodeList)
        {
            // 读取节点属性示例
            var itemId = item.Attribute("ID")?.Value;
            // 读取普通子节点示例
            var title = item.Element("TITLE")?.Value;
            // 读取属性列表中的指定值示例
            var prezzo = item.Descendants("ATTRIBUTE")
                .FirstOrDefault(a => a.Element("ATTRID")?.Value == "prezzo")?
                .Element("ATTRVAL")?.Value;

            // 映射到DTO加入列表
            list.Add(new InsertClassDTO
            {
                Id = itemId,
                Title = title,
                Prezzo = decimal.TryParse(prezzo, out var p) ? p : 0,
                // 其他字段按需求赋值
            });
        }

        // 后续批量插库建议用EF Core的AddRange+SaveChangesAsync,减少数据库交互次数
        return list;
    }
}

Web API层先返回响应的实现

[ApiController]
[Route("api/[controller]")]
public class XmlProcessController : ControllerBase
{
    private readonly LetturaXml _letturaXml;
    private readonly ILogger<XmlProcessController> _logger;

    public XmlProcessController(LetturaXml letturaXml, ILogger<XmlProcessController> logger)
    {
        _letturaXml = letturaXml;
        _logger = logger;
    }

    [HttpPost]
    public IActionResult ProcessXml([FromBody] InputDTO input)
    {
        // 先做基础参数校验
        if (!System.IO.File.Exists(input.filePath))
        {
            return BadRequest("目标XML文件不存在");
        }

        // 后台启动任务处理XML和插库逻辑,不阻塞响应返回
        _ = Task.Run(async () =>
        {
            try
            {
                await _letturaXml.XmlToListAsync(input);
            }
            catch (Exception ex)
            {
                // 必须添加异常日志,避免后台任务出错无感知
                _logger.LogError(ex, "XML解析入库流程执行失败");
            }
        });

        return Ok("ok");
    }
}

生产环境注意事项

如果业务对任务执行可靠性要求高,后台长期运行的任务更推荐用IHostedService或者专业的任务调度组件,避免应用池回收导致未完成的任务中断。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 11:39:05