使用Angular2及WebApi开发SPA类型的企业应用 - Part 6- RESTful 和 WebApi
来源:互联网 发布:怎么把淘宝开通手机 编辑:程序博客网 时间:2024/06/08 02:43
使用Angular2及RESTful WebApi开发SPA类型的企业应用 - Part 6 RESTful 和 WebApi
作者:techcoaching,翻译:飘落寒冰
原文 有道
注:第一次翻译文章,有错译之处还请多多包涵,欢迎指出以便改进。
在本文中,我们将简单介绍本项目如何使用RESTful/WebApi
从Github上下载源码
该系列的全部文章
- 概览
- 添加新角色
- 项目结构
- 多语言
- 依赖注入和控制反转-为什么和为什么不?
- RESTful & WebApi
- 应用生命周期管理
- 应用构建与部署
简介
本项目中,我们是用angular2(typescript)处理客户端逻辑和请求服务器端处理业务逻辑(C#)。
客户端和服务器通过WebApi(RESTful的Web Servic)来通信
客户端请求
在组件中,我们调用了相关的服务
@Component({ selector: "roles", templateUrl: "app/modules/security/permission/permissions.html", directives: [Grid, PageActions, Page]})export class Permissions extends BasePage { private router: Router; public model: PermissionsModel; constructor(router: Router) { super(); let self: Permissions = this; self.router = router; self.model = new PermissionsModel(self.i18nHelper); self.loadPermissions(); this.model.addPageAction(new PageAction("btnAddPer", "security.permissions.addPermissionAction", () => self.onAddNewPermissionClicked())); } private loadPermissions() { let self: Permissions = this; permissionService.getPermissions().then(function (items: Array<any>) { self.model.importPermissions(items); }); }}
permissionService实际上是通过IConnector(IConnect是angular中调用Http的接口)向服务器发送请求。
import configHelper from "../../../../common/helpers/configHelper";import {Promise} from "../../../../common/models/promise";import {IoCNames} from "../../../../common/enum";import {IConnector} from "../../../../common/connectors/iconnector";let permissionService = { getPermissions: getPermissions};export default permissionService;function getPermissions(): Promise { let connector: IConnector = window.ioc.resolve(IoCNames.IConnector); let url = String.format("{0}permissions", configHelper.getAppConfig().api.baseUrl); return connector.get(url);}
IConnector中,我们用了Http服务
export class RESTConnector implements IConnector { private static http: Http; private static eventManager: EventManager; constructor() { let http: Http = window.appState.getInjector().get(Http); this.setHttp(http); } public get(url: string): Promise { RESTConnector.eventManager.publish(LoadingIndicatorEvent.Show); let def = PromiseFactory.create(); let headers = new JsonHeaders(); RESTConnector.http.get(url, { headers: headers }) .map((response: any) => response.json()) .subscribe( (data: any) => this.handleResponse(def, data), (exception: any) => this.handleException(def, exception) ); return def; }}
服务器端API
我们通过PermissionsController接收请求
namespace App.Api.Features.Security{ [RoutePrefix("api/permissions")] public class PermissionsController : ApiController { [HttpGet] [Route()] public IResponseData<IList<PermissionAsKeyNamePair>> GetPermissions() { IResponseData<IList<PermissionAsKeyNamePair>> response = new ResponseData<IList<PermissionAsKeyNamePair>>(); try { IPermissionService permissionService = IoC.Container.Resolve<IPermissionService>(); IList<PermissionAsKeyNamePair> pers = permissionService.GetPermissions(); response.SetData(pers); } catch (ValidationException ex) { response.SetErrors(ex.Errors); response.SetStatus(System.Net.HttpStatusCode.PreconditionFailed); } return response; } }}
如果我们需要在请求时向server端传递参数,这些参数必须是DTO对。
RESTful规定了每种操作使用特定的Http Verb (Get, Create, Update, Delete) 和请求路径。我们不介绍这些内容。
我只想澄清一些不同之处:
我们定义了两种累行errors/excetion,分别用来返回:基础错误和业务错误
- Infrastructure Error
用来处理网络错误(找不到路径,超时,…), IIS配置错误configuration on IIS。这意味着业务逻辑部分尚未执行。
- Business Error
用来处理客户端传递到服务器端用来处理业务逻辑的数据有错误。
例如:用户的用户名和密码不匹配。这种情况下,我们不能用通过HttpCode 500传递,客户端不明白服务器端发生了什么事情。
所有我们需要把此错误返回给客户端
IResponseData<IList<PermissionAsKeyNamePair>> response = new ResponseData<IList<PermissionAsKeyNamePair>>();try{}catch (ValidationException ex){ response.SetErrors(ex.Errors); response.SetStatus(System.Net.HttpStatusCode.PreconditionFailed);}return response;
REST工具的输出:
我们可以发现,API返回了多个校验错误,我们可以在UI中将他们展示出来。这种方式比返回一个通用错误要更友好。
在相应的service中,我们校验的了请求中的参数,如果校验失败,我们将抛出如下异常:
private void ValidateUserLoginRequest(UserSignInRequest request){ ValidationException exception = new ValidationException(); if (request == null) { exception.Add(new ValidationError("common.invalidRequest")); } if (String.IsNullOrWhiteSpace(request.Email)) { exception.Add(new ValidationError("registration.signin.validation.emailRequired")); } if (String.IsNullOrWhiteSpace(request.Pwd)) { exception.Add(new ValidationError("registration.signin.validation.pwdRequired")); } IUserRepository userRepository = IoC.Container.Resolve<IUserRepository>(); User userProfile = userRepository.GetByEmail(request.Email); if (userProfile == null || EncodeHelper.EncodePassword(request.Pwd) != userProfile.Password) { exception.Add(new ValidationError("registration.signin.validation.invalidEmailOrPwd")); } exception.ThrowIfError();}
总结
本例中,API成功返回了处理结果(HttpCode 200),但是收到的确是业务逻辑错误。
一些朋友认为这可能令人困惑。如果您有更好的解决方案,我很高兴与各位一起探讨。
授权
本文,以及所包含的源码,文件遵循CPOL协议
- 使用Angular2及WebApi开发SPA类型的企业应用 - Part 6- RESTful 和 WebApi
- 使用Angular2及WebApi开发SPA类型的企业应用
- 使用Angular2及WebApi开发SPA类型的企业应用
- 使用Angular2及WebApi开发SPA类型的企业应用 - Part 2- 添加新角色
- 使用Angular2及WebApi开发SPA类型的企业应用 - Part 3 项目结构
- 使用Angular2及WebApi开发SPA类型的企业应用 - Part 4- 多语言
- 使用Angular2及WebApi开发SPA类型的企业应用 - Part 5- 依赖注入和控制反转
- 使用Angular2与WebApi开发SPA类型的企业应用 - Part 1- 概览
- Asp.net WebAPi Restful 的实现和跨域
- webapi的使用
- webapi的使用
- C# webAPI的使用
- WebApi使用
- WebAPI
- webApi
- webapi
- WebAPi
- webAPI
- Phoenix安装小结
- 2017年超星慕课西方文化概论尔雅答案
- CentOS7安装mongodb
- LeetCode笔记:347. Top K Frequent Elements
- pandas库简介(1)--pandas的三种数据结构
- 使用Angular2及WebApi开发SPA类型的企业应用 - Part 6- RESTful 和 WebApi
- Linux上安装paramiko模块以及easy_install的安装方法
- 接口型设计模式(Interface patterns)之adapter(适配器)
- RAC 性能分析 - 'log file sync' 等待事件
- 网络状态代码数字的含义
- LeetCode: Ones and Zeroes
- Apache select和Nginx epoll模型区别
- poj 3258 二分 River Hopscotch
- CentOS6.3 重启后/etc/resolv.conf 被还原解决办法