1. 程式人生 > >ASP.NET MVC 隨想錄——開始使用ASP.NET Identity,初級篇

ASP.NET MVC 隨想錄——開始使用ASP.NET Identity,初級篇

在之前的文章中,我為大家介紹了OWIN和Katana,有了對它們的基本瞭解後,才能更好的去學習ASP.NET Identity,因為它已經對OWIN 有了良好的整合。

在這篇文章中,我主要關注ASP.NET Identity的建立和使用,包括基礎類的搭建和使用者管理功能的實現——

在後續文章中,我將探索它更高階的用法,比如身份驗證並聯合ASP.NET MVC 進行授權、使用第三方登入、宣告式認證等。

回到頂部

ASP.NET Identity 前世今生

ASP.NET Membership

ASP.NET 2.0時代,ASP.NET Membership用於使用者管理的常見需求。包括表單身份驗證(

Form Authentication),一個用於儲存使用者名稱、密碼和其他使用者資訊的 SQL Server 資料庫。但是現在,對於 Web 應用程式的資料儲存我們有了更多的選擇。而且,大多數開發者希望自己的站點能夠使用第三方供應商提供的社交賬號來實現身份驗證和授權。但是,由於 ASP.NET Membership自身設計的限制,已經難以滿足如下變化:

  • 資料庫架構為 SQL Server 設計,而且無法修改。雖然你可以新增額外的使用者資訊,但這些資料被存入了一張不同的資料表。而且這些資訊難以訪問,除了使用 Profile Provider API
  • 雖然通過Provider,你可以對後臺資料儲存結構的修改,但是該
    Provider的設計是假設我們對關係型資料庫進行修改。雖然你也可以寫一個面向非關係型(例如 Windows Azure Tables)儲存機制的Provider。但是,圍繞著相關的設計,你還需要大量的工作。這包括編寫大量的程式碼,以及為那些 NoSQL 資料庫不支援的方法丟擲一大堆 System.NotImplementedException 異常。
  • 由於登入、登出功能基於表單身份驗證,因此ASP.NET Membership 無法支援 OWINOWIN 包括了一些用於身份驗證的 Middleware 中介軟體,如支援Microsoft 賬戶、 Facebook,GoogleTwitter
    等的登入,還支援來自於組織內部的賬號例如 Active Directory Windows Azure Active Directory 等登入。OWIN 也提供了包括對OAuth 2.0, JWT CORS的支援。

正是由於ASP.NET Membership 諸多限制,微軟採取了一系列的補救措施,比如釋出了ASP.NET Simple Membership ASP.NET Universal Providers,他們通過Entity FrameworkCode First,可以方便的去擴充套件使用者資訊,而非像ASP.NET Membership 那樣需要Provider 來實現。

但是它們仍舊存在不足,主要包括如下兩點:

  • 對非關係型資料庫支援不好
  • 無法和OWIN相容

ASP.NET Identity

由於ASP.NET Membership、ASP.NET Simple Membership ASP.NET Universal Providers 設計上的不足,微軟在接受了大量反饋後,於.NET Framework 4.5 中推出了ASP.NET Identity,如果用一句話概括——ASP.NET Identity 為ASP.NET 應用程式提供了一系列的API用來管理和維護使用者 ,它包括如下新特性:

    One ASP.NET Identity

  • ASP.NET Identity 可以用在所有的 ASP.NET 框架上,例如 ASP.NET MVC, Web FormsWeb PagesASP.NET Web API SignalR
  • ASP.NET Identity 可以用在各種應用程式中,例如Web 應用程式、移動應用、商店應用或者混合架構應用

易於管理使用者資訊

  • ASP.NET Identity提供了豐富的API ,可以方便的管理使用者

持久化控制

  • 預設情況下,ASP.NET Identity將使用者所有的資料儲存在資料庫中。ASP.NET Identity 使用 Entity Framework 實現其所有的檢索和持久化機制。
  • 通過Code First,你可以對資料庫架構的完全控制,一些常見的任務例如改變表名稱、改變主鍵資料型別等都可以很輕易地完成。
  • 能夠很容易地引入其他不同的儲存機制,例如 SharePoint, Windows Azure 儲存表服務, NoSQL 資料庫等。不必再丟擲 System.NotImplementedException 異常了。

