untiy,ef,jwt,filter和webapi

1,DbFirst创建EF数据模型(Models,Dto。通过Dto我们实现了表现层与Model之间的解耦。)

2,创建和实现数据访问层IDAL、业务逻辑层IBLL。

①创建IDAL层:

IBaseService:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Eims.IDAL
{
    public interface IBaseService<T> : IDisposable where T : class
    {
        Task<int> InsertAsync(T model, bool saved = true);
        Task<int> UpdateAsync(T model, bool saved = true);
        Task<int> DeleteAsync(int id, bool saved = true);
        Task<int> Save();
        IQueryable<T> GetAll();
    }
}

IStaffService:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Eims.Models;

namespace Eims.IDAL
{
    public interface IStaffService : IBaseService<Staff>
    {
    }
}

②创建DAL层,他们实现IDAL

BaseService:

using Eims.IDAL;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Eims.Models;
using System.Data.Entity;

namespace Eims.DAL
{
    public class BaseService<T> : IBaseService<T>, IDisposable where T : class, new()
    {
        private readonly EimsContext _db;

        public BaseService(EimsContext db)
        {
            _db = db;
        }

        public async Task<int> InsertAsync(T model, bool saved = true)
        {
            _db.Set<T>().Add(model);
            if (saved) return await Save();
            else return -1;//-2,-1,0,>0
        }

        public async Task<int> DeleteAsync(int id, bool saved = true)
        {
            _db.Configuration.ValidateOnSaveEnabled = false;
            var t=_db.Set<T>().Find(id);
            _db.Entry(t).State = EntityState.Deleted;
            if (saved) return await Save();
            else return -1;
            
        }

        public async Task<int> UpdateAsync(T model, bool saved = true)
        {
            _db.Configuration.ValidateOnSaveEnabled = false;
            _db.Entry(model).State = EntityState.Modified;
            if (saved) return await Save();
            else return -1;
        }

        public async Task<int> Save()
        {
            try
            {
                int i = await _db.SaveChangesAsync();
                _db.Configuration.ValidateOnSaveEnabled = true;
                return i;
            }
            catch { return -2; }
        }

        public IQueryable<T> GetAll()
        {
            return _db.Set<T>().AsNoTracking();
        }

        public void Dispose()
        {
            throw new NotImplementedException();
        }
    }
}

StaffService:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Eims.IDAL;
using Eims.Models;

namespace Eims.DAL
{
    public class StaffService : BaseService<Staff>, IStaffService
    {
        public StaffService()
            : base(new EimsContext())
        {
        }
    }
}

③创建IBLL层

IBaseManager

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Eims.Dto;

namespace Eims.IBLL
{
    public interface IBaseManager<T>
    {
        Task<List<T>> _getPage(T model, int pageSize = 10, int pageIndex = 0);
        Task<List<T>> _getAll();
        Task<int> _add(T model);
        Task<int> _edit(T model);
        Task<int> _del(int id);
    }
}

IStaffManager:

using Eims.Dto;
using System.Threading.Tasks;

namespace Eims.IBLL
{
    public interface IStaffManager : IBaseManager<StaffDto>
    {
        Task<AccountDto> _login(int id, string password);
    }
}

④创建BLL层,他们实现IBLL

StaffManager:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Eims.IBLL;
using Eims.Dto;
using Eims.IDAL;
using Unity;
using System.Data.Entity;

namespace Eims.BLL
{
    public class StaffManager : IStaffManager
    {
        [Dependency]
        public IStaffService staffService { get; set; }

        public async Task<int> _add(StaffDto staffDto)
        {
            return await staffService.InsertAsync(new Models.Staff() 
            {
                Address=staffDto.Address,
                Birthday=staffDto.Birthday,
                EducationLevel=staffDto.EducationLevel,
                Email=staffDto.Email,
                GraduatedSchool=staffDto.GraduatedSchool,
                HealthStatus=staffDto.HealthStatus,
                Hometown=staffDto.Hometown,
                Id=staffDto.Id,
                IDcard=staffDto.IDcard,
                MaritalStatus=staffDto.MaritalStatus,
                Name=staffDto.Name,
                Password=staffDto.Password,
                Phone=staffDto.Phone,
                RoleId=staffDto.RoleId,
                PoliticalStatus=staffDto.PoliticalStatus,
                Sex=staffDto.Sex,
                WorkingState=staffDto.WorkingState
            });
        }

