.NET Framework与.NET Core XML Schema编译差异及关联Schema加载咨询
解决ASP.NET Core中XML Schema关联文件未加载的问题
我之前也碰到过一模一样的情况——在.NET Framework桌面应用里运行正常的XML验证代码,移到ASP.NET Core控制器里就因为关联Schema没加载报错。核心原因是ASP.NET Core中XmlSchemaSet的默认行为和.NET Framework不同,出于安全考量它不会自动解析xs:include引用的外部Schema文件,下面给你两种可行的解决办法:
方法1:手动添加所有依赖的Schema文件
既然自动加载失效,咱们直接把关联的enums.xsd也添加到XmlSchemaSet中,确保所有需要的Schema都被加载:
// 注意:务必通过IWebHostEnvironment获取正确的物理路径,避免相对路径问题 private readonly IWebHostEnvironment _env; public YourController(IWebHostEnvironment env) { _env = env; } // 验证方法内的代码 string baseXsdPath = Path.Combine(_env.ContentRootPath, "Schemas", "base.xsd"); string enumXsdPath = Path.Combine(_env.ContentRootPath, "Schemas", "enums.xsd"); XDocument doc = XDocument.Load(xmlPath); XmlSchemaSet schemas = new XmlSchemaSet(); // 同时添加主Schema和关联的枚举Schema schemas.Add("http://some.domain.org", baseXsdPath); schemas.Add("http://some.domain.org", enumXsdPath); schemas.Compile(); bool isValid = true; doc.Validate(schemas, (o, e) => { res.AddMessage(MessageSeverities.Error, $"{e.Severity}:{e.Message}"); isValid = false; }); if (isValid) { res.AddMessage(MessageSeverities.Notice, $"{formFile.FileName} is valid!"); }
方法2:配置XmlResolver自动解析依赖文件
如果你不想手动维护所有依赖的Schema列表,可以通过配置XmlReaderSettings启用XmlUrlResolver,让它自动识别并加载xs:include引用的文件:
// 同样需要注入IWebHostEnvironment获取路径 private readonly IWebHostEnvironment _env; public YourController(IWebHostEnvironment env) { _env = env; } // 验证方法内的代码 string baseXsdPath = Path.Combine(_env.ContentRootPath, "Schemas", "base.xsd"); XDocument doc = XDocument.Load(xmlPath); XmlSchemaSet schemas = new XmlSchemaSet(); // 创建配置,允许解析外部Schema资源 XmlReaderSettings readerSettings = new XmlReaderSettings(); readerSettings.XmlResolver = new XmlUrlResolver(); // 若不需要DTD处理可忽略此行,根据实际场景调整 readerSettings.DtdProcessing = DtdProcessing.Parse; // 使用配置好的XmlReader加载主Schema using (XmlReader reader = XmlReader.Create(baseXsdPath, readerSettings)) { schemas.Add("http://some.domain.org", reader); } schemas.Compile(); // 后续验证逻辑与原代码一致 bool isValid = true; doc.Validate(schemas, (o, e) => { res.AddMessage(MessageSeverities.Error, $"{e.Severity}:{e.Message}"); isValid = false; }); if (isValid) { res.AddMessage(MessageSeverities.Notice, $"{formFile.FileName} is valid!"); }
重要提醒:路径正确性
在ASP.NET Core中绝对不要直接使用相对路径引用文件,因为运行时的工作目录可能和开发环境不一致。一定要通过注入IWebHostEnvironment获取项目根目录(ContentRootPath)或wwwroot目录(WebRootPath),再拼接Schema文件的相对路径。
内容的提问来源于stack exchange,提问作者tschmit
相关产品推荐
相关产品推荐