單元測試能力

  • ASP.NET Identity 能讓 Web 應用程式能夠更好地進行單元測試。你可以為你應用程式使用了 ASP.NET Identity 的部分編寫單元測試。

角色Provider

  • ASP.NET Identity 中的角色Provider配合ASP.NET MVC Authorize,可以讓你基於角色來限制對應用程式某個部分的訪問。你可以很容易地建立Admin之類的角色,並將使用者加入其中。

基於宣告的

  • ASP.NET Identity 支援基於宣告的身份驗證,它使用一組"宣告"來表示使用者的身份標識。相對於"角色","宣告"能使開發人員能夠更好地描述使用者的身份標識。"角色"本質上只是一個布林型別(即"屬於"或"不屬於"特定角色),而一個"宣告"可以包含更多關於使用者標識和成員資格的資訊。

社交賬號登入Provider

  • 你可以很容易的為你的應用程式加入社交賬號登入功能(例如 Microsoft 賬戶,Facebook,TwitterGoogle 等),並將使用者特定的資料存入你的應用程式。

    Windows Azure Active Directory

  • 你還可以加入使用 Windows Azure Active Directory 進行登入的功能,並將使用者特定的資料存入你的應用程式。

    OWIN 整合

  • ASP.NET 身份驗證現在是基於 OWIN 中介軟體實現,並且可以在任何基於 OWIN 的宿主上使用。ASP.NET Identity 不依賴System.Web程式集,與此同時,它完全兼容於 OWIN 框架,並且能被用在任何基於OWIN HostServer 之上。
  • ASP.NET Identity使用OWIN Authentication來登入、登出操作。這意味著應用程式使用CookieAuthentication 生成 cookie 而非FormsAuthentication 

    NuGet

  • ASP.NET Identity 作為一個 NuGet 包進行釋出,並且安裝在ASP.NET MVCWeb Forms ASP.NET Web API 專案模板中。當然,你也可以從 NuGet 庫中下載它。
  • ASP.NET IdentityNuGet包的形式釋出,這樣能讓ASP.NET 團隊更好的Bug修復和迭代新功能,與此同時,開發人員可以在第一時間獲取到最新版本。
回到頂部

建立 ASP.NET Identity

建立 ASP.NET Identity資料庫

ASP.NET Identity並不像ASP.NET Membership那樣依賴SQL Server架構,但關係型儲存仍然是預設和最簡單的實現方式,儘管近些年來NoSQL發展迅猛,但關係型資料庫易於理解,仍舊是開發團隊內部主流的儲存選擇。

ASP.NET Identity使用Entity Framework Code First來自動建立資料庫架構。在此示例中,我使用localdb來建立一個空的資料庫IdentityDb,然後交由Code First管理資料庫架構。

localdb內建在Visual Studio中而且它是輕量級的SQL Server,能讓開發者簡單快速操作資料庫。

新增ASP.NET Identity 包

Identity以包的形式釋出在NuGet上,這能夠很方便的將它安裝到任意專案中,通過在Package Manger Console輸入如下命令來安裝Identity

  • Install-Package Microsoft.AspNet.Identity.EntityFramework
  • Install-Package Microsoft.AspNet.Identity.OWIN
  • Install-Package Microsoft.Owin.Host.SystemWeb

Visual Studio中選擇建立一個完整的ASP.NET MVC專案時,預設情況下該模板會使用ASP.NET Identity API自動新增通用的使用者管理模組。對於初學者,我建議學習它裡面API的使用,但我不推薦將它使用在正式環境中,因為它產生了過多的通用和冗餘程式碼,有時候我們只想讓它簡單工作。

更新Web.config檔案

若要將ASP.NET Identity使用在專案裡,除了新增相應的包之外,還需要在Web.config中新增如下配置資訊:

  • 資料庫連線字串
  • 指定的OWIN Startup啟動項,用作初始化Middleware至Pipeline
  1. <connectionStrings>
  2.   <add name="IdentityDb" providerName="System.Data.SqlClient"
  3.        connectionString="Data Source=(localdb)\v11.0;Initial Catalog=IdentityDb;Integrated Security=True;Connect Timeout=15;Encrypt=False;TrustServerCertificate=False; MultipleActiveResultSets=True" />
  4. </connectionStrings>
  5. <appSettings>
  6.   <add key="owin:AppStartup" value="UsersManagement.IdentityConfig" />
  7. </appSettings>

建立Entity Framework

