使用ABP构建WebAPI的心得
本人多年winform经验,但是web方面做得很少,现在在用ABP做Web程序,以下是一些心得体会。可能弯路比较多。。。
现在有个需求是使用ajax加载jsTree做导航,这里就需要创建webapi了,参考了一些技术文档:
基于DDD的现代ASP.NET开发框架--ABP系列之2、ABP入门教程
在Application下定义了如下接口和类用于测试:
public interface INaviTreeAppService : IApplicationService { ListResultOutput<NaviTreeOutput> GetNaviTreeOutputs(); //[HttpGet] NaviTreeOutput GetTopNode(); }
public class NaviTreeManagerAppService : ApplicationService, INaviTreeAppService { private readonly IRepository<DepartMent> _departmentRepository; public NaviTreeAppService(IRepository<DepartMent> departmentRepository ) { _departmentRepository = departmentRepository; } public ListResultOutput<Dto.NaviTreeOutput> GetNaviTreeOutputs() { var list = new List<Dto.NaviTreeOutput>(); var opt = new Dto.NaviTreeOutput(); opt.id = "1"; opt.parent = "#"; opt.text = "监控单位1"; opt.state=new StateObj(){selected=true,opened=true}; list.Add(opt); opt = new Dto.NaviTreeOutput(); opt.id = "2"; opt.parent = "#"; opt.text = "监控单位2"; opt.state = new StateObj() { opened = true }; list.Add(opt); opt = new Dto.NaviTreeOutput(); opt.id = "3"; opt.parent = "1"; opt.text = "监控子单位11"; opt.state = new StateObj() { opened = true }; list.Add(opt); opt = new Dto.NaviTreeOutput(); opt.id = "4"; opt.parent = "1"; opt.text = "监控子单位12"; opt.state = new StateObj() { opened = true }; list.Add(opt); opt = new Dto.NaviTreeOutput(); opt.id = "5"; opt.parent = "2"; opt.text = "监控子单位21"; opt.state = new StateObj() { opened = true }; list.Add(opt); opt = new Dto.NaviTreeOutput(); opt.id = "6"; opt.parent = "2"; opt.text = "监控子单位22"; opt.state = new StateObj() { opened = true }; list.Add(opt); return new ListResultOutput<NaviTreeOutput>(list); } public NaviTreeOutput GetTopNode() { var opt = new Dto.NaviTreeOutput(); opt.id = "1"; opt.parent = "#"; opt.text = "监控单位1"; opt.state = new StateObj() { selected = true, opened = true }; return opt; } }
在webapimodule中添加如下解析,将Post改为Get访问:
DynamicApiControllerBuilder.For<INaviTreeAppService>("DepartAndNavi/NaviTree").ForMethod("GetTopNode").WithVerb(HttpVerb.Get).Build();
在浏览器中输入路径后,发现报错:{"message":"An error has occurred."}
打开地址:http://localhost:6634/api/abpServiceProxies/GetAll 发现确实有此api,但是访问就是报错。
重新读了好几遍相关文档,对比了现有的abpzero定义,都没有发现什么。
但是看到webapimodule文件的动态解析:
DynamicApiControllerBuilder .ForAll<IApplicationService>(typeof(WebMonitorApplicationModule).Assembly, "app") .Build();
我觉得我写了application层的定义,那么就应该解析出我的INaviTreeAppService中定义的api,所以我删除了自定义的解析,
然后访问http://localhost:6634/api/abpServiceProxies/GetAll查看,发现没有INaviTreeAppService的webapi定义。
这时终于知道具体的错误地点了,肯定是application层写的不对,又是读文档又是对比代码。
终于让我发现了错误的地方了:Zero写的都是对应的,比如ITenantAppService和TenantAppService;IRoleAppService和RoleAppService
而我的INaviTreeAppService 和 NaviTreeManagerAppService 则不是如此,然后将NaviTreeManagerAppService 改为NaviTreeAppService后成功了。
看来abp也继承了mvc中默认规则的设置,IAppService跟实现类AppService必须是名称相同。