使用ABP构建WebAPI的心得

本人多年winform经验,但是web方面做得很少,现在在用ABP做Web程序,以下是一些心得体会。可能弯路比较多。。。

现在有个需求是使用ajax加载jsTree做导航,这里就需要创建webapi了,参考了一些技术文档:

基于DDD的现代ASP.NET开发框架--ABP系列之2、ABP入门教程

构建Web API控制器

在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必须是名称相同。

 

posted @ 2016-04-27 17:06  Vevi  阅读(5542)  评论(0编辑  收藏  举报