惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Attack and Defense Labs
Attack and Defense Labs
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
The Hacker News
The Hacker News
C
Cyber Attacks, Cyber Crime and Cyber Security
A
Arctic Wolf
Recent Commits to openclaw:main
Recent Commits to openclaw:main
T
Troy Hunt's Blog
小众软件
小众软件
L
LangChain Blog
Schneier on Security
Schneier on Security
D
DataBreaches.Net
爱范儿
爱范儿
P
Proofpoint News Feed
博客园 - 聂微东
M
MIT News - Artificial intelligence
Hacker News: Ask HN
Hacker News: Ask HN
T
Tailwind CSS Blog
Vercel News
Vercel News
V
Visual Studio Blog
aimingoo的专栏
aimingoo的专栏
云风的 BLOG
云风的 BLOG
Jina AI
Jina AI
阮一峰的网络日志
阮一峰的网络日志
博客园 - 【当耐特】
博客园 - 三生石上(FineUI控件)
雷峰网
雷峰网
T
Threat Research - Cisco Blogs
Simon Willison's Weblog
Simon Willison's Weblog
月光博客
月光博客
Spread Privacy
Spread Privacy
C
Cisco Blogs
S
Securelist
量子位
S
Security @ Cisco Blogs
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
T
Tenable Blog
WordPress大学
WordPress大学
T
The Exploit Database - CXSecurity.com
宝玉的分享
宝玉的分享
C
Cybersecurity and Infrastructure Security Agency CISA
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
MongoDB | Blog
MongoDB | Blog
C
CERT Recently Published Vulnerability Notes
Help Net Security
Help Net Security
酷 壳 – CoolShell
酷 壳 – CoolShell
博客园 - 司徒正美
B
Blog RSS Feed
博客园_首页
Security Archives - TechRepublic
Security Archives - TechRepublic
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org

博客园 - 开发手游啦啦啦

用TypeScript开发爬虫程序 ABP导航源码分析 ABP的语言切换 AngularJs自定义指令详解(10) - 执行次序 AngularJs自定义指令详解(9) - terminal AngularJs自定义指令详解(8) - priority AngularJs自定义指令详解(7) - multiElement AngularJs自定义指令详解(6) - controller、require AngularJs自定义指令详解(5) - link AngularJs自定义指令详解(4) - transclude AngularJs自定义指令详解(3) - scope AngularJs自定义指令详解(2) - template AngularJs自定义指令详解(1) - restrict ABP的工作单元 ABP的数据过滤器(Data Filters) ABP的事件总线和领域事件(EventBus & Domain Events) 初入Cocos2d-x 2.2 quick-cocos2d-x之testlua之VisibleRect.lua quick-cocos2d-x之testlua之mainMenu.lua
ABP的Zero Sample
开发手游啦啦啦 · 2015-06-22 · via 博客园 - 开发手游啦啦啦

下载自:https://github.com/aspnetboilerplate/module-zero

打开D:\ABP\module-zero-master\sample里的ModuleZeroSampleProject.sln项目文件,马上还原程序包,试图update-database,报错,说没这个命令。

网上搜了半天,才看到解决方法:

输入set-executionpolicy remotesigned

再输入:

PM> Import-Module D:\ABP\module-zero-master\sample\packages\EntityFramework.6.1.3\tools\EntityFramework.psd1

PM> update-database

终于搞定。

(奇怪的是,重新解压,直接编译,让VS自动还原程序包,就不会出现上面的问题,直接update-database通过)

还有就是别手痒,去更新程序包,我下载的项目里还使用jquery-2.1.3.min.js,一更新就被换成jquery-2.1.4.min.js,但是BundleConfig类里还是2.1.3,没有改2.1.4啊…………

启动ModuleZeroSampleProject.Web项目,使用admin/123qwe登录没有问题。但是如果无输入、乱输入,则没有任何错误提示。

参考http://qasample.aspnetboilerplate.com/示例网站,分明是有错误提示的嘛:

原来还得改Web.config:

<customErrors mode="On" />

一个典型的ABP项目:

先看Core项目下的实体:

用户:

User继承的是AbpUser<Tenant, User>

UserManager继承的是AbpUserManager<Tenant, Role, User>

UserStore继承的是AbpUserStore<Tenant, Role, User>

这几个类实际上并无增加内容,仅仅是直接继承而已。需要注意的是User所继承的AbpUser<Tenant, User>使用了子类User作为TUser

角色:

Role继承的是AbpRole<Tenant, User>

RoleStore继承的是AbpRoleStore<Tenant, Role, User>

RoleManager继承的是AbpRoleManager<Tenant, Role, User>

PermissionChecker继承的是PermissionChecker<Tenant, Role, User>

同样,这些子类都没有增加内容。

租户:

Tenant继承的是AbpTenant<Tenant, User>

问题和回答:

Question继承了CreationAuditedEntity<int, User>,表明这个类要求包含创建者信息,后面可以看到需要使用到它的CreatorUser属性。