如果大家使用過ASP.NET Membership,對比過後你會發現在ASP.NET Identity擴充套件User資訊是多麼的簡單和方便。

1.建立 User 類

第一個要被建立的類它代表使用者,我將它命名為AppUser,繼承自Microsoft.AspNet.Identity.EntityFramework 名稱空間下IdentityUser,IdentityUser 提供了基本的使用者資訊,如Email、PasswordHash、UserName、PhoneNumber、Roles等,當然我們也可以在其派生類中新增額外的資訊,程式碼如下:

  1. using Microsoft.AspNet.Identity.EntityFramework;
  2. namespace UsersManagement.Models
  3. {
  4.     public class AppUser:IdentityUser
  5.     {
  6.     }
  7. }

2.建立 Database Context 類

接下來的步驟就是建立EF Database Context 來操作AppUser。ASP.NET Identity將使用Code First 來建立和管理資料庫架構。值得注意的是,Database Context必須繼承自IdentityDbContext<T>,而且T為User類(在此示例即AppUser),程式碼如下所示:

  1. public class AppIdentityDbContext : IdentityDbContext<AppUser>
  2.    {
  3.        public AppIdentityDbContext() : base("IdentityDb")
  4.        {
  5.        }
  6.        static AppIdentityDbContext()
  7.        {
  8.            Database.SetInitializer<AppIdentityDbContext>(new IdentityDbInit());
  9.        }
  10.        public static AppIdentityDbContext Create()
  11.        {
  12.            return new AppIdentityDbContext();
  13.        }
  14.    }
  15.    public class IdentityDbInit : DropCreateDatabaseIfModelChanges<AppIdentityDbContext>
  16.    {
  17.        protected override void Seed(AppIdentityDbContext context)
  18.        {
  19.            PerformInitialSetup(context);
  20.            base.Seed(context);
  21.        }
  22.        public void PerformInitialSetup(AppIdentityDbContext context)
  23.        {
  24.            //初始
  25.        }
  26.    }

上述程式碼中,AppIdentityDbContext 的建構函式呼叫基類建構函式並將資料庫連線字串的Name作為引數傳遞,它將用作連線資料庫。同時,當Entity Framework Code First成功建立資料庫架構後,AppIdentityDbContext的靜態建構函式呼叫Database.SetInitializer方法Seed 資料庫而且只執行一次。在這兒,我的Seed 類IdentityDbInit。

最後,AppIdentityDbContext 定義了 Create方法,它將被 OWIN Middleware回掉然後返回AppIdentityDbContext例項,這個例項被儲存在OwinContext中。

3.建立User Manger 類

User Manager類作為ASP.NET Identity中最為重要的類之一,用來管理User。同樣,自定義的User Manger類必須繼承自UserManager<T >,此處T就為AppUser。UserManager<T>提供了建立和操作使用者的一些基本方法並且全面支援C# 非同步程式設計,所以你可以使用CreateAsync(Create),FindAsync(Find)、DeleteAsync(Delete)、UpdateAsync(Update)來進行使用者管理,值得注意的是,它並不通過Entity Framework 來直接操作使用者,而是間接呼叫UserStore來實現。UserStore<T>是Entity Framework 類並實現了IUserStore<T>介面,並且實現了定義在UserManger中操作使用者的方法。程式碼如下所示:

  1. /// <summary>
  2. /// 使用者管
  3. /// </summary>
  4.  public class AppUserManager : UserManager<AppUser> {
  5.      public AppUserManager(IUserStore<AppUser> store)
  6.          : base(store) {
  7.      }
  8.      public static AppUserManager Create(
  9.              IdentityFactoryOptions<AppUserManager> options,
  10.              IOwinContext context) {
  11.          AppIdentityDbContext db = context.Get<AppIdentityDbContext>();
  12.          //UserStore<T> 是 包含在 Microsoft.AspNet.Identity.EntityFramework 中,它實現了 UserManger 類中與使用者操作相關的方法。
  13.          //也就是說UserStore<T>類中的方法(諸如:FindById、FindByNameAsync...)通過EntityFramework檢索和持久化UserInfo到資料庫
  14.          AppUserManager manager = new AppUserManager(new UserStore<AppUser>(db));
  15.          return manager;
  16.      }
  17.  }