        public async Task<int> _del(int id)
        {
            return await staffService.DeleteAsync(id);
        }

        public async Task<int> _edit(StaffDto staffDto)
        {
            return await staffService.UpdateAsync(new Models.Staff()
            {
                Address = staffDto.Address,
                Birthday = staffDto.Birthday,
                EducationLevel = staffDto.EducationLevel,
                Email = staffDto.Email,
                GraduatedSchool = staffDto.GraduatedSchool,
                HealthStatus = staffDto.HealthStatus,
                Hometown = staffDto.Hometown,
                Id = staffDto.Id,
                IDcard = staffDto.IDcard,
                MaritalStatus = staffDto.MaritalStatus,
                Name = staffDto.Name,
                Password = staffDto.Password,
                Phone = staffDto.Phone,
                RoleId = staffDto.RoleId,
                PoliticalStatus = staffDto.PoliticalStatus,
                Sex = staffDto.Sex,
                WorkingState = staffDto.WorkingState
            });
        }

        public async Task<List<StaffDto>> _getAll()
        {
            return await staffService.GetAll().Select(m=> new StaffDto()
            {
                Address = m.Address,
                Birthday = m.Birthday,
                EducationLevel = m.EducationLevel,
                Email = m.Email,
                GraduatedSchool = m.GraduatedSchool,
                HealthStatus = m.HealthStatus,
                Hometown = m.Hometown,
                Id = m.Id,
                IDcard = m.IDcard,
                MaritalStatus = m.MaritalStatus,
                Name = m.Name,
                Password = m.Password,
                Phone = m.Phone,
                RoleId = m.RoleId,
                PoliticalStatus = m.PoliticalStatus,
                Sex = m.Sex,
                WorkingState = m.WorkingState
            }).ToListAsync();
        }

        public async Task<List<StaffDto>> _getPage(StaffDto model, int pageSize, int pageIndex)
        {
            return await staffService.GetAll().Where(m => m.Id == model.Id || m.Name == model.Name || m.IDcard == model.IDcard).OrderBy(m => m.Id).Skip(pageSize * pageIndex).Take(pageSize).Select(m => new StaffDto()
            {
                Address = m.Address,
                Birthday = m.Birthday,
                EducationLevel = m.EducationLevel,
                Email = m.Email,
                GraduatedSchool = m.GraduatedSchool,
                HealthStatus = m.HealthStatus,
                Hometown = m.Hometown,
                Id = m.Id,
                IDcard = m.IDcard,
                MaritalStatus = m.MaritalStatus,
                Name = m.Name,
                Password = m.Password,
                Phone = m.Phone,
                RoleId = m.RoleId,
                PoliticalStatus = m.PoliticalStatus,
                Sex = m.Sex,
                WorkingState = m.WorkingState
            }).ToListAsync();
        }

        public async Task<AccountDto> Login(int id, string password)
        {
            var staff = staffService.GetAll().FirstOrDefault(m => m.Id == id && m.Password == password);
            if (staff == null) return null;
            return new AccountDto() 
            {
                Id=staff.Id,
                RoleId=staff.RoleId,
            };
        }
    }
}

3,创建 依赖关系 容器。这是为了在多个项目中重复使用,比如WebMVC和WebApi。

using Eims.BLL;
using Eims.DAL;
using Eims.IBLL;
using Eims.IDAL;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Unity;

namespace Eims.Core
{

