65.9K
CodeProject 正在变化。 阅读更多。
Home

Angular 单页应用程序 - 酷的权限控制系统

starIconstarIconstarIconstarIconstarIcon

5.00/5 (11投票s)

2016年3月29日

Ms-PL

3分钟阅读

viewsIcon

26135

downloadIcon

167

Angular 单页应用, MEF, 权限控制, WCF Restful 服务, ui-router,

酷炫的权限控制系统 第 1 部分 -- asp.net MVC

酷炫的权限控制系统 第 2 部分 -- asp.net MVC 使用 WCF

引言

如之前的文章所述,我介绍了酷炫的权限控制,它是一个单点登录项目。它支持基于 WCF restful 服务的多种 UI 层。在之前的文章中,我通过 asp.net MVC 实现了 UI 层。在这篇文章中,我将展示如何使用 angular 来实现酷炫的权限控制作为 UI 层。如果您想回顾我的上一篇文章,请参阅我的上一篇文章。此外,我想花一些时间感谢那些投票为 5 并提出问题的人。

背景

为了增加学习兴趣并区分之前的文章。我更喜欢设计单页应用程序。为了完成此任务,我使用 Angular 来实现 UI 层,因为 Angular 支持大量功能,它不仅提供双向绑定,还提供页面路由。毫无疑问,您可以使用 jQuery、Knockout 或其他 JavaScript 代替。关于服务器端服务,我使用 WCF restful 方法来实现目的。

外观

图 Angular 酷炫的权限控制系统

设计模式

首先,我想描述如何从客户端脚本调用 WCF restful 方法。

调用单参数 WCF 服务

