本文介绍“ 为ASP.NET Web API生成TypeScript客户端API ”,重点介绍Angular 2+代码示例和各自的SDLC。如果您正在开发.NET Core Web API后端,则可能需要阅读为ASP.NET Core Web API生成C#Client API。
背景
自WebApiClientGen
Angular 2仍然在RC2时,自2016年6月v1.9.0-beta 以来,对Angular2的支持已经可用。并且在WebApiClientGen
v2.0中提供了对Angular 2产品发布的支持。希望NG2的发展不会如此频繁地破坏我的CodeGen和我的Web前端应用程序。:)
在2016年9月底发布Angular 2的第一个产品发布几周后,我碰巧启动了一个使用Angular2的主要Web应用程序项目,因此我WebApiClientGen
对NG2应用程序开发的使用方法几乎相同。
推定
- 您正在开发ASP.NET Web API 2.x应用程序,并将基于Angular 2+为SPA开发TypeScript库。
- 您和其他开发人员喜欢在服务器端和客户端都通过强类型数据和函数进行高度抽象。
- Web API和实体框架代码优先使用POCO类,您可能不希望将所有数据类和成员发布到客户端程序源码。
并且可选地,如果您或您的团队支持基于Trunk的开发,那么更好,因为使用的设计WebApiClientGen
和工作流程WebApiClientGen
假设基于Trunk的开发,这比其他分支策略(如Feature Branching和GitFlow等)更有效。对于熟练掌握TDD的团队。
为了跟进这种开发客户端程序的新方法,最好有一个ASP.NET Web API项目。您可以使用现有项目,也可以创建演示项目。
使用代码
本文重点介绍Angular 2+的代码示例。假设您有一个ASP.NET Web API项目和一个Angular2项目作为VS解决方案中的兄弟项目。如果你将它们分开,那么为了使开发步骤无缝地编写脚本应该不难。
我认为您已阅读“ 为ASP.NET Web API生成TypeScript客户端API ”。为jQuery生成客户端API的步骤几乎与为Angular 2生成客户端API的步骤相同。演示TypeScript代码基于TUTORIAL:TOUR OF HEROES,许多人从中学习了Angular2。因此,您将能够看到如何WebApiClientGen
适应并改进Angular2应用程序的典型开发周期。
这是Web API代码:
using System; using System.Collections.Generic; using System.Linq; using System.Web.Http; using System.Runtime.Serialization; using System.Collections.Concurrent; namespace DemoWebApi.Controllers { [RoutePrefix("api/Heroes")] public class HeroesController : ApiController { public Hero[] Get() { return HeroesData.Instance.Dic.Values.ToArray(); } public Hero Get(long id) { Hero r; HeroesData.Instance.Dic.TryGetValue(id, out r); return r; } public void Delete(long id) { Hero r; HeroesData.Instance.Dic.TryRemove(id, out r); } public Hero Post(string name) { var max = HeroesData.Instance.Dic.Keys.Max(); var hero = new Hero { Id = max + 1, Name = name }; HeroesData.Instance.Dic.TryAdd(max + 1, hero); return hero; } public Hero Put(Hero hero) { HeroesData.Instance.Dic[hero.Id] = hero; return hero; } [HttpGet] public Hero[] Search(string name) { return HeroesData.Instance.Dic.Values.Where(d => d.Name.Contains(name)).ToArray(); } } [DataContract(Namespace = DemoWebApi.DemoData.Constants.DataNamespace)] public class Hero { [DataMember] public long Id { get; set; } [DataMember] public string Name { get; set; } } public sealed class HeroesData { private static readonly Lazy<HeroesData> lazy = new Lazy<HeroesData>(() => new HeroesData()); public static HeroesData Instance { get { return lazy.Value; } } private HeroesData() { Dic = new ConcurrentDictionary<long, Hero>(new KeyValuePair<long, Hero>[] { new KeyValuePair<long, Hero>(11, new Hero {Id=11, Name="Mr. Nice" }), new KeyValuePair<long, Hero>(12, new Hero {Id=12, Name="Narco" }), new KeyValuePair<long, Hero>(13, new Hero {Id=13, Name="Bombasto" }), new KeyValuePair<long, Hero>(14, new Hero {Id=14, Name="Celeritas" }), new KeyValuePair<long, Hero>(15, new Hero {Id=15, Name="Magneta" }), new KeyValuePair<long, Hero>(16, new Hero {Id=16, Name="RubberMan" }), new KeyValuePair&