Angular复选框单击和$ resource导致SecurityException:操作不安全

时间:2016-08-24 14:35:26

标签: javascript angularjs asp.net-web-api dynamics-crm

我想将angular.js与对Microsoft Dynamics CRM webapi端点的调用结合起来。

网页显示项目列表作为复选框。选中未选中的复选框应执行关联。取消勾选复选框后,请执行解除关联。

您将在下面的代码中看到关联确实有效,但解除关联不起作用。我无法设置一个plunker,因为代码与Microsoft Dynamics CRM应用程序绑定。

首先,HTML部分

<!DOCTYPE html>

<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="utf-8" />
    <title></title>
    <script src="../../ClientGlobalContext.js.aspx"></script>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.0-rc.4/angular.min.js"></script>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.0-rc.4/angular-resource.min.js"></script>
    <script src="https://code.jquery.com/jquery-2.2.4.min.js"></script>
    <!-- Latest compiled and minified CSS -->
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
    <!-- Optional theme -->
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css" integrity="sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp" crossorigin="anonymous">
    <!-- Latest compiled and minified JavaScript -->
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
    <script src="crmwebapimodule.js"></script>
    <script src="manyrelationshipapp.js"></script>
</head>
<body ng-app="crmApp">
    <div ng-controller="AppController" class="col-sm-7 col-md-2">
        <div ng-repeat="match in matches">
            <input type="checkbox" id="{{match.recordId}}" ng-model="match.checked" ng-click="doAction(match.recordId, match.checked)" />
            <span for="{{match.recordId}}">{{match.label}}</span>
        </div>
    </div>
</body>
</html>

然后是我的CRM模块

// create a module with a dependency on ngResource
var angularMscrm = angular.module('ManyRelationshipAngularMscrm', ['ngResource']);

// define the CrmService factory
angularMscrm.factory('CrmWebApiService', function ($resource) {
    var oDataUrl = Xrm.Page.context.getClientUrl() + '/api/data/v8.1/';

    var defaultParams = {};

    // describe our API actions
    var actions = {
        GetActiveItems: {
            isArray: false,
            method: 'GET',
            url: oDataUrl + ':entitySet?$select=:primaryField',//&$filter=statecode eq 0',
            headers: {
                'Content-Type': 'application/json',
                'Accept': 'application/json',
                'OData-MaxVersion': '4.0',
                'OData-Version': '4.0'
            }
        },
        GetSelectedItems: {
            isArray: false,
            method: 'GET',
            url: oDataUrl + ':entitySet(:primaryEntityId)?$select=:primaryField&$expand=:entityRelationName($select=:secondaryPrimaryField)',
            headers: {
                'Content-Type': 'application/json',
                'Accept': 'application/json',
                'OData-MaxVersion': '4.0',
                'OData-Version': '4.0'
            }
        },
        Associate: {
            method: 'POST',
            url: oDataUrl + ':primaryEntitySet(:entityId)/:entityRelationName/$ref',
            headers: {
                'Accept': 'application/json',
                'OData-MaxVersion': '4.0',
                'OData-Version': '4.0'
            }
        },
        Disassociate: {
            method: 'DELETE ',
            url: oDataUrl + ':primaryEntitySet(:primaryEntityId)/:entityRelationName(:secondaryEntityId)/$ref',
            headers: {
                'Accept': 'application/json',
                'OData-MaxVersion': '4.0',
                'OData-Version': '4.0'
            }
        }
    };

    // create the service
    return $resource(oDataUrl, defaultParams, actions);
});

最后,控制器本身