以名为 GetSystemInfo 的服务接口为例。
[OperationContract]
//Customized attribute for logging and initialization
[CoolWCFBehavior]
[WebInvoke(Method = "POST", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
SystemInfoVM GetSystemInfo(WCFAuthInfoVM entity_WCFAuthInfoVM);
    

在之前的代码片段中,我将 WebInvoke 或 WebGet 属性应用于服务,以便可以使用 ajax get 或 post 方法从客户端使用该方法。有关详细信息,请访问 msdn 链接 (https://msdn.microsoft.com/en-us/library/bb412172(v=vs.100).aspx)。

public string GetMultiLingualResSer(string str_LangKey)
{
    LanguageKey languageKey_Input = LanguageKey.en;

    Enum.TryParse<LanguageKey>(str_LangKey, out languageKey_Input);

    IDictionary<string, string> dic_AllKey = LangPack.GetAllByLangKey(LangPack.GetLanugage(languageKey_Input));

    JavaScriptSerializer jsonSerializer = new JavaScriptSerializer();

    return jsonSerializer.Serialize(dic_AllKey);
}

在上面的代码片段中,我完成了接口的具体内容。此函数将返回所有语言资源作为 JSON 字符串。

///<reference path="../Scripts/angular.js" />
///<reference path="../Scripts/angular-route.js" />
(function () {
    'use strict';
    var injectParams = ['$http'];
    var SystemInfoRestfulSer = function ($http) {
        this.GetMultiLingualResSer = function (str_LangKey) {
            var request = $http({
                method: 'GET',
                headers: {
                    'Content-Type': 'application/json; charset=utf-8'
                },
                url: WCFPath + 'SystemMgtService.svc/GetMultiLingualResSer/' + (str_LangKey != "" ? str_LangKey : "en"),
                data: {}
            });
            return request;
        };
    
    //.........
    //.........
    
    SystemInfoRestfulSer.$inject = injectParams;
    angular.module('WCFClient').service('SystemInfoRestfulSer', SystemInfoRestfulSer);
})();
    

创建先前的 angular 服务以调用 WCF 服务并接收异步承诺。 关于 $http 方法,请参阅 angular api https://docs.angularjs.org/api/ng/service/$http

以下代码片段演示了如何调用 angular 服务的方法。同时,我使用 ui-route 在单页应用程序上呈现嵌套视图功能。

$stateProvider.state('CPCS', {
    url: '/',
    resolve: {
        Setup: ['$q', '$state', '$location', '$cookies', 'StaticContentModel', 'SystemInfoVM', 'WCFAuthInfoVM', 'SystemInfoRestfulSer', '$sessionStorage', function ($q, $state, $location, $cookies, StaticContentModel, SystemInfoVM, WCFAuthInfoVM, SystemInfoRestfulSer, $sessionStorage) {
            var promise_Global = $q.defer();
            //Get Languar Pack
            var promise_GetLanguagePack = new function () {
                var deferred_GetLanguagePack = $q.defer();
                SystemInfoRestfulSer.GetMultiLingualResSer(defaultLangKey).then(function (response) {
                        var multiLignualRes = angular.fromJson(response.data);
                        if (multiLignualRes != null && multiLignualRes != undefined) {
                            $sessionStorage.MultiLingualRes = multiLignualRes;
                            $sessionStorage.SelectedLang = defaultLangKey;
                        }
                        deferred_GetLanguagePack.resolve();
                    });
                    return deferred_GetLanguagePack.promise;
            };
            //Get System Info
            var promise_GetSysInfo = new function () {
                //......
            };
            //Wait serice response and navigate to login page
            $q.all([promise_GetLanguagePack, promise_GetSysInfo]).then(function () {
                promise_Global.resolve();
                $state.go('LoginModule.Login');
            });
        }]
    },
    controller: 'GlobalController'
})

调用多参数 WCF 服务

以名为 Login 的服务接口为例。
[OperationContract]
//Customized attribute for logging and initialization
[CoolWCFBehavior]
[WebInvoke(Method = "POST", BodyStyle = WebMessageBodyStyle.WrappedRequest, RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json, UriTemplate = "login")]
LUSerLoginResult Login(LoginUserVM entityInst, string str_Language, string str_IpAdd, string str_HostName);
    

在之前的代码片段中,我添加了属性“BodyStyle = WebMessageBodyStyle.WrappedRequest”来包装请求。请求和响应将是
请求

{"entityInst":{ID:"",LoginName:"",LoginPwd:"",...},"str_Language":"","str_IpAdd":"","str_HostName":""}

响应

{"Str_ServerToken":"XXXXXXXXXXX","IsPWDExpire":false,"Entity_SessionWUserInfo":{LoginName:"","Status":1,"UserType":1,....}}

以下代码片段演示了 angular 服务和调用者。
Angular 服务 (Login)

this.Login = function (LoginUserJson) {
    var request = $http({
        method: 'POST',
        headers: {
        'Content-Type': 'application/json; charset=utf-8'
        },
        url: WCFPath + 'LoginUserMgtService.svc/login',
        data: LoginUserJson
    });
    
    return request;
};

调用者

//Login Method
$scope.DoLogin = function () {
    $scope.IsEnable_DoLogin = false;
    var model = {
        'entityInst': $scope.LoginUserModel,
        'str_Language': $scope.LangPacks.SelectedKey.Key,
        'str_IpAdd': "",
        'str_HostName': ""
    };
    var loginRequest = LoginUserMgtSer.Login(model);
    loginRequest.then(function (response) {
        var loginResult = new LUSerLoginResult(response.data);
        //Success
        if (!loginResult.HasError()) {
            var SessionInfo = {
                'WCFToken': loginResult.Str_ServerToken,
                'UserId': loginResult.Entity_SessionWUserInfo.ID
            };
            var clientSession = new ClientSessionMgt();
            var request_SetUserInfo = clientSession.SetUserInfo(SessionInfo);
            if (loginResult.PwdExpire()) {
                //Reset Password
                $state.go("LoginModule.Reset");
            }
            else {
                //Navigate to Index Page
                $state.go('Main.Home.IndexPart1');
            }
            $scope.IsEnable_DoLogin = true;
        }
        //Error
        else {
            $scope.IsEnable_DoLogin = true;
            throw new ExcetionInst(ExceptionType.ValidationError, $location.path(), $sessionStorage.MultiLingualRes.LoginScreenTitle, loginResult.GetErrMsgs());
        }
    });
};

 

其次,使用 AngularJS MVC 设计模式来设计项目。

图 3.1 AngularJS MVC 设计模式

如之前的图表所述,用户访问该站点,控制器 选择合适的 视图 来执行请求并调用 Angular 服务或 Factory 的方法以获取数据,另一方面,Angular 服务或 Factory 通过 $http 请求调用 WCF restful 服务。Angular 服务或 Factory 向调用者响应 json。控制器 构造 模型 并使用双向绑定将 模型 与视图连接。

以功能类型管理为例。功能类型管理包含三个视图。

  1. 列表功能类型 (FTManage.tpl.html)
  2. 编辑功能类型 (FTManage.Edit.tpl.html)
  3. 创建功能类型 (FTManage.Create.tpl.html)

对应的路由将是

  1. /FTManage
  2. /FTManage/Edit
  3. /FTManage/Create
图 3.2 功能类型管理配置

 

功能类型管理包含“创建 / 删除 / 编辑 / 搜索 / 分页 / 排序”方法。

图 3.3 功能类型管理控制器

下图说明了功能类型客户端服务

图 3.4 功能类型服务

下面的代码显示了服务的详细信息。

.....
        this.Create = function (json_Data) {
            var request = $http({
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json; charset=utf-8'
                },
                url: WCFPath + 'FunTypeMgtService.svc/Create',
                data: json_Data
            });
            return request;
        };
        this.Delete = function (json_Data) {
            var request = $http({
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json; charset=utf-8'
                },
                url: WCFPath + 'FunTypeMgtService.svc/Delete',
                data: json_Data
            });
            return request;
        };
        this.Update = function (json_Data) {
            var request = $http({
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json; charset=utf-8'
                },
                url: WCFPath + 'FunTypeMgtService.svc/Update',
                data: json_Data
            });
            return request;
        };
.....
    

设置

我列出我的开发环境供您参考。

  1. AngularJS v1.5.0
  2. Microsoft Visual Studio 2013
  3. .NET Framework 4.5.1
  4. MYSQL 5.6.26
  5. Entity Framework 6.0

4.1 编辑 WEB.CONFIG 文件

4.1.1 对于 MYSQL 用户

图 4.1.1.1 托管服务 web.config(MySql 与 WCF 版本)

最后

关于用 angular 编写的酷炫权限控制的源代码,我将在完成 MSSQL 版本和全面测试后将其上传到 GIT。

此外,酷炫的权限控制基于许多有趣的设计模式。例如 angular、MEF、Entity Framework、jQuery 和 Bootstrap(UI)。很抱歉,我无法在短时间内向您介绍所有这些设计模式。感谢您的阅读。

历史

2016-03-28 初次发布

2016-03-29 修复下载链接。

© . All rights reserved.