上述程式碼中,靜態的Create方法將返回AppUserManger例項,它用來操作和管理使用者,值得注意的是,它需要傳入OwinContext物件,通過該上下文物件,獲取到儲存在Owin環境字典中的Database Context例項。

4.建立OWIN Startup 類

最後,通過Katana(OWIN的實現)提供的API,將Middleware 中介軟體註冊到Middleware中,如下所示:

  1. public class IdentityConfig
  2.     {
  3.         public void Configuration(IAppBuilder app)
  4.         {
  5.             //1.使用app.Use方法將IdentityFactoryMiddleware和引數callback回掉函式註冊到Owin Pipeline
  6.             //app.Use(typeof(IdentityFactoryMiddleware<T, IdentityFactoryOptions<T>>), args);
  7.             //2.當IdentityFactoryMiddleware中介軟體被Invoke執行時,執行callback回掉函式,返回具體例項Instance
  8.             //TResult instance = ((IdentityFactoryMiddleware<TResult, TOptions>) this).Options.Provider.Create(((IdentityFactoryMiddleware<TResult, TOptions>) this).Options, context);
  9.             //3.將返回的例項儲存在Owin Context
  10.             //context.Set<TResult>(instance);
  11.             app.CreatePerOwinContext<AppIdentityDbContext>(AppIdentityDbContext.Create);
  12.             app.CreatePerOwinContext<AppUserManager>(AppUserManager.Create);
  13.             app.UseCookieAuthentication(new CookieAuthenticationOptions
  14.             {
  15.                 AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
  16.                 LoginPath = new PathString("/Account/Login"),
  17.             });
  18.         }
  19.     }

上述程式碼中,通過CreatePerOwinContext方法將AppIdentityDbContext和 AppUserManager的例項註冊到OwinContext中,這樣確保每一次請求都能獲取到相關ASP.NET Identity物件,而且還能保證全域性唯一。

UseCookieAuthentication 方法指定了身份驗證型別為ApplicationCookie,同時指定LoginPath屬性,當Http請求內容認證不通過時重定向到指定的URL。

回到頂部

使用ASP.NET Identity

成功建立ASP.NET Identity之後,接下來就是如何去使用它了,讓我們再回顧一下ASP.NET Identity的幾個重要知識點:

  • 大多數應用程式需要使用者、角色管理,ASP.NET Identity提供了API用來管理使用者和身份驗證
  • ASP.NET Identity 可以運用到多種場景中,通過對使用者、角色的管理,可以聯合ASP.NET MVC Authorize 過濾器 來實現授權功能。

獲取所有的Users物件

在上一小節中,通過CreatePerOwinContext方法將AppIdentityDbContext和 AppUserManager的例項註冊到OwinContext中,我們可以通過OwinContext物件的Get方法來獲取到他們,將下面程式碼放在Controller中,方便供Action獲取物件:

  1. private AppUserManager UserManager
  2. {
  3.       get { return HttpContext.GetOwinContext().GetUserManager<AppUserManager>(); }
  4.  }

在上述程式碼中,通過Microsoft.Owin.Host.SystemWeb 程式集,為HttpContext增加了擴充套件方法GetOwinContext,返回的 OwinContext物件是對Http請求的封裝,所以GetOwinContext方法可以獲取到每一次Http請求的內容。接著通過IOwinContext的擴充套件方法GetUserManager獲取到儲存在OwinContext中的UserManager例項。

然後,通過UserManager的Users屬性,可以獲取到所有的User集合,如下所示:

  1. public ActionResult Index()
  2. {
  3.     return View(UserManager.Users);
  4. }

建立User物件

通過UserManager的CreateAsync方法,可以快速的建立User物件,如下程式碼建立了User ViewModel:

  1. public class UserViewModel
  2. {
  3.     [Required]
  4.     public string Name { get; set; }
  5.     [Required]
  6.     public string Email { get; set; }
  7.     [Required]
  8.     public string Password { get; set; }
  9. }

使用UserManager物件的CreateAsync方法將AppUser物件將它持久化到資料庫:

  1. [HttpPost]
  2. public async Task<ActionResult> Create(UserViewModel model)
  3. {
  4.     if (ModelState.IsValid)
  5.     {
  6.         var user = new AppUser {UserName = model.Name, Email = model.Email};
  7.         //傳入Password並轉換成PasswordHash
  8.         IdentityResult result = await UserManager.CreateAsync(user,
  9.             model.Password);
  10.         if (result.Succeeded)
  11.         {
  12.             return RedirectToAction("Index");
  13.         }
  14.         AddErrorsFromResult(result);
  15.     }
  16.     return View(model);
  17. }