    public partial class RegisterTypes
    {
        /// <summary>
        /// Registers the type mappings with the Unity container.
        /// </summary>
        /// <param name="container">The unity container to configure.</param>
        /// <remarks>
        /// There is no need to register concrete types such as controllers or
        /// API controllers (unless you want to change the defaults), as Unity
        /// allows resolving a concrete type even if it was not previously
        /// registered.
        /// </remarks>
        public static void Partial(IUnityContainer container)
        {
            container.RegisterType<IAttendanceManager, AttendanceManager>();
            container.RegisterType<IAttendanceService, AttendanceService>();
            container.RegisterType<IArticleManager, ArticleManager>();
            container.RegisterType<IArticleService, ArticleService>();
            container.RegisterType<IStaffManager, StaffManager>();
            container.RegisterType<IStaffService, StaffService>();
            container.RegisterType<ISuggestManager, SuggestManager>();
            container.RegisterType<ISuggestService, SuggestService>();
            container.RegisterType<IWageManager, WageManager>();
            container.RegisterType<IWageService, WageService>();
        }
    }
}

4,创建项目Apps.WebApi

5,jwt解密和加密工具类。

token:

  • header (base64后的)

  • payload (base64后的)

  • signature:它由header、payload、secret加密生成。不知道secret就无法解密。

验证过程:用户登陆后服务器向客户端签发token,客户端请求服务器携带token,服务器进行通过解密token进行身份校验。

服务器解密后可将解密信息(例如:权限Id)存入上下文供Controller使用。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using JWT;
using JWT.Algorithms;
using JWT.Serializers;
using JWT.Exceptions;
using Newtonsoft.Json;

namespace Eims.WebApi.Core
{
    public class JwtTools
    {
        public static string Key { get; set; } = "wangzhenyang";


        public static string Encode(Dictionary<string, object> payload, string key = null)
        {
            if (string.IsNullOrEmpty(key)) key = Key;
            payload.Add("timeout", DateTime.Now.AddDays(1));

            IJsonSerializer jsonSerializer = new JsonNetSerializer();//json序列化
            IBase64UrlEncoder urlEncoder = new JwtBase64UrlEncoder();//base64加密编码器
            IJwtAlgorithm algorithm = new HMACSHA256Algorithm();//算法
            IJwtEncoder jwtEncoder = new JwtEncoder(algorithm, jsonSerializer, urlEncoder);
            return jwtEncoder.Encode(payload, key);
        }

        public static Dictionary<string, object> Decode(string code, string key = null)
        {
            if (string.IsNullOrEmpty(key)) key = Key;
            try
            {
                IJsonSerializer jsonSerializer = new JsonNetSerializer();//json序列化
                IDateTimeProvider provider = new UtcDateTimeProvider();//日期提供者
                IJwtValidator jwtValidator = new JwtValidator(jsonSerializer, provider);//验证器
                IBase64UrlEncoder urlEncoder = new JwtBase64UrlEncoder();//base64加密编码器
                IJwtAlgorithm algorithm = new HMACSHA256Algorithm();//算法
                IJwtDecoder jwtDecoder = new JwtDecoder(jsonSerializer, jwtValidator, urlEncoder, algorithm);
                var json = jwtDecoder.Decode(code, key, true);
                var result = JsonConvert.DeserializeObject<Dictionary<string, object>>(json);

                if ((DateTime)result["timeout"] < DateTime.Now)
                    throw new Exception("jwtstring已经过期,必须重新登陆");
                result.Remove("timeout");
                return result;
            }
            catch (TokenExpiredException) { throw; }
        }
    }
}

6,在Api项目内,创建过滤器类MainAuthAttribute,他实现接口Attribute, IAuthorizationFilter。

注意:①在控制器上添加注释[MainAuth]后,会在运行该控制器时调用Filter

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using System.Web;
using System.Web.Http.Filters;
using Eims.WebApi.Core;
using System.Net.Http;
using System.Web.Http.Controllers;
using System.Web.Http;
using Eims.WebApi.Models.Auth;

namespace Eims.WebApi.Filter
{
    public class MainAuthAttribute : Attribute, IAuthorizationFilter
    {
        public bool RoleValidation { get; set; } = false;//是否开启权限验证

        public bool AllowMultiple => throw new NotImplementedException();

