asp.net core2.1+EFCore + MVC開發留言管理項目實戰(二)


  承接上篇,這里主要介紹如何實現cookie驗證登錄以及簡單的BaseRepository編寫。廢話不多說,下面進入主題。

  一、cookie驗證登錄

  1、startup的ConfigurationServices方法加上如下代碼:

  同樣startup的Configure方法加上如下代碼:

  2、繼承AuthorizeAttribute標簽並實現IAuthorizationFilter接口,代碼如下:

using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Abstractions;
using Microsoft.AspNetCore.Mvc.Filters;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace Ye.BoardMessage.WebApp.Models
{
    /// <summary>
    /// 跳過檢查屬性
    /// </summary>
    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
    public sealed class SkipUserAuthorizeAttribute : Attribute, IFilterMetadata
    {
    }

    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = true)]
    public class UserAuthorizeAttribute : AuthorizeAttribute, IAuthorizationFilter
    {
        public UserAuthorizeAttribute()
        {
            this.AuthenticationSchemes = CookieAuthenticationDefaults.AuthenticationScheme;
        }
        public virtual void OnAuthorization(AuthorizationFilterContext filterContext)
        {
            var authenticate = filterContext.HttpContext.AuthenticateAsync(CookieAuthenticationDefaults.AuthenticationScheme);
            if (authenticate.Result.Succeeded || this.SkipUserAuthorize(filterContext.ActionDescriptor))
            {
                return;
            }
            HttpRequest httpRequest = filterContext.HttpContext.Request;
            string url = "/Account/Login";
            url = string.Concat(url, "?returnUrl=", httpRequest.Path);
            RedirectResult redirectResult = new RedirectResult(url);
            filterContext.Result = redirectResult;
            return;
        }

        protected virtual bool SkipUserAuthorize(ActionDescriptor actionDescriptor)
        {
            bool skipAuthorize = actionDescriptor.FilterDescriptors.Where(a => a.Filter is SkipUserAuthorizeAttribute).Any();
            if (skipAuthorize)
            {
                return true;
            }
            return false;
        }
    }
}
View Code

  3、驗證,代碼如下:

[HttpPost]
        [ValidateAntiForgeryToken]
        public async Task<IActionResult> Login(string email, string password)
        {
            password = MD5Encrypted(password);
            var serviceResponse = service.Login(email, password);
            if (!serviceResponse.IsSuccess)
            {
                return Content("用戶名或者密碼錯誤“);
            }
            var claims = new List<Claim>
                {
                    new Claim(ClaimTypes.Name, serviceResponse.Result.Email),
                    new Claim("FullName", serviceResponse.Result.FullName),
                    new Claim(ClaimTypes.Role, "Administrator"),
                };

            var claimsIdentity = new ClaimsIdentity(
                claims, CookieAuthenticationDefaults.AuthenticationScheme);

            await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme,
                 new ClaimsPrincipal(claimsIdentity));

            return LocalRedirect(Request.Query["ReturnUrl"].ToString() ?? "/");
        }
View Code

  4、退出,代碼如下:

[Models.UserAuthorize]
        [HttpGet]
        public async Task<IActionResult> Logout()
        {
            await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
            return LocalRedirect("/Account/Login");
        }

   說明:以上代碼的實現參考了  《這個大神的博客》

  二、BaseRepository實現

  封裝了基本的增刪改查方法,可以與其他倉儲共用。此外,有個比較大的缺陷,沒有實現事務方面的UnitOfWork,對這個感興趣的看官可以自行實現,亦可以參考ABP的EF實現,這里有部分代碼也是參考ABP的實現的。好了,廢話不多說,上代碼:

  接口:

using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.ChangeTracking;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;

namespace Ye.BoardMessage.Entity.IRepositories
{
    public interface IBaseRepository<TEntity,TKey> where TEntity : class,new()
    {
        bool Insert(TEntity entity);

        Task<EntityEntry<TEntity>> InsertAsync(TEntity entity);

        TEntity Update(TEntity entity);

        Task<TEntity> UpdateAsync(TEntity entity);

        void Delete(TEntity entity);

        void Delete(IEnumerable<TEntity> entities);

        TEntity First();

        Task<TEntity> FirstAsync();

        TEntity First(Expression<Func<TEntity, bool>> where);

        Task<TEntity> FirstAsync(Expression<Func<TEntity, bool>> where);

        IQueryable<TEntity> Query();

        IQueryable<TEntity> Query(Expression<Func<TEntity,bool>> where);

        DbContext DbContext { get; }

        int SaveChanged();
    }
}
View Code

  實現:

using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.ChangeTracking;
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;
using Ye.BoardMessage.Entity.IRepositories;
using System.Linq;

namespace Ye.BoardMessage.Repository
{
    public class BaseRepository<TEntity, TKey> : IBaseRepository<TEntity, TKey> where TEntity : class, new()
    {
        private DbContext _context;

        protected BaseRepository(DbContext context)
        {
            this._context = context;
        }

        public bool Insert(TEntity entity)
        {
            if (null == entity)
                return false;
            Table.Add(entity);
            return true;
        }

        public Task<EntityEntry<TEntity>> InsertAsync(TEntity entity)
        {
            return Table.AddAsync(entity);
        }

        public TEntity Update(TEntity entity)
        {
            AttachIfNot(entity);
            _context.Entry(entity).State = EntityState.Modified;
            return entity;
        }

        public Task<TEntity> UpdateAsync(TEntity entity)
        {
            return Task.FromResult(Update(entity));
        }

        public void Delete(TEntity entity)
        {
            AttachIfNot(entity);
            Table.Remove(entity);
        }

        public void Delete(IEnumerable<TEntity> entities)
        {
            foreach (TEntity item in entities)
                Delete(item);
        }

        public TEntity First()
        {
            return Table.First();
        }

        public Task<TEntity> FirstAsync()
        {
            return Table.FirstAsync();
        }

        public TEntity First(Expression<Func<TEntity, bool>> where)
        {
            if (null == where)
                return null;
            return Table.First(where);
        }

        public Task<TEntity> FirstAsync(Expression<Func<TEntity, bool>> where)
        {
            if (null == where)
                return null;
            return Table.FirstAsync(where);
        }

        public DbContext DbContext => _context;

        public DbSet<TEntity> Table
        {
            get
            {
                return _context.Set<TEntity>();
            }
        }

        public IQueryable<TEntity> Query()
        {
            return Table.AsQueryable<TEntity>();
        }

        public IQueryable<TEntity> Query(Expression<Func<TEntity, bool>> where)
        {
            if (null != where)
                return Table.Where(where);
            else
                return Query();
        }

        protected virtual void AttachIfNot(TEntity entity)
        {
            if (!Table.Local.Contains(entity))
            {
                Table.Attach(entity);
            }
        }

        public int SaveChanged()
        {
            return _context.SaveChanges();
        }
    }
}
View Code

  三、總結

  EFCore的使用與EntityFramework並無多大區別;asp.net core 安全方面集成的東西很多,光是官方文檔就占據了上十個篇幅來介紹,在這方面還需要下苦工來研究,可謂 ”路漫漫其修遠兮“ 。這里稍微提下,前端模板是使用開源的前端模板《SB-admin》,一款bootstrap風格的模板。下面上幾個圖片看看效果。

  1、登錄

  2、首頁

  

  3、列表頁面

    

  至此,這個系列已經基本完畢,下篇將簡單介紹下如何安裝以及使用(網上參考資料太多,本人主要是整理下本人覺得有用的博文)。


免責聲明!

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



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