本人多年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必须是名称相同。