在数据表Questions里能够发现:

这个字段并没有在Question类里出现,要在CreationAuditedEntity里找:

因为问题和回答是一对多关系,所以有属性:

public virtual ICollection<Answer> Answers { get; set; }

Answer也继承了CreationAuditedEntity<int, User>

注意到有属性IsAccepted

领域服务:QuestionDomainService,继承了DomainService类

这个服务就是放“接受答案”方法的地方:

就是如果已有接受的答案,则找出来,设置为非接受,然后设置传入的答案为已接受。

注意在这个类已经使用了IRepository<Answer>

再看ModuleZeroSampleProject.EntityFramework项目下的ModuleZeroSampleProjectDbContext类

继承的是AbpZeroDbContext<Tenant, Role, User>

声明了:

        public virtual IDbSet<Question> Questions { get; set; }

        public virtual IDbSet<Answer> Answers { get; set; }

但是查看数据库,数据表可不止这两个。

再看ModuleZeroSampleProject.Application项目:

ModuleZeroSampleProjectAuthorizationProvider类,继承AuthorizationProvider,声明了几个权限:

创建问题、删除问题、删除答案、回答问题。

设置类MySettingProvider,继承SettingProvider,设置了一页显示10条问题。

IUserAppService声明了GetUsers方法,也就是用户列表。

IQuestionAppService声明了

GetQuestions获得所有问题

CreateQuestion创建问题

GetQuestion获取一个问题

VoteUp加1投票

VoteDown减1投票

SubmitAnswer回答问题

AcceptAnswer接受答案

再看实现:QuestionAppService类

GetQuestions方法中,读取了MySettingProvider里的配置:

 input.MaxResultCount = SettingManager.GetSettingValue<int>(MySettingProvider.QuestionsDefaultPageSize);

获取问题列表,需要注意输入的参数为GetQuestionsInput对象,该对象实现了IPagedResultRequest、ISortedResultRequest

看表达式

需要知道,Question类继承了CreationAuditedEntity<int, User>,因而具有CreateUser属性。

这里使用了EF里扩展的Include方法,要求根据外键CreatorUserID来加载创建者

PageBy方法是ABP扩展的一个分页方法。

另外要注意的是automapping:

    [AutoMapFrom(typeof(Question))]

    public class QuestionDto : CreationAuditedEntityDto

QuestionDto 类只有CreatorUserName属性,而没有CreatorUserID属性,但是还能映射:

Items = questions.MapTo<List<QuestionDto>>()

CreateQuestion方法:

可以看到CreateQuestion方法前,加了[AbpAuthorize("CanCreateQuestions")] 特性,对权限的验证非常便捷。

异步插入数据的写法:

GetQuestion方法:

跨表查询好狠:

            var question =

                _questionRepository

                    .GetAll()

                    .Include(q => q.CreatorUser)

                    .Include(q => q.Answers)

                    .Include("Answers.CreatorUser")

                    .FirstOrDefault(q => q.Id == input.Id);

SubmitAnswer方法:

使用了 _unitOfWorkManager.Current.SaveChanges();

AcceptAnswer方法:

直接调用了领域服务:_questionDomainService.AcceptAnswer(answer)

再看Tests项目对上面服务方法的测试,首先进行注入:

声明一个继承于AbpIntegratedTestBase的类SampleProjectTestBase,其构造函数

具体的测试类如UserAppService_Tests,需要继承SampleProjectTestBase

重新生成,就可以运行测试了:

Web项目,AccountController类,注意到使用了UserManager、AuthenticationManager

通过HttpContext.GetOwinContext().Authentication获取AuthenticationManager,使用了Owin

UserManager是通过AccountController的构造函数传入的,前者的父类有实现ITransientDependency,所以这里会被自动注入。

使用:
            var loginResult = await _userManager.LoginAsync(

                loginModel.UsernameOrEmailAddress,

                loginModel.Password,

                loginModel.TenancyName

                );

LoginAsync方法:

public virtual Task<AbpUserManager<TTenant, TRole, TUser>.AbpLoginResult> LoginAsync(string userNameOrEmailAddress, string plainPassword, string tenancyName = null)

这方法需要去zero的源码里研究

 AuthenticationManager可直接使用其SignIn、SignOut方法:

            AuthenticationManager.SignOut(DefaultAuthenticationTypes.ExternalCookie);

            AuthenticationManager.SignIn(new AuthenticationProperties { IsPersistent = loginModel.RememberMe }, loginResult.Identity);

HomeController加了 [AbpMvcAuthorize]特性。

Startup类可以看到配置,[assembly: OwinStartup(typeof(Startup))]

在Configuration方法里

        public void Configuration(IAppBuilder app)

        {

            app.UseCookieAuthentication(new CookieAuthenticationOptions

            {

                AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,

                LoginPath = new PathString("/Account/Login")

            });

            app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);

        }

    }

详情参考文章