ABP的Zero Sample


下載自: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);
        }
    }
詳情參考文章
Code! MVC 5 App with Facebook, Twitter, LinkedIn and Google OAuth2 Sign-on (C#) http://www.asp.net/mvc/overview/security/create-an-aspnet-mvc-5-app-with-facebook-and-google-oauth2-and-openid-sign-on

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM