我有一个基于Angular 6的Dnn SPA模块,该模块可以调用Dnn服务框架。所有这些功能对于属于管理员角色的用户来说都是完美的,但是当用户仅使用“所有用户”或“注册用户”角色登录时,我们会在Chrome Dev Console中出现以下错误:
错误TypeError:无法读取未定义的属性“ length” 在http.js:108 在Array.forEach() 在HttpHeaders.lazyInit(http.js:102) 在HttpHeaders.push ../ node_modules/@angular/common/fesm5/http.js.HttpHeaders.init中 (http.js:166) 在HttpHeaders.push ../ node_modules/@angular/common/fesm5/http.js.HttpHeaders.forEach中 (http.js:235) 在Observable._subscribe(http.js:1435) 在Observable.push ../ node_modules / rxjs / _esm5 / internal / Observable.js.Observable._trySubscribe中 (ReplaySubject.js:83) 在Observable.push ../ node_modules / rxjs / _esm5 / internal / Observable.js.Observable.subscribe (ReplaySubject.js:69) 在tryCatch.js:17 在subscriptionToResult(index.js:1)
我认为,也许由于某些原因我们的拦截器未添加HTTPHeaders,但是在“网络”选项卡上,我们都没有进行任何调用。
尝试解决问题:
检查Angular是否启动
我的Angular应用程序中有一个应用程序初始化程序,因此我向它添加了控制台日志,该日志已被触发:
export function appInitializer(configurationService: ConfigurationService) {
configurationService.configuration.antiforgeryToken = dnnService.framework.getAntiForgeryValue();
configurationService.apiPath = dnnService.framework.getServiceRoot(dnnService.path);
configurationService.configuration.moduleId = dnnService.moduleId;
configurationService.configuration.tabId = dnnService.tabId;
configurationService.configuration.tabModuleId = dnnService.tabModuleId;
console.log('configuration for app initializer: ', configurationService);
return () => true;
}
检查防伪令牌
应该添加的一个HTTPHeader是防伪令牌
dnnService.framework.getAntiForgeryValue()
由于某些原因,该值对于“注册用户”为空,对于管理员用户具有正确的值。但是,如果甚至没有拨打电话,那么我不确定这可能是问题的原因。
为WebApi调用添加了其他日志记录
我发现一个可疑的日志条目,但无法将其链接到问题:
[WARN] DotNetNuke.Entities.Tabs.TabController-无效的tabId -1 门户网站0
更改了所有WebApi控制器的访问级别
我将所有DnnModuleAuthorisation更改为以下内容:
[DnnModuleAuthorize(AccessLevel = SecurityAccessLevel.Anonymous)]
我也尝试过
[DnnModuleAuthorize(AccessLevel = SecurityAccessLevel.View)]
没有什么不同。
检查是否首次触发对HTTP WebApi端点的呼叫
在ngDoBootstrap中,我进行了第一个HTTP调用,使事情停止运行,因此这使我相信Angular实际上存在问题:
ngDoBootstrap(app) {
console.log('about to get settings');
this.settingsService.getSettings().subscribe((settings: Settings) => {
console.log('fired call to get settings'); //<- Never gets here
});
}
getSettings()。subscribe中的console.log永远不会触发!
关于其他检查内容的任何提示或指导都将非常有用。
答案 0 :(得分:1)
也许您需要手动添加jQuery库。在管理模式下,这些由框架自动添加。这就是为什么那里没有错误的原因。
using DotNetNuke.Framework;
using DotNetNuke.Common;
//7.2 and lower
if (Globals.DataBaseVersion.Major < 7 || (Globals.DataBaseVersion.Major == 7 && Globals.DataBaseVersion.Minor < 2))
{
jQuery.RequestDnnPluginsRegistration();
}
else
{
//7.3 and higher
JavaScriptLibraries.JavaScript.RequestRegistration(JavaScriptLibraries.CommonJs.DnnPlugins);
}
答案 1 :(得分:1)
原来是RequestVerificationToken。由于某种原因,Dnn只为管理员输出令牌,或者在我已删除的外观(?)中存在搜索框时输出。
此问题的解决方法是添加搜索并使用样式将其隐藏。例如。
<div id="search-top" style="display:none !important">
<dnn:SEARCH ID="dnnSearch2" runat="server" ShowSite="false" ShowWeb="false" EnableTheming="true" Submit="Search" CssClass="SearchButton" />
</div>
我已经对非管理员用户进行了测试,并且可以正常工作。
有关更多信息,请参见相关的Dnn 9 bug posted on DnnTracker:
答案 2 :(得分:0)
查看此page。您可以将防伪令牌加载到模板中,然后在服务中检索它。自从我与DNN合作以来已经有一段时间了,但是我记得遇到了同样的问题,并且有一个简单的解决方法。
编辑:我能够伸手找到我为此编写的代码。这是我在纯SPA模块(仅HTML / JS)中检索API的方式:
[JavaScript:{ jsname: "AngularJs" }]
[JavaScript:{ path: "~/DesktopModules/module/dist/app.build.js"}]
<div id="root"
data-module-id="[ModuleContext:ModuleId]"
data-is-superuser="[ModuleContext:IsSuperUser]"
data-anti-forgery-token="[AntiForgeryToken:true]"
ng-cloak="true"
ng-switch="{{'[ModuleContext:IsSuperUser]'.toLowerCase()}}">
<!-- non-admins -->
<div ng-switch-when="false">
<app></app>
</div>
<!-- admins -->
<div ng-switch-when="true">
<div class="panel panel-info">
<div class="panel-heading">
<h3 class="panel-title" ng-bind="::'App'"></h3>
</div>
</div>
</div>
</div>
<script>
angular.element(function () {
angular.bootstrap(document.getElementById('root'), ['App']);
});
</script>