        public async Task<HttpResponseMessage> ExecuteAuthorizationFilterAsync(HttpActionContext actionContext, CancellationToken cancellationToken, Func<Task<HttpResponseMessage>> continuation)
        {
            //获取request->headers->token
            IEnumerable<string> headers;
            if (actionContext.Request.Headers.TryGetValues("token", out headers))
            {
                //解密token为键值对
                Dictionary<string, object> keyValues = JwtTools.Decode(headers.First());
                int id = Convert.ToInt32(keyValues["Id"].ToString());
                int roleId = Convert.ToInt32(keyValues["RoleId"].ToString());
                //将解密内容存入user->identiey
                (actionContext.ControllerContext.Controller as ApiController).User = new ApplicationUser(id, roleId);
                //验证类别
                if (RoleValidation == false || roleId == 0)
                {
                    return await continuation();
                }
            }
            return new HttpResponseMessage(System.Net.HttpStatusCode.Unauthorized);
        }
    }
}

7,WebApi全局的依赖注入

8,可以在项目中创建BaseController通用类

9,测试类TestController

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;
using Unity;
using Eims.Dto;
using Eims.IBLL;
using System.Threading.Tasks;
using System.Web.Http.Cors;
using Eims.WebApi.Models;
using Eims.WebApi.Filter;
using Eims.WebApi.Models.Auth;
using Eims.WebApi.Core;

/*
 *  测试api
 */


namespace Eims.WebApi.Controllers
{
    [RoutePrefix(prefix: "api/test")]
    [EnableCors(origins: "*", headers: "*", methods: "*")]
    public class TestController : ApiController
    {
        [Dependency]
        public IAttendanceManager attendanceManager { get; set; }
        [Dependency]
        public IArticleManager articleManager { get; set; }
        [Dependency]
        public IWageManager wageManager { get; set; }
        [Dependency]
        public ISuggestManager suggestManager { get; set; }
        [Dependency]
        public IStaffManager staffManager { get; set; }

        [Route(""), HttpGet]
        public async Task<IHttpActionResult> Test()
        {

            /*//_add
            string str = "@@@@@@@@@@";
            string result = "";
            result += await attendanceManager._add(new AttendanceDto()
            {
                Id = 1,
                Remarks = str
            });
            result += await articleManager._add(new ArticleDto()
            {
                Title = str
            });
            result += await wageManager._add(new WageDto()
            {
                Remark = str
            });
            result += await suggestManager._add(new SuggestDto()
            {
                Content = str
            });
            result += await staffManager._add(new StaffDto()
            {
                Id = 5555,
                Name = str
            });
            return Ok(result); */



            /*//_getPage
            return Ok(await attendanceManager._getPage(new AttendanceDto()
            {
                Name = "name"
            }));*/



            /*//_del
            return Ok(await staffManager._del(5555));*/




            //_edit
            return Ok(await suggestManager._edit(new SuggestDto()
            {
                Id = 2,
                Content="工资太高,1亿就可🙆‍",
                SuggestTime=DateTime.Now,
                Title = "工资问题",
                StaffId=0
            }));

        }




        [HttpPost, Route("login")]
        public async Task<IHttpActionResult> login(LoginViewModel model)
        {
            if (ModelState.IsValid)
            {
                AccountDto user = await staffManager.Login(model.Id, model.Password);
                if (user == null)
                    return Ok(new ResponseData()
                    {
                        Code = 0,
                        ErrorMessage = "密码错误或账号不存在"
                    });
                return Ok(new ResponseData()
                {
                    Data = JwtTools.Encode(new Dictionary<string, object>()
                    {
                        { "Id",user.Id },
                        { "RoleId",user.RoleId }
                    })
                });
            }
            else
            {
                return Ok(new ResponseData() { Code = 0, ErrorMessage = "账号密码输入有误" });
            }
        }

        [MainAuth(RoleValidation = true)]
        [HttpGet, Route("getAll")]
        public IHttpActionResult getAll()
        {
            UserIdentity my = ((UserIdentity)User.Identity);
            if (my.RoleId != 0)
                return Ok(new ResponseData()
                {
                    Code = 0,
                    ErrorMessage = "你没有管理员权限"
                });
            return Ok(my);
        }


        [HttpPost]
        public Dictionary<string, Object> parm(AccountDto model, string str, int i)
        {
            return new Dictionary<string, object>()
            {
                { "2",model }
            };
        }

    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值