一開(kāi)始列出的這個(gè)博文大綱,讓我想到了很久之前的一篇博文:戀愛(ài)雖易,相處不易:當(dāng)EntityFramework愛(ài)上AutoMapper,只不過(guò)這次的劇情換主角了,而且與 EF 和 AutoMapper 愛(ài)情故事不同的是,這次是個(gè)悲劇。
對(duì) ASP.NET 5 和 EF7 的感情,從她倆一出生,我就不可自拔的愛(ài)上她們了,不要嫌哥多情,有“情”,就是任性。
從一開(kāi)始的一見(jiàn)鐘情,到慢慢的深入了解,再到最后的抉擇與無(wú)奈,不管結(jié)局如何如何,其實(shí)這個(gè)過(guò)程,已經(jīng)讓我們彼此學(xué)到了很多,也成長(zhǎng)了很多。
前段時(shí)間,重寫之前的一個(gè)項(xiàng)目,選擇的是用 ASP.NET 5+EF7 進(jìn)行開(kāi)發(fā),因?yàn)槲易约汉芟矚g EF,所以一開(kāi)始就先研究的 EF7,當(dāng)看到 Code First Only,以及跨平臺(tái)的支持(和我關(guān)系不大)等等,非常的激動(dòng),記得當(dāng)時(shí)還紀(jì)錄了一篇博文:EF7 Code First Only-所引發(fā)的一些“臆想”,有人會(huì)說(shuō),對(duì)于 EF 的開(kāi)發(fā)模式,EF7 的功能又不是增加,而是減少了(Only),有必要這么大驚小怪嗎?當(dāng)然表面上來(lái)說(shuō),確實(shí)沒(méi)有什么驚奇的地方,但自己深入一想,Only 關(guān)鍵字,所傳遞的一些信息卻是另一層面的東西,那篇博文中已經(jīng)寫的很詳細(xì)了,這邊就不啰嗦了。
對(duì)于 EF7 的項(xiàng)目應(yīng)用,我自己是充滿信心的,不管遇到什么問(wèn)題,我也都想盡辦法去解決,無(wú)奈的是網(wǎng)上資料太少,谷歌搜索一些 EF7 問(wèn)題關(guān)鍵詞,基本上找不到對(duì)應(yīng)的解決方案,所以有些東西只能自己去摸索,去實(shí)踐,但這樣也會(huì)造成,往往一個(gè)很簡(jiǎn)單的問(wèn)題,自己卻想的很復(fù)雜,最后就不知不覺(jué)的陷在里面,而且越是解決不了,自己就越想解決,然后就陷入一個(gè)惡性循環(huán),最后呢?這個(gè)問(wèn)題還是沒(méi)有解決,這樣所造成的結(jié)果是什么呢?很簡(jiǎn)單,寶貴的時(shí)間被浪費(fèi)了,沒(méi)辦法,這也是新技術(shù)所應(yīng)用的成本。
我記得有一個(gè) EF7 Migration 的問(wèn)題,這個(gè)問(wèn)題大概花了我兩三天的時(shí)間,是的,兩三天的時(shí)間啊,一直在解決這個(gè)問(wèn)題,最后呢?很顯然,沒(méi)有解決,而且之后的幾天一直在郁悶,壓抑的感覺(jué)越來(lái)越強(qiáng)烈,當(dāng)一個(gè)問(wèn)題存在你心中很久很久,你就越想解決它,這個(gè)想法也就會(huì)變的越來(lái)越強(qiáng)烈,所以你需要你個(gè)發(fā)泄點(diǎn),什么呢?就是寫博文。轉(zhuǎn)移注意力,也算是一種吐槽,就紀(jì)錄了一篇博文:
這篇博文前面部分是一些 EF7 的簡(jiǎn)單使用,比如鏈接與實(shí)體映射配置等,當(dāng)然用過(guò)之后,你會(huì)發(fā)現(xiàn)和 EF 的其他版本差別很大,不可否認(rèn),非常強(qiáng)大,也更加“人性化”,比如最愛(ài)的:OneToOne、OneToMany 和 ManyToOne,簡(jiǎn)單、直接、明了。博文的后半部分主要紀(jì)錄我遇到的 EF7 Migration 問(wèn)題,當(dāng)然只是一個(gè)紀(jì)錄,沒(méi)有說(shuō)明其解決方式,當(dāng)時(shí)紀(jì)錄的目的也更多的是一種吐槽,或者自我發(fā)泄,但沒(méi)想到有一位園友 JeffreyWu,回復(fù)中貼出的一個(gè)參考鏈接,打開(kāi)了自己的一扇窗,真心非常感謝他,而且當(dāng)時(shí)的心情真是描述不出來(lái),就像烏云之后的晴天,壓抑自己的一個(gè)問(wèn)題,終于被解決了,那種感覺(jué)真是比中 500W 彩票的感覺(jué)還要好。
其實(shí)你發(fā)現(xiàn),EF7 Migration 的問(wèn)題解決很簡(jiǎn)單,就是換一種方法:使用 KVM 進(jìn)行命令操作,而我那幾天時(shí)間卻一直撲在:怎么使用 Package Manager Console 進(jìn)行 EF7 Migration 操作?而且一直陷在里面,最后卻解決不了。所以通過(guò)這件事,我自己也收獲了一點(diǎn),那就是如何解決問(wèn)題?如果一個(gè)問(wèn)題在一個(gè)場(chǎng)景中自己始終解決不了,不妨跳出這個(gè)場(chǎng)景,換一種思路去解決,不經(jīng)意的一瞬間,也許這個(gè)問(wèn)題就可以解決了。當(dāng)然收獲的最重要一點(diǎn)是:有問(wèn)題,寫博文,拋出問(wèn)題,之后零零散散紀(jì)錄了一些:
上面這些 EF7 問(wèn)題,都是項(xiàng)目應(yīng)用中所遇到的,而且是最最普通的問(wèn)題。通過(guò)之前 EF7 Migration 的事件,我自己在解決上面問(wèn)題中,對(duì)于每一個(gè)問(wèn)題,給自己的解決時(shí)間為最多半天,如果自己在半天時(shí)間內(nèi)解決不了,那就換一種思路,或者用另外一種方式去實(shí)現(xiàn),達(dá)到同樣的效果即可,所以對(duì)于上面每一個(gè)問(wèn)題,我都沒(méi)有像 EF7 Migration 一樣,陷在里面過(guò),當(dāng)然有的解決了,有的沒(méi)有解決,比較好的是,可以用另一種方式實(shí)現(xiàn)同樣的效果。
在博文中,有園友說(shuō)可以把問(wèn)題提交給:EntityFramework 7 Issues,然后我也順便提交了幾個(gè),當(dāng)時(shí)看到 issues 中那幾百個(gè)問(wèn)題,而且大部分都是 Open 狀態(tài),Closed 的很少,對(duì)于提交的問(wèn)題,我的想法是希望自己的寫法有問(wèn)題,而不是 EF7 本身的問(wèn)題,因?yàn)槲翼?xiàng)目正在使用它,我自己的問(wèn)題可以解決,如果是它的問(wèn)題,要等它解決,這就需要時(shí)間,不知道何年何月,但事實(shí)卻是,提交的幾個(gè)問(wèn)題都是 Bug:
這個(gè)很無(wú)奈,但通過(guò)這件事你會(huì)發(fā)現(xiàn)除這件事之外的很多東西,比如,因?yàn)殚_(kāi)源,因?yàn)樯鐓^(qū),你可以干很多事情,如果自己有能力,有時(shí)間,你完全可以去查看 EF7 的源代碼,去幫微軟解決問(wèn)題,然后隨意的和大洋彼岸寫 C# 最好的程序員交流,當(dāng)然能干這些的前提條件很多。
其實(shí)這些問(wèn)題最后確診為“Bug”,就致使我對(duì)使用 EF7 產(chǎn)生了一些動(dòng)搖,畢竟她現(xiàn)在還處在 Beta 階段,她還年輕,需要時(shí)間成長(zhǎng),而我卻沒(méi)有時(shí)間陪她、等她,這也許是我和她之間的一種無(wú)奈吧。
ASP.NET 5 之前的名字叫 ASP.NET vNext,其實(shí)我對(duì)她就像是與鄰班的女同學(xué),見(jiàn)過(guò)幾面,卻不怎么了解。對(duì)于 ASP.NET 5,說(shuō)白了,我頂多是做了幾個(gè) Demo,并沒(méi)有用于生產(chǎn)環(huán)境,從 ASP.NET 5 的目錄結(jié)構(gòu)或者其他文章的運(yùn)行機(jī)制介紹中,你就可以看出 ASP.NET 5 這次的改變是翻天覆地的,但簡(jiǎn)單的 Demo 說(shuō)明不了什么問(wèn)題,其實(shí)在現(xiàn)有的 ASP.NET 5 項(xiàng)目中,我也寫了不少的代碼,但都局限于 Controller 和 View 的使用,對(duì)于這塊,你可以像使用之前 MVC 版本一樣,在這部分中,你能體會(huì)到它的改變很少,最多你會(huì)發(fā)現(xiàn),在 Views 目錄下居然沒(méi)有了 Web.config,除了 Controller 和 View,在 ASP.NET 5 中,我寫代碼最多的地方就是 MaPRoute 路由配置了,這個(gè)不得不說(shuō)非常強(qiáng)大,寫起來(lái)也非常的爽,詳細(xì)內(nèi)容后面再說(shuō)。
關(guān)于 ASP.NET 5,我只紀(jì)錄一點(diǎn),昨天進(jìn)行 ASP.NET 5 項(xiàng)目的身份驗(yàn)證開(kāi)發(fā),也就是類似之前 MVC 的 FormsAuthentication.SetAuthCookie
操作,你會(huì)發(fā)現(xiàn)在 ASP.NET 5 中,沒(méi)有了這段代碼,身份驗(yàn)證操作采用類似于 Owin 形式的,但這個(gè)我沒(méi)接觸過(guò),所以不是很了解,關(guān)于這個(gè)問(wèn)題,我給自己一天的時(shí)間去解決,或者做出一個(gè)可以運(yùn)行的 IdentityDemo,結(jié)果呢?我想你已經(jīng)猜到了,沒(méi)有完成。
關(guān)于 ASP.NET 5 的學(xué)習(xí),微軟提供了一個(gè) ASP.NET 5 版本的 MusicStore 項(xiàng)目,對(duì)于學(xué)習(xí)資料很少的 ASP.NET 5 來(lái)說(shuō),這是相當(dāng)寶貴的,關(guān)于身份驗(yàn)證的實(shí)現(xiàn),我當(dāng)時(shí)也希望可以從這個(gè)項(xiàng)目中得到一些啟發(fā),但遺憾的是沒(méi)有找到我所需要的,我稍微貼一下這部分的實(shí)現(xiàn)代碼。
AccountController:
[Authorize]public class AccountController : Controller{ public AccountController(UserManager<applicationUser> userManager, SignInManager<ApplicationUser> signInManager) { UserManager = userManager; SignInManager = signInManager; } public UserManager<ApplicationUser> UserManager { get; private set; } public SignInManager<ApplicationUser> SignInManager { get; private set; } // GET: /Account/Login [HttpGet] [AllowAnonymous] public IActionResult Login(string returnUrl = null) { ViewBag.ReturnUrl = returnUrl; return View(); } // // POST: /Account/Login [HttpPost] [AllowAnonymous] [ValidateAntiForgeryToken] public async Task<IActionResult> Login(LoginViewModel model, string returnUrl = null) { if (ModelState.IsValid) { var signInStatus = await SignInManager.PassWordSignInAsync(model.UserName, model.Password, model.RememberMe, shouldLockout: false); switch (signInStatus) { case SignInStatus.Success: return RedirectToLocal(returnUrl); case SignInStatus.Failure: default: ModelState.AddModelError("", "Invalid username or password."); return View(model); } } // If we got this far, something failed, redisplay form return View(model); }}
ConfigureServices:
// Add Identity services to the services container.services.AddDefaultIdentity<ApplicationDbContext, ApplicationUser, IdentityRole>(Configuration);
這只是示例項(xiàng)目中的部分代碼,除了 ConfigureServices 中的這部分的配置,其實(shí)還有 services.AddIdentity<IdentityUser>();
,app.UseIdentity();
等等,到現(xiàn)在我都不明白這其中的區(qū)別,或者所不同的作用,在之前的 MVC 版本中,我們一般在 Web.config 中進(jìn)行下面配置:
<system.web> <authentication mode="Forms"> <forms name=".DottextCookie" loginUrl="~/Account/Login" protection="All" domain=".demo.com" protection="All" timeout="43200" path="/" /> </authentication> <compilation debug="true" targetFramework="4.5.3" /> <httpRuntime /></system.web>
而在 ASP.NET 5 中沒(méi)有了 Web.config,哪該怎么進(jìn)行配置?MusicStore 中并沒(méi)有這部分的實(shí)現(xiàn),找資料后發(fā)現(xiàn),要這樣進(jìn)行配置:
app.UseCookieAuthentication((cookieOptions) =>{ cookieOptions.AuthenticationType = ClaimsIdentityOptions.DefaultSecurityStampClaimType; cookieOptions.AuthenticationMode = AuthenticationMode.Active; cookieOptions.CookieHttpOnly = true; cookieOptions.CookieName = ".DottextCookie"; cookieOptions.LoginPath = new PathString("/Account/Login"); cookieOptions.CookieDomain = ".demo.com";}, "AccountAuthorize");
project.json 配置:
"dependencies": { "Microsoft.AspNet.Identity.EntityFramework": "3.0.0-beta1", "Microsoft.AspNet.Identity": "3.0.0-beta1", "Microsoft.AspNet.Security": "1.0.0-beta1", "Microsoft.AspNet.Security.Cookies": "1.0.0-beta1"}
Security 類似于關(guān)聯(lián)賬戶登錄,比如你可以在 ASP.NET 5 中,增加外部賬戶驗(yàn)證(Google、Facebook 賬戶等等),那 Microsoft.AspNet.Identity.EntityFramework
是什么?身份驗(yàn)證怎么和 EF 扯到一起了,這個(gè)是 ASP.NET 5 中新增的一個(gè)功能,你可以進(jìn)行配置身份驗(yàn)證的 DbContext,就比如上面 ConfigureServices 中的配置代碼,然后綁定之后,你可以很方便的進(jìn)行身份驗(yàn)證操作,比如 Login、Register、Manage 和 LogOff 等等,找到一篇示例說(shuō)明:
越扯越多了,這部分內(nèi)容,可以另外寫篇博文說(shuō)明,其實(shí)最后我想要的功能是不綁定 DbContext,在 ASP.NET 5 項(xiàng)目中,只進(jìn)行判斷操作,身份驗(yàn)證在另外服務(wù)中進(jìn)行,然后在本項(xiàng)目中可以實(shí)現(xiàn)類似 FormsAuthentication.SetAuthCookie
操作就可以了,但最后做了幾個(gè) Demo 都不能實(shí)現(xiàn),規(guī)定的一天時(shí)間,已經(jīng)用完了,所以。。。
還有一個(gè)問(wèn)題是如何在 ASP.NET 5 項(xiàng)目中添加 Web 引用,比如 WCF,但你發(fā)現(xiàn)在 Web 項(xiàng)目或是類庫(kù)項(xiàng)目,并沒(méi)有“Add Web Reference”這個(gè)選項(xiàng),比如這個(gè)帖子:Add Web Service Reference in VS 2015,沒(méi)人回答,搜索之類的關(guān)鍵詞,如果有回答,大部分是:no,那如果不支持的話,可以換一種思路去解決,比如使用 WebAPI,當(dāng)然現(xiàn)在也比較流行這個(gè),但這就會(huì)造成一個(gè)重寫成本,你需要額外進(jìn)行考慮。
新聞熱點(diǎn)
疑難解答
圖片精選
網(wǎng)友關(guān)注