CreateAsync返回IdentityResult 型別物件,它包含如下了兩個重要屬性:

  • Succeeded : 如果操作成功返回True
  • Errors:返回一個字串型別的錯誤集合
  1. private void AddErrorsFromResult(IdentityResult result)
  2. {
  3.     foreach (string error in result.Errors)
  4.     {
  5.         ModelState.AddModelError("", error);
  6.     }
  7. }

新增自定義密碼驗證策略

有時候,我們需要實現密碼策略,如同AD中控制那樣,密碼複雜度越高,那麼它被破譯的概率就越低。

ASP.NET Identity 提供了PasswordValidator類,提供瞭如下屬性來配置密碼策略:

RequiredLength

指定有效的密碼最小長度

RequireNonLetterOrDigit

當為True時,有效的密碼必須包含一個字元,它既不是數字也不是字母

RequireDigit

當為True時,有效密碼必須包含數字

RequireLowercase

當為True時,有效密碼必須包含一個小寫字元

RequireUppercase

當為True時,有效密碼必須包含一個大寫字元

如果這些預定義屬性無法滿足我們的需求時,我們可以新增自定義的密碼驗證策略,只要繼承PasswordValidator 並且Override ValidateAsync方法即可,如下程式碼所示:

  1. public class CustomPasswordValidator : PasswordValidator
  2.    {
  3.        public override async Task<IdentityResult> ValidateAsync(string password)
  4.        {
  5.            IdentityResult result = await base.ValidateAsync(password);
  6.            if (password.Contains("12345"))
  7.            {
  8.                List<string> errors = result.Errors.ToList();
  9.                errors.Add("密碼不能包含連續數字");
  10.                result = new IdentityResult(errors);
  11.            }
  12.            return result;
  13.        }
  14.    }

上述程式碼中,值得注意的是,IdentityResult 物件的 Errors是隻讀的,所以無法直接賦值,只能通過例項化IdentityResult 類並通過建構函式傳入Errors。

自定義的密碼策略建立完畢過後,接著就將它附加到UserManager物件的PasswordValidator 屬性上,如下程式碼所示:

  1. //自定義的Password Validator
  2. manager.PasswordValidator = new CustomPasswordValidator
  3. {
  4.     RequiredLength = 6,
  5.     RequireNonLetterOrDigit = false,
  6.     RequireDigit = false,
  7.     RequireLowercase = true,
  8.     RequireUppercase = true
  9. };

更多使用者驗證策略

UserManager 除了PasswordValidator之外,還提供了一個更加通用的屬性:UserValidator ,它包含如下兩個策略屬性:

AllowOnlyAlphanumericUserNames

當為True時,UserName只能包含字母數字

RequireUniqueEmail

當為True時,Email地址必須唯一

當然這兩種策略如果不滿足我們的需求的話,我們也可以像Password那樣去定製化,只要 繼承UserValidator<T> 然後 Override ValidateAsync 方法,如下所示:

  1. public class CustomUserValidator : UserValidator<AppUser>
  2. {
  3.     public CustomUserValidator(AppUserManager mgr)
  4.         : base(mgr)
  5.     {
  6.     }
  7.     public override async Task<IdentityResult> ValidateAsync(AppUser user)
  8.     {
  9.         IdentityResult result = await base.ValidateAsync(user);
  10.         if (!user.Email.ToLower().EndsWith("@jkxy.com"))
  11.         {
  12.             List<string> errors = result.Errors.ToList();
  13.             errors.Add("Email 地址只支援jkxy域名");
  14.             result = new IdentityResult(errors);
  15.         }
  16.         return result;
  17.     }
  18. }

上述程式碼增強了對Email的驗證,必須為@jkxy域名,然後將自定義的UserValidator 附加到User Manger 物件上:

  1. //自定義的User Validator
  2. manager.UserValidator = new CustomUserValidator(manager) {
  3.     AllowOnlyAlphanumericUserNames = true,
  4.     RequireUniqueEmail = true
  5. };
回到頂部

ASP.NET Identity 其他API介紹

在上一小節中,介紹了CreateAsync 的使用,接下來一鼓作氣,繼續ASP.NET Identity之旅。