/// <reference path="CrmWebApiModule.js" />
(function () {
    // create a module for our Angular app with a dependency on our angularMscrm module
    var CrmApp = angular.module('crmApp', ['ManyRelationshipAngularMscrm']);

    // create a controller for the page, and inject our CrmService into it
    CrmApp.controller('AppController', function ($scope, CrmWebApiService) {
        // Data for test purpose
        var params =
        {
            recordId: '{32A33A4B-99A4-E511-80C0-00155D0A061D}',
            primaryEntitySet: 'opportunities',
            primaryIdAttr: 'opportunityid',
            primaryField: 'name',
            secondaryEntitySet: 'competitors',
            secondaryIdAttr: 'competitorid',
            secondaryPrimaryField: 'name',
            entityRelationSet: 'opportunitycompetitors_association'
        };

        if (params.recordId.length == 38) {
            params.recordId = params.recordId.substr(1, 36);
        }

        $scope.matches = new Array();

        $scope.doAction = function (id, value) {
            if (value === true) { 
                CrmWebApiService.Associate({
                    primaryEntitySet: params.primaryEntitySet,
                    entityId: params.recordId,
                    entityRelationName: params.entityRelationSet
                },
                {
                    "@odata.id": Xrm.Page.context.getClientUrl() + '/API/data/v8.1/' + params.secondaryEntitySet + '('+ id +')'
                }, function(response) {
                     alert(httpResponse);
                });
            } else {
                CrmWebApiService.Disassociate({
                    primaryEntitySet: params.primaryEntitySet,
                    primaryEntityId: params.recordId,
                    entityRelationName: params.entityRelationSet,
                    secondaryEntityId: id
                }, function (response) {

                },
                function(httpResponse) {
                    alert(httpResponse);
                });
            }

        }

        CrmWebApiService.GetActiveItems({
            entitySet: params.secondaryEntitySet,
            primaryField: params.secondaryPrimaryField
        },
            function (response) {
                var data = response.value;

                for (var i = 0; i < data.length; i++) {
                    $scope.matches.push({
                        recordId: data[i][params.secondaryIdAttr].toLowerCase(),
                        label: data[i][params.secondaryPrimaryField],
                        checked: false
                    });
                }
            });

        CrmWebApiService.GetSelectedItems({
            entitySet: params.primaryEntitySet,
            primaryEntityId: params.recordId,
            primaryField: params.primaryField,
            entityRelationName: params.entityRelationSet,
            secondaryPrimaryField: params.secondaryPrimaryField
        },
            function (response) {
                var data = response[params.entityRelationSet];

                for (var i = 0; i < $scope.matches.length; i++) {
                    for (var j = 0; j < data.length; j++) {
                        if ($scope.matches[i].recordId === data[j][params.secondaryIdAttr]) {
                            $scope.matches[i].checked = true;
                            break;
                        }
                    }
                }
            });
    });
}());

Soo,该关联按预期工作,但解除关联会导致以下错误:

Error: The operation is insecure.
hf/<@https://ajax.googleapis.com/ajax/libs/angularjs/1.3.0-rc.4/angular.min.js:84:6
s@https://ajax.googleapis.com/ajax/libs/angularjs/1.3.0-rc.4/angular.min.js:80:22
m/f<@https://ajax.googleapis.com/ajax/libs/angularjs/1.3.0-rc.4/angular.min.js:77:308
f/<@https://ajax.googleapis.com/ajax/libs/angularjs/1.3.0-rc.4/angular.min.js:107:349
Ge/this.$get</k.prototype.$eval@https://ajax.googleapis.com/ajax/libs/angularjs/1.3.0-rc.4/angular.min.js:121:189
Ge/this.$get</k.prototype.$digest@https://ajax.googleapis.com/ajax/libs/angularjs/1.3.0-rc.4/angular.min.js:118:296
Ge/this.$get</k.prototype.$apply@https://ajax.googleapis.com/ajax/libs/angularjs/1.3.0-rc.4/angular.min.js:121:458
tc[c]</<.compile/</<@https://ajax.googleapis.com/ajax/libs/angularjs/1.3.0-rc.4/angular.min.js:220:167
$e/c@https://ajax.googleapis.com/ajax/libs/angularjs/1.3.0-rc.4/angular.min.js:32:253
e/<()angular.min.js (ligne 99)
ye/this.$get</<(a=Object { type="object"}, c=undefined)angular.min.js (ligne 74)
f/<()angular.min.js (ligne 107)
Ge/this.$get</k.prototype.$eval(a=Object { type="object"}, b=undefined)angular.min.js (ligne 121)
Ge/this.$get</k.prototype.$digest()angular.min.js (ligne 118)
Ge/this.$get</k.prototype.$apply(a=Object { type="object"})angular.min.js (ligne 121)
tc[c]</<.compile/</<(d=Object { type="object"})angular.min.js (ligne 220)
$e/c(c=Object { type="object"}, e=undefined)angular.min.js (ligne 32)

我只是不知道什么是不安全的以及如何解决这个问题......

我看到的唯一区别是关联与HTTP POST一起使用并与HTTP DELETE取消关联,但它不会导致我解决问题。

感谢您的帮助

0 个答案:

没有答案