在Orchard Core重写规则中如何获取YesSQL ISession?
解决Orchard Core自定义IRule中ISession为null的问题
问题原因
自定义IRule的执行上下文通常不在标准HTTP请求范围内,而IOrchardHelper的默认实现依赖请求上下文提供的ISession,导致调用GetContentItemByAliasAsync时无法获取有效会话,触发NullReferenceException。
解决方案
绕过IOrchardHelper,直接通过IContentManager和ISessionFactory手动创建会话来查询内容项:
- 注入必要服务
在自定义IRule的构造函数中注入IContentManager和ISessionFactory:
private readonly IContentManager _contentManager; private readonly ISessionFactory _sessionFactory; public YourCustomRule(IContentManager contentManager, ISessionFactory sessionFactory) { _contentManager = contentManager; _sessionFactory = sessionFactory; }
- 手动创建会话并查询
使用ISessionFactory创建临时会话,通过AliasIndex查询别名对应的内容项ID,再通过IContentManager获取内容项:
using var session = _sessionFactory.CreateSession(); // 查询别名对应的索引记录 var aliasIndex = session.Query<AliasIndex>() .Where(x => x.Alias == "redirects-list") .FirstOrDefault(); if (aliasIndex == null) { // 处理别名不存在的情况 return null; } // 获取发布状态的内容项 var listCi = await _contentManager.GetAsync( aliasIndex.ContentItemId, VersionOptions.Published, session: session );
注意事项
ISessionFactory是单例生命周期,可安全注入到单例的IRule中;创建的会话在using块结束后会自动释放。- 若仅需查询已发布内容,使用
VersionOptions.Published避免查询草稿版本,提升性能。
内容的提问来源于stack exchange,提问作者David
相关产品推荐
相关产品推荐