實現Delete 使用者功能

按照我們的經驗,若要刪除一個使用者,首先需要Find 它。通過UserManager 物件的 FindByIdAsync來找到要被刪除的物件,如果該物件不為null,那麼再呼叫UserManager物件的DeleteAsync來刪除它,如下所示:

  1. [HttpPost]
  2. public async Task<ActionResult> Delete(string id)
  3. {
  4.     AppUser user = await UserManager.FindByIdAsync(id);
  5.     if (user != null)
  6.     {
  7.         IdentityResult result = await UserManager.DeleteAsync(user);
  8.         if (result.Succeeded)
  9.         {
  10.             return RedirectToAction("Index");
  11.         }
  12.         return View("Error", result.Errors);
  13.     }
  14.     return View("Error", new[] {"User Not Found"});
  15. }

實現編輯使用者操作

因為編輯操作UpdateAsync 只接受一個引數,而不像CreateAsync那樣可以傳入Password,所以我們需要手動的去校驗並給PasswordHash屬性賦值,當密碼策略驗證通過時再去驗證Email策略,這樣確保沒有髒資料,如下所示:

  1. [HttpPost]
  2. 相關推薦

    ASP.NET MVC 隨想錄——開始使用ASP.NET Identity初級

    在之前的文章中,我為大家介紹了OWIN和Katana,有了對它們的基本瞭解後,才能更好的去學習ASP.NET Identity,因為它已經對OWIN 有了良好的整合。 在這篇文章中,我主要關注ASP.NET Identity的建立和使用,包括基礎類的搭建和使用者管理功能的實現—— 在後續文章中,我將

    ASP.NET MVC 隨想錄—— 使用ASP.NET Identity實現基於宣告的授權高階

    在這篇文章中,我將繼續ASP.NET Identity 之旅,這也是ASP.NET Identity 三部曲的最後一篇。在本文中,將為大家介紹ASP.NET Identity 的高階功能,它支援宣告式並且還可以靈活的與ASP.NET MVC 授權結合使用,同時,它還支援使用第三方來實現身份驗證。 關於A

    開始使用ASP.NET Identity初級

    在之前的文章中,我為大家介紹了OWIN和Katana,有了對它們的基本瞭解後,才能更好的去學習ASP.NET Identity,因為它已經對OWIN 有了良好的整合。在這篇文章中,我主要關注ASP.NET Identity的建立和使用,包括基礎類的搭建和使用者管理功能的實現—

    JSON之Asp.net MVC C#對象轉JSONDataTable轉JSONList<T>轉JSON,JSON轉List<T>,JSON轉C#對象

    技術分享 toolbar index 基本 枚舉 對象轉json tostring cab 拼接 一、JSON解析與字符串化   JSON.stringify()  序列化對象、數組或原始值   語法:JSON.stringify(o,filter,indent)     

    七天學會ASP.NET MVC ——深入理解ASP.NET MVC

    pow rdquo www turn iter 業務邏輯 activator 過去的 界面 七天學會ASP.NET MVC (一)——深入理解ASP.NET MVC 系列文章 七天學會ASP.NET MVC (一)&mdas

    ASP.NET MVC 學習(一) ado.net 呼叫儲存過程

    ASP.NET MVC  學習(一) ado.net 呼叫儲存過程     見證我的菜鳥歷史: 想學一學儲存過程,自己寫了一下簡單的例子,發現了一些問題這裡記錄一下 以下是儲存過程: create

    ASP.NET MVC升級到ASP.NET Core MVC踩坑小結

    寫在前面ASP.NET Core是微軟新推出的支援跨平臺、高效能、開源的開發框架,它的優勢不必多說,因為已經說得太多了。當然,現在依然有著數量龐大的系統運行於.NET Framework上,由於有大量的Break Changes,很多專案專案團隊也不敢貿然升級,其中的考量也不全部是技術原因,更多的可能還是業務

    .net MVC使用NPOI讀取Excel模板再寫入數據

    produce clas actor 找到 讀取 粘貼 亮點 div gin   NPOI其實已經介紹的差不多了,再貼一個方便以後復制粘貼。 亮點其實是 Server.MapPath 這個東西,可以找到MVC工程下的文件夾,找路徑還是很方便的。 /// <su

    .net mvc web api 返回 json 內容過濾值為null的屬性

    .net mvc web api 返回 json 內容時,好多屬性為null的沒必要下發。 下面看下怎麼過濾值為null的屬性 1.響應內容(過濾前) {"msg":"初始化成功!","code"

    【開源分享:入門到精通ASP.NET MVC+EF6+Bootstrap】從這裏開始一起搭框架(1)開篇介紹

    strong src 擁有 ckeditor 開發 技術分享 mdi 控制 https 框架簡介 這幾年一直在做ASP.NET開發,幾年前做項目都是老老實實一行行的寫代碼,後來發現那些高手基本都會有自己積累起來的代碼庫,現在稱之為開發框架,基礎代碼不用再去堆,

    Asp.Net MVC 5使用Identity之簡單的註冊和登陸

    stat bar del info var asp.net rem boot manage 由於.Net MVC 5登陸和註冊方式有很多種,但是Identity方式去實現或許會更簡單更容易理解 首先新建一個項目 其次如下選擇Empty和MVC的選項 然後打開NuGe

    ASP.NET MVC Identity 兩個多個連接字符串問題解決一例

    fail conn init led user asp identity 字符串 initial 按照ASP.NET MVC Identity建立了一個用戶權限管理模塊,由於還要加自己已有的數據庫,所以建立了一個實體模型,建立了之後,發現登錄不了: 一直顯示“Login i

    從零開始學習ASP.NET MVC 1.0 (一) 開天闢地入門

    《從零開始學習ASP.NET MVC 1.0》 文章導航 一.摘要 隨著ASP.NET MVC 1.0版本的正式釋出, 我將本系列文章也更新到了1.0, 對於已經發表的文章我都會根據1.0版本重新編輯. 希望本系列文章能打給大家幫助. 二.前言 ASP.NET MVC是微軟官方提供的開源M

    從零開始學習 ASP.NET MVC 1.0 (五) ViewEngine 深入解析與應用例項

    《從零開始學習ASP.NET MVC 1.0》 文章導航 一.摘要 本文講解ViewEngine的作用, 並且深入解析了實現ViewEngine相關的所有介面和類, 最後演示瞭如何開發一個自定義的ViewEngine. 本系列文章已經全部更新為ASP.NET MVC 1.0版本.希望大家多多支援!

    從零開始學習 ASP.NET MVC 1.0 (四) View/Model 全解

    《從零開始學習ASP.NET MVC 1.0》 文章導航 一.摘要 本文講解在Action中向View傳遞Model的幾種方式.以及View獲取Model以後如何編寫顯示邏輯.還詳細的介紹了ASP.NET MVC框架提供的Html Helper類的使用及如何為Html Helper類新增自定義擴充

    從零開始學習 ASP.NET MVC 1.0 (三) Controller/Action 深入解析與應用例項

    《從零開始學習ASP.NET MVC 1.0》 文章導航 一.摘要 一個Url請求經過了Routing處理後會呼叫Controller的Action方法. 中間的過程是怎樣的? Action方法中返回ActionResult物件後,如何到達View的? 本文將講解Controller的基本用法, 

    從零開始學習 ASP.NET MVC 1.0 (二) 識別URL的Routing元件

    《從零開始學習ASP.NET MVC 1.0》 文章導航 一.摘要 本篇文章從基礎到深入的介紹ASP.NET MVC中的Routing元件. Routing翻譯過來是"路由選擇", 負責ASP.NET MVC的第一個工作:識別URL, 將一個Url請求"路由"給Controller. 二.

    【無私分享:從入門到精通ASP.NET MVC】從0開始一起搭框架、做專案(7.2) 模組管理模組的新增、修改、刪除

    索引 簡述 今天我們來做模組管理的 新增、修改、刪除 專案準備 我們用的工具是:VS 2013 + SqlServer 2012 + IIS7.5 希望大家對ASP.NET MVC有一個初步的理解,理論性的東西我們不做過多解釋,有些地方不理解也沒關係,會用就行了,用的多了,用的久了,自然就理解了

    【無私分享:從入門到精通ASP.NET MVC】從0開始一起搭框架、做專案(5.3) 登入功能的實現豐富資料表、建立關聯

    1 USE [wkmvc_db] 2 GO 3 /****** Object: Table [dbo].[SYS_CODE] Script Date: 2016/5/17 9:30:01 ******/ 4 SET ANSI_NULLS ON 5 GO 6 SET