• ASP.NET Core 个人新闻项目


    # 1.打开Microsoft Visual Studio 2019软件新建ASP.NET Core Web API(.NET 5.0)项目

    # 2.数据库设计

    新闻表
    ID
    新闻标题
    新闻内容
    创建时间
    新闻类型ID
    浏览量
    点赞量
    作者ID
    ```

    新闻类型表
    ID
    类型名
    ```

    作者表
    ID
    姓名
    账号
    密码 MD5
    ```

    # 3.添加表的模型

    操作:新建MyNews.Model类库
    添加NuGet程序包:SqlSugarCore(官网:https://www.donet5.com/home/doc)

    (1)新建BaseId类(公共类)
        using SqlSugar;

        namespace MyNews.Model
        {
            public class BaseId
            {
                //自增主键Id
                [SugarColumn(IsIdentity = true, IsPrimaryKey = true)]
                public int Id { get; set; }
            }
        }

    (2)新建News类(新闻)
        using System;
        using SqlSugar;

        namespace MyNews.Model
        {
            public class News : BaseId
            {
                //标题
                [SugarColumn(ColumnDataType = "nvarchar(50)")]
                public string Title { get; set; }

                //内容
                [SugarColumn(ColumnDataType = "text")]
                public string Content { get; set; }

                //创建时间
                public DateTime CreateTime { get; set; }

                //新闻类型Id
                public int TypeId { get; set; }

                //浏览量
                public int BrowseCount { get; set; }

                //点赞量
                public int LikeCount { get; set; }

                //作者Id
                public int WriterId { get; set; }

                #region ORM不处理该列(不映射到数据库)
                [SugarColumn(IsIgnore = true)]
                public NewsType NewsType { get; set; }

                [SugarColumn(IsIgnore = true)]
                public Writer Writer { get; set; }
                #endregion
            }
        }

    (3)新建NewsType类(新闻类型)
        using SqlSugar;

        namespace MyNews.Model
        {
            public class NewsType : BaseId
            {
                //新闻类型名
                [SugarColumn(ColumnDataType ="nvarchar(20)")]
                public string Name { get; set; }
            }
        }

    (5)新建Writer类(作者)
        using SqlSugar;

        namespace MyNews.Model
        {
            public class Writer : BaseId
            {
                //作者姓名
                [SugarColumn(ColumnDataType ="nvarchar(20)")]
                public string Name { get; set; }

                //账号
                [SugarColumn(ColumnDataType ="nvarchar(20)")]
                public string UserName { get; set; }

                //密码
                [SugarColumn(ColumnDataType ="nvarchar(100)")]
                public string UserPwd { get; set; }
            }
        }
    ```

    # 3.架构设计

    仓储层(Repository):用于数据的增删改查
    服务层(Service):调用仓储层

    (1)新建仓储层
    操作:新建Repository文件夹->新建MyNews.IRepository类库(接口)和MyNews.Repository类库(实现接口)

    ①在MyNews.IRepository类库中新建IBaseRepository类(主要是增删改查方法)
    添加NuGet程序包:SqlSugarCore(官网:https://www.donet5.com/home/doc)
        using SqlSugar;
        using System;
        using System.Collections.Generic;
        using System.Linq;
        using System.Linq.Expressions;
        using System.Text;
        using System.Threading.Tasks;

        namespace MyNews.IRepository
        {
            public interface IBaseRepository<T> where T : class, new()
            {
                /// <summary>
                /// 增加
                /// </summary>
                /// <param name="entity">传入的类</param>
                /// <returns></returns>
                Task<bool> CreateAsync(T entity);

                /// <summary>
                /// 删除
                /// </summary>
                /// <param name="id"></param>
                /// <returns></returns>
                Task<bool> DeleteAsync(int id);

                /// <summary>
                /// 修改
                /// </summary>
                /// <param name="entity">传入的类</param>
                /// <returns></returns>
                Task<bool> EditAsync(T entity);

                /// <summary>
                /// 查询单条数据
                /// </summary>
                /// <param name="id"></param>
                /// <returns></returns>
                Task<T> FindAsync(int id);

                /// <summary>
                /// 查询单条数据(自定义)
                /// </summary>
                /// <param name="func"></param>
                /// <returns></returns>
                Task<T> FindAsync(Expression<Func<T, bool>> func);

                /// <summary>
                /// 查询全部数据
                /// </summary>
                /// <returns></returns>
                Task<List<T>> QueryAsync();

                /// <summary>
                /// 自定义条件查询
                /// </summary>
                /// <param name="func"></param>
                /// <returns></returns>
                Task<List<T>> QueryAsync(Expression<Func<T, bool>> func);

                /// <summary>
                /// 分页查询
                /// </summary>
                /// <param name="page"></param>
                /// <param name="size"></param>
                /// <param name="total"></param>
                /// <returns></returns>
                Task<List<T>> QueryAsync(int page, int size, RefAsync<int> total);

                /// <summary>
                /// 分页查询(自定义)
                /// </summary>
                /// <param name="func"></param>
                /// <param name="page"></param>
                /// <param name="size"></param>
                /// <param name="total"></param>
                /// <returns></returns>
                Task<List<T>> QueryAsync(Expression<Func<T, bool>> func, int page, int size, RefAsync<int> total);
            }
        }

    ②在MyNews.Repository类库中新建BaseRepository类
    添加NuGet程序包:SqlSugarCore(官网:https://www.donet5.com/home/doc)
    添加NuGet程序包:SqlSugar.IOC(参考:https://www.donet5.com/Doc/10)

    前提:在MyNews.WebApi项目(也要引用SqlSugar程序包)Startup类中注入SqlSugarIOC
        services.AddSqlSugar(new IocConfig()
        {
            //ConfigId="db01"  多租户用到
            ConnectionString =this.Configuration["SqlConn"],
            DbType = IocDbType.SqlServer,
            IsAutoCloseConnection = true//自动释放
        });
    这里把数据库连接字符串放在了appsetting.json文件里:  "SqlConn": "Server=(localdb)\\MSSQLLocalDB;Database=MyNewsDB;Trusted_Connection=True;"
        using MyNews.IRepository;
        using MyNews.Model;
        using SqlSugar;
        using SqlSugar.IOC;
        using System;
        using System.Collections.Generic;
        using System.Linq;
        using System.Linq.Expressions;
        using System.Text;
        using System.Threading.Tasks;

        namespace MyNews.Repository
        {
            public class BaseRepository<T> : SimpleClient<T>, IBaseRepository<T> where T : class, new()
            {
                public BaseRepository(ISqlSugarClient context = null) : base(context)//注意这里要有默认值等于null
                {
                    base.Context = DbScoped.SugarScope;
                    #region 创建数据库和表
                    //DbScoped.Sugar上下文共享 除了SugarIoc 你还可以用SqlSugarScope单例模式实现
                    //base.Context.DbMaintenance.CreateDatabase();//创建数据库
                    //base.Context.CodeFirst.SetStringDefaultLength(200).InitTables(typeof(News), typeof(NewsType), typeof(Writer));//这样一个表就能成功创建了
                    #endregion
                }

                /// <summary>
                /// 增加
                /// </summary>
                /// <param name="entity">传入的类</param>
                /// <returns></returns>
                public async Task<bool> CreateAsync(T entity)
                {
                    return await base.InsertAsync(entity);
                }

                /// <summary>
                /// 删除
                /// </summary>
                /// <param name="id"></param>
                /// <returns></returns>
                public async Task<bool> DeleteAsync(int id)
                {
                    return await base.DeleteByIdAsync(id);
                }

                /// <summary>
                /// 修改
                /// </summary>
                /// <param name="entity">传入的类</param>
                /// <returns></returns>
                public async Task<bool> EditAsync(T entity)
                {
                    return await base.UpdateAsync(entity);
                }

                /// <summary>
                /// 查询单条数据
                /// </summary>
                /// <param name="id"></param>
                /// <returns></returns>
                public virtual async Task<T> FindAsync(int id)
                {
                    return await base.GetByIdAsync(id);
                }


                /// <summary>
                /// 查询单条数据(自定义)
                /// </summary>
                /// <param name="func"></param>
                /// <returns></returns>
                public virtual async Task<T> FindAsync(Expression<Func<T, bool>> func)
                {
                    return await base.GetSingleAsync(func);
                }

                /// <summary>
                /// 查询全部数据
                /// </summary>
                /// <returns></returns>
                public virtual async Task<List<T>> QueryAsync()
                {
                    return await base.GetListAsync();
                }

                /// <summary>
                /// 自定义条件查询
                /// </summary>
                /// <param name="func"></param>
                /// <returns></returns>
                public virtual async Task<List<T>> QueryAsync(Expression<Func<T, bool>> func)
                {
                    return await base.GetListAsync(func);
                }

                /// <summary>
                /// 分页
                /// </summary>
                /// <param name="page"></param>
                /// <param name="size"></param>
                /// <param name="total"></param>
                /// <returns></returns>
                public virtual async Task<List<T>> QueryAsync(int page, int size, RefAsync<int> total)
                {
                    return await base.Context.Queryable<T>().ToPageListAsync(page, size, total);
                }

                /// <summary>
                /// 自定义条件分页查询
                /// </summary>
                /// <param name="func"></param>
                /// <param name="page"></param>
                /// <param name="size"></param>
                /// <param name="total"></param>
                /// <returns></returns>
                public virtual async Task<List<T>> QueryAsync(Expression<Func<T, bool>> func, int page, int size, RefAsync<int> total)
                {
                    return await base.Context.Queryable<T>().Where(func).ToPageListAsync(page, size, total);
                }
            }
        }


    ③在MyNews.IRepository类库中新建INewsRepository、INewsTypeRepository、IWriterRepository接口分别继承IBaseRepository接口
        using MyNews.Model;
        using System;
        using System.Collections.Generic;
        using System.Linq;
        using System.Text;
        using System.Threading.Tasks;

        namespace MyNews.IRepository
        {
            public interface INewsRepository : IBaseRepository<News>
            {
            }
        }

    ④在MyNews.Repository类库中新建NewsRepository、NewsTpyeRepository、WriterRepository类分别继承BaseRepository类,并实现对应接口
        using MyNews.IRepository;
        using MyNews.Model;
        using System;
        using System.Collections.Generic;
        using System.Linq;
        using System.Text;
        using System.Threading.Tasks;

        namespace MyNews.Repository
        {
            public class NewsRepository : BaseRepository<News>, INewsRepository
            {
            }
        }

    (2)新建服务层
    操作:新建Service文件夹->新建MyNews.IService类库(接口)和MyNews.Service类库(实现接口)

    ①在MyNews.IService类库中新建IBaseService类(主要是增删改查方法)
    添加NuGet程序包:SqlSugarCore(官网:https://www.donet5.com/home/doc)
        using SqlSugar;
        using System;
        using System.Collections.Generic;
        using System.Linq;
        using System.Linq.Expressions;
        using System.Text;
        using System.Threading.Tasks;

        namespace MyNews.IService
        {
            public interface IBaseService<T> where T : class, new()
            {
                /// <summary>
                /// 增加
                /// </summary>
                /// <param name="entity">传入的类</param>
                /// <returns></returns>
                Task<bool> CreateAsync(T entity);

                /// <summary>
                /// 删除
                /// </summary>
                /// <param name="id"></param>
                /// <returns></returns>
                Task<bool> DeleteAsync(int id);

                /// <summary>
                /// 修改
                /// </summary>
                /// <param name="entity">传入的类</param>
                /// <returns></returns>
                Task<bool> EditAsync(T entity);

                /// <summary>
                /// 查询单条数据
                /// </summary>
                /// <param name="id"></param>
                /// <returns></returns>
                Task<T> FindAsync(int id);

                /// <summary>
                /// 查询单条数据(自定义)
                /// </summary>
                /// <param name="func"></param>
                /// <returns></returns>
                Task<T> FindAsync(Expression<Func<T, bool>> func);

                /// <summary>
                /// 查询全部数据
                /// </summary>
                /// <returns></returns>
                Task<List<T>> QueryAsync();

                /// <summary>
                /// 自定义条件查询
                /// </summary>
                /// <param name="func"></param>
                /// <returns></returns>
                Task<List<T>> QueryAsync(Expression<Func<T, bool>> func);

                /// <summary>
                /// 分页
                /// </summary>
                /// <param name="page"></param>
                /// <param name="size"></param>
                /// <param name="total"></param>
                /// <returns></returns>
                Task<List<T>> QueryAsync(int page, int size, RefAsync<int> total);

                /// <summary>
                /// 分页查询(自定义)
                /// </summary>
                /// <param name="func"></param>
                /// <param name="page"></param>
                /// <param name="size"></param>
                /// <param name="total"></param>
                /// <returns></returns>
                Task<List<T>> QueryAsync(Expression<Func<T, bool>> func, int page, int size, RefAsync<int> total);
            }
        }

    ②在MyNews.BaseService类库中新建BaseService类
    添加IBaseRepository项目的引用
        using MyNews.IRepository;
        using MyNews.IService;
        using SqlSugar;
        using System;
        using System.Collections.Generic;
        using System.Linq;
        using System.Linq.Expressions;
        using System.Text;
        using System.Threading.Tasks;

        namespace MyNews.Service
        {
            public class BaseService<T> : IBaseService<T> where T : class, new()
            {
                protected IBaseRepository<T> baseRepository;

                /// <summary>
                /// 增加
                /// </summary>
                /// <param name="entity">传入的类</param>
                /// <returns></returns>
                public async Task<bool> CreateAsync(T entity)
                {
                    return await baseRepository.CreateAsync(entity);
                }

                /// <summary>
                /// 删除
                /// </summary>
                /// <param name="id"></param>
                /// <returns></returns>
                public async Task<bool> DeleteAsync(int id)
                {
                    return await baseRepository.DeleteAsync(id);
                }

                /// <summary>
                /// 修改
                /// </summary>
                /// <param name="entity">传入的类</param>
                /// <returns></returns>
                public async Task<bool> EditAsync(T entity)
                {
                    return await baseRepository.EditAsync(entity);
                }

                /// <summary>
                /// 查询单条数据
                /// </summary>
                /// <param name="id"></param>
                /// <returns></returns>
                public async Task<T> FindAsync(int id)
                {
                    return await baseRepository.FindAsync(id);
                }

                /// <summary>
                /// 查询单条数据(自定义)
                /// </summary>
                /// <param name="func"></param>
                /// <returns></returns>
                public async Task<T> FindAsync(Expression<Func<T, bool>> func)
                {
                    return await baseRepository.FindAsync(func);
                }

                /// <summary>
                /// 查询全部数据
                /// </summary>
                /// <returns></returns>
                public async Task<List<T>> QueryAsync()
                {
                    return await baseRepository.QueryAsync();
                }

                /// <summary>
                /// 查询全部数据(自定义)
                /// </summary>
                /// <param name="func"></param>
                /// <returns></returns>
                public async Task<List<T>> QueryAsync(Expression<Func<T, bool>> func)
                {
                    return await baseRepository.QueryAsync(func);
                }

                /// <summary>
                /// 分页查询(自定义)
                /// </summary>
                /// <param name="page"></param>
                /// <param name="size"></param>
                /// <param name="total"></param>
                /// <returns></returns>
                public async Task<List<T>> QueryAsync(int page, int size, RefAsync<int> total)
                {
                    return await baseRepository.QueryAsync(page, size, total);
                }

                /// <summary>
                /// 分页查询(自定义)
                /// </summary>
                /// <param name="func"></param>
                /// <param name="page"></param>
                /// <param name="size"></param>
                /// <param name="total"></param>
                /// <returns></returns>
                public async Task<List<T>> QueryAsync(Expression<Func<T, bool>> func, int page, int size, RefAsync<int> total)
                {
                    return await baseRepository.QueryAsync(func,page, size, total);
                }
            }
        }

    ③在MyNews.IService类库中新建INewsService、INewsTypeService、IWriterService接口分别继承IBaseService接口
        using MyNews.Model;
        using System;
        using System.Collections.Generic;
        using System.Linq;
        using System.Text;
        using System.Threading.Tasks;

        namespace MyNews.IService
        {
            public interface INewsService : IBaseService<News>
            {
            }
        }

    ④IOC依赖注入
    在MyNews.WebApi项目(项目引用:MyNews.IRepository、MyNews.Repository、MyNews.IService、MyNews.Service)Startup类中注入IOC
    新建IOCExtend类
        public static class IOCExtend
        {
            public static IServiceCollection AddCustomIOC(this IServiceCollection services)
            {
                services.AddScoped<INewsRepository, NewsRepository>();
                services.AddScoped<INewsTypeRepository, NewsTypeRepository>();
                services.AddScoped<IWriterRepository, WriterRepository>();
                services.AddScoped<INewsService, NewsService>();
                services.AddScoped<INewsTypeService, NewsTypeService>();
                services.AddScoped<IWriterService, WriterService>();
                return services;
            }
        }
    注入
        #region IOC依赖注入
        services.AddCustomIOC();
        #endregion

    ④在MyNews.Service类库中新建NewsService、NewsTpyeService、WriterService类分别继承BaseService类,并实现对应接口
        using MyNews.IRepository;
        using MyNews.IService;
        using MyNews.Model;
        using System;
        using System.Collections.Generic;
        using System.Linq;
        using System.Text;
        using System.Threading.Tasks;

        namespace MyNews.Service
        {
            public class NewsService : BaseService<News>, INewsService
            {
                private INewsRepository newsRepository;
                public NewsService(INewsRepository newsRepository)
                {
                    base.baseRepository = newsRepository;
                    this.newsRepository = newsRepository;
                }
            }
        }

    # 5.新建数据库和表
    在MyNews.WebApi项目Controllers文件夹新建NewsControllers控制器实现News的查询,然后运行程序打开swagger进入News方法执行就可以完成新建数据库和表(方法写在仓储层)
        using Microsoft.AspNetCore.Http;
        using Microsoft.AspNetCore.Mvc;
        using MyNews.IService;
        using System;
        using System.Collections.Generic;
        using System.Linq;
        using System.Threading.Tasks;

        namespace MyNews.Controllers
        {
            [Route("api/[controller]")]
            [ApiController]
            public class NewsController : ControllerBase
            {
                private readonly INewsService newsService;
                public NewsController(INewsService newsService)
                {
                    this.newsService = newsService;
                }

                [HttpGet("News")]
                public async Task<ActionResult> GetBlogNews()
                {
                    var data = await newsService.QueryAsync();
                    return Ok(data);
                }
            }
        }

    # 6.封装API返回结果
    在MyNews.WebApi项目新建Utility文件夹->ApiResult文件夹->ApiResult类和ApiResultHelper类

    ApiResult.cs
        using System;
        using System.Collections.Generic;
        using System.Linq;
        using System.Threading.Tasks;

        namespace MyNews.WebApi.Utility.ApiResult
        {
            public class ApiResult
            {
                //状态字码
                public int Code { get; set; }

                //数据
                public dynamic Data { get; set; }

                //返回成功/错误信息
                public string Msg { get; set; }

                //数据总条数
                public int Total { get; set; }
            }
        }

    ApiResultHelper
        using SqlSugar;
        using System;
        using System.Collections.Generic;
        using System.Linq;
        using System.Threading.Tasks;

        namespace MyNews.WebApi.Utility.ApiResult
        {
            public static class ApiResultHelper
            {
                /// <summary>
                /// 成功后返回的数据
                /// </summary>
                /// <param name="data">数据</param>
                /// <returns></returns>
                public static ApiResult Success(dynamic data)
                {
                    return new ApiResult
                    {
                        Code = 200,
                        Data = data,
                        Msg = "操作成功",
                        Total = 0
                    };
                }

                /// <summary>
                /// 成功后返回的数据(分页)
                /// </summary>
                /// <param name="data">数据</param>
                /// <returns></returns>
                public static ApiResult Success(dynamic data, RefAsync<int> total)
                {
                    return new ApiResult
                    {
                        Code = 200,
                        Data = data,
                        Msg = "操作成功",
                        Total = total
                    };
                }

                /// <summary>
                /// 失败后返回的数据
                /// </summary>
                /// <param name="msg"></param>
                /// <returns></returns>
                public static ApiResult Error(string msg)
                {
                    return new ApiResult
                    {
                        Code = 500,
                        Data = null,
                        Msg = msg,
                        Total = 0
                    };
                }
            }
        }

    # 7.新闻、新闻类型、用户增删改查
    (1)新闻
        using AutoMapper;
        using Microsoft.AspNetCore.Authorization;
        using Microsoft.AspNetCore.Http;
        using Microsoft.AspNetCore.Mvc;
        using MyNews.IService;
        using MyNews.Model;
        using MyNews.Model.DTO;
        using MyNews.WebApi.Utility.ApiResult;
        using SqlSugar;
        using System;
        using System.Collections.Generic;
        using System.Linq;
        using System.Threading.Tasks;

        namespace MyNews.WebApi.Controllers
        {
            [Route("api/[controller]")]
            [ApiController]
            [Authorize]
            public class NewsController : ControllerBase
            {
                private readonly INewsService newsService;
                public NewsController(INewsService newsService)
                {
                    this.newsService = newsService;
                }

                /// <summary>
                /// 添加文章
                /// </summary>
                /// <param name="title"></param>
                /// <param name="content"></param>
                /// <returns></returns>
                [HttpPost("Create")]
                public async Task<ActionResult<ApiResult>> Create(string title, string content, int typeid)
                {
                    News news = new News
                    {
                        BrowseCount = 0,
                        Content = content,
                        LikeCount = 0,
                        CreateTime = DateTime.Now,
                        Title = title,
                        TypeId = typeid,
                        WriterId = Convert.ToInt32(this.User.FindFirst("Id").Value)
                    };
                    bool b = await newsService.CreateAsync(news);
                    if (!b)
                    {
                        return ApiResultHelper.Error("添加失败,服务器发生错误");
                    }
                    return ApiResultHelper.Success(news);
                }

                /// <summary>
                /// 删除新闻
                /// </summary>
                /// <param name="id"></param>
                /// <returns></returns>

                [HttpDelete("Delete")]
                public async Task<ActionResult<ApiResult>> Delete(int id)
                {
                    bool b = await newsService.DeleteAsync(id);
                    if (!b)
                    {
                        return ApiResultHelper.Error("删除失败");
                    }
                    return ApiResultHelper.Success(b);
                }

                /// <summary>
                /// 修改新闻
                /// </summary>
                /// <param name="id"></param>
                /// <param name="title"></param>
                /// <param name="content"></param>
                /// <param name="typeid"></param>
                /// <returns></returns>

                [HttpPut("Edit")]
                public async Task<ActionResult<ApiResult>> Edit(int id, string title, string content, int typeid)
                {
                    var blogNews = await newsService.FindAsync(id);
                    if (blogNews == null)
                    {
                        return ApiResultHelper.Error("没有找到该新闻");
                    }
                    blogNews.Title = title;
                    blogNews.Content = content;
                    blogNews.TypeId = typeid;
                    blogNews.WriterId = Convert.ToInt32(this.User.FindFirst("Id").Value);
                    bool b = await newsService.EditAsync(blogNews);
                    if (!b)
                    {
                        return ApiResultHelper.Error("修改失败");
                    }
                    return ApiResultHelper.Success(blogNews);
                }

                ///// <summary>
                ///// 查询新闻
                ///// </summary>
                ///// <returns></returns>
                //[HttpGet("News")]
                //public async Task<ActionResult<ApiResult>> GetBlogNews()
                //{
                //    var data = await newsService.QueryAsync();
                //    if (data.Count == 0)
                //    {
                //        return ApiResultHelper.Error("没有更多的新闻");
                //    }
                //    return ApiResultHelper.Success(data);
                //}

                /// <summary>
                /// 导航查询新闻(查询当前登录用户所属的新闻 )
                /// </summary>
                /// <returns></returns>
                [HttpGet("News")]
                public async Task<ActionResult<ApiResult>> GetBlogNews()
                {
                    int id = Convert.ToInt32(this.User.FindFirst("Id").Value);
                    var data = await newsService.QueryAsync(c => c.WriterId == id);
                    if (data.Count == 0)
                    {
                        return ApiResultHelper.Error("没有更多的新闻");
                    }
                    return ApiResultHelper.Success(data);
                }

                /// <summary>
                /// 分页查询
                /// </summary>
                /// <param name="iMapper"></param>
                /// <param name="page"></param>
                /// <param name="size"></param>
                /// <returns></returns>
                [HttpGet("NewsPage")]
                public async Task<ApiResult> GetBlogNewsPage([FromServices] IMapper iMapper, int page, int size)
                {
                    RefAsync<int> total = 0;
                    var news = await newsService.QueryAsync(page, size, total);
                    try
                    {
                        var newsDTO = iMapper.Map<List<NewsDTO>>(news);
                        return ApiResultHelper.Success(newsDTO, total);
                    }
                    catch (Exception)
                    {
                        return ApiResultHelper.Error("AutoMapper映射错误");
                    }
                }
            }
        }

    (2)新闻类型
        using Microsoft.AspNetCore.Authorization;
        using Microsoft.AspNetCore.Http;
        using Microsoft.AspNetCore.Mvc;
        using MyNews.IService;
        using MyNews.Model;
        using MyNews.WebApi.Utility.ApiResult;
        using System;
        using System.Collections.Generic;
        using System.Linq;
        using System.Threading.Tasks;

        namespace MyNews.WebApi.Controllers
        {
            [Route("api/[controller]")]
            [ApiController]
            [Authorize]
            public class NewsTpyeController : ControllerBase
            {
                private readonly INewsTypeService newsTypeService;
                public NewsTpyeController(INewsTypeService newsTypeService)
                {
                    this.newsTypeService = newsTypeService;
                }

                /// <summary>
                /// 添加新闻类型
                /// </summary>
                /// <param name="name"></param>
                /// <returns></returns>
                [HttpPost("Create")]
                public async Task<ApiResult> Create(string name)
                {
                    #region 数据验证
                    if (String.IsNullOrWhiteSpace(name))
                    {
                        return ApiResultHelper.Error("新闻类型名不能为空");
                    }
                    #endregion
                    NewsType type = new NewsType
                    {
                        Name = name
                    };
                    bool b = await newsTypeService.CreateAsync(type);
                    if (!b)
                    {
                        return ApiResultHelper.Error("添加失败");
                    }
                    return ApiResultHelper.Success(type);
                }

                /// <summary>
                /// 删除新闻类型
                /// </summary>
                /// <param name="id"></param>
                /// <returns></returns>

                [HttpDelete("Delete")]
                public async Task<ApiResult> Delete(int id)
                {
                    bool b = await newsTypeService.DeleteAsync(id);
                    if (!b)
                    {
                        return ApiResultHelper.Error("删除失败");
                    }
                    return ApiResultHelper.Success(b);
                }

                /// <summary>
                /// 修改新闻类型
                /// </summary>
                /// <param name="id"></param>
                /// <param name="title"></param>
                /// <param name="content"></param>
                /// <param name="typeid"></param>
                /// <returns></returns>

                [HttpPut("Edit")]
                public async Task<ApiResult> Edit(int id, string name)
                {
                    var type = await newsTypeService.FindAsync(id);
                    if (type == null)
                    {
                        return ApiResultHelper.Error("没有找到该新闻类型");
                    }
                    type.Name = name;
                    bool b = await newsTypeService.EditAsync(type);
                    if (!b)
                    {
                        return ApiResultHelper.Error("修改失败");
                    };
                    return ApiResultHelper.Success(type);
                }

                /// <summary>
                /// 查询新闻类型
                /// </summary>
                /// <returns></returns>
                [HttpGet("NewsType")]
                public async Task<ApiResult> Types()
                {
                    var data = await newsTypeService.QueryAsync();
                    if (data.Count == 0)
                    {
                        return ApiResultHelper.Error("没有更多的类型");
                    }
                    return ApiResultHelper.Success(data);
                }
            }
        }

    (3)作者
        using AutoMapper;
        using Microsoft.AspNetCore.Authorization;
        using Microsoft.AspNetCore.Http;
        using Microsoft.AspNetCore.Mvc;
        using MyNews.IService;
        using MyNews.Model;
        using MyNews.Model.DTO;
        using MyNews.WebApi.Utility._MD5;
        using MyNews.WebApi.Utility.ApiResult;
        using System;
        using System.Collections.Generic;
        using System.Linq;
        using System.Threading.Tasks;

        namespace MyNews.WebApi.Controllers
        {
            [Route("api/[controller]")]
            [ApiController]
            [Authorize]
            public class WriterController : ControllerBase
            {
                private readonly IWriterService writerService;
                public WriterController(IWriterService writerService)
                {
                    this.writerService = writerService;
                }

                /// <summary>
                /// 添加用户
                /// </summary>
                /// <param name="name"></param>
                /// <param name="username"></param>
                /// <param name="userpwd"></param>
                /// <returns></returns>
                [HttpPost("Create")]
                public async Task<ApiResult> Create(string name, string username, string userpwd)
                {
                    //数据校验
                    Writer writer = new Writer
                    {
                        Name = name,
                        //加密密码
                        UserPwd = MD5Helper.MD5Encrypt32(userpwd),
                        UserName = username
                    };
                    //判断数据库中是否已经存在账号跟要添加的账号相同的数据
                    var oldWriter = await writerService.FindAsync(c => c.UserName == username);
                    if (oldWriter != null)
                    {
                        return ApiResultHelper.Error("账号已经存在");
                    }
                    bool b = await writerService.CreateAsync(writer);
                    if (!b)
                    {
                        return ApiResultHelper.Error("添加失败");
                    }
                    return ApiResultHelper.Success(writer);
                }

                /// <summary>
                /// 修改用户
                /// </summary>
                /// <param name="name"></param>
                /// <returns></returns>
                [HttpPut("Edit")]
                public async Task<ApiResult> Edit(string name)
                {
                    int id = Convert.ToInt32(this.User.FindFirst("Id").Value);
                    var writer = await writerService.FindAsync(id);
                    writer.Name = name;
                    bool b = await writerService.EditAsync(writer);
                    if (!b) return ApiResultHelper.Error("修改失败");
                    return ApiResultHelper.Success("修改成功");
                }

                /// <summary>
                /// 查询用户
                /// </summary>
                /// <param name="iMapper"></param>
                /// <param name="id"></param>
                /// <returns></returns>
                [AllowAnonymous]//匿名访问
                [HttpGet("FindWriter")]
                public async Task<ApiResult> FindWriter([FromServices] IMapper iMapper, int id)
                {
                    var writer = await writerService.FindAsync(id);
                    var writerDTO = iMapper.Map<WriterDTO>(writer);
                    return ApiResultHelper.Success(writerDTO);
                }
            }
        }

    # 8.JWT的使用
    (1)JWT授权
    ①添加一个webapi项目
    新建JWT文件夹->MyNews.JWT项目
    添加NuGet程序包:SqlSugarCore(官网:https://www.donet5.com/home/doc)

    ②安装Nuget程序包 System.IdentityModel.Tokens.Jwt

    ③复制WebAapi项目中的Startup类中的代码到MyNews.JWT项目中Startup类中、UTIlity文件夹

    ④新建控制器AuthoizeController
        using Microsoft.AspNetCore.Http;
        using Microsoft.AspNetCore.Mvc;
        using Microsoft.IdentityModel.Tokens;
        using MyNews.IService;
        using MyNews.JWT.Utility._MD5;
        using MyNews.JWT.Utility.ApiResult;
        using System;
        using System.Collections.Generic;
        using System.IdentityModel.Tokens.Jwt;
        using System.Linq;
        using System.Security.Claims;
        using System.Text;
        using System.Threading.Tasks;

        namespace MyNews.JWT.Controllers
        {
            [Route("api/[controller]")]
            [ApiController]
            public class AuthoizeController : ControllerBase
            {
                private readonly IWriterService writerService;
                public AuthoizeController(IWriterService writerService)
                {
                    this.writerService = writerService;
                }

                /// <summary>
                /// JWT授权
                /// </summary>
                /// <param name="username"></param>
                /// <param name="userpwd"></param>
                /// <returns></returns>
                [HttpPost("Login")]
                public async Task<ApiResult> Login(string username, string userpwd)
                {
                    //加密后的密码 123456 =>E1ADC3949BA59ABBE56E057F2F883E
                    string pwd = MD5Helper.MD5Encrypt32(userpwd);
                    //数据校验
                    var writer = await writerService.FindAsync(c => c.UserName == username && c.UserPwd == pwd);
                    if (writer != null)
                    {
                        //登陆成功
                        var claims = new Claim[]
                            {
                        new Claim(ClaimTypes.Name, writer.Name),
                        new Claim("Id", writer.Id.ToString()),
                        new Claim("UserName", writer.UserName)
                                //不能放敏感信息
                            };
                        var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("SDMC-CJAS1-SAD-DFSFA-SADHJVF-VF"));
                        //issuer代表颁发Token的Web应用程序,audience是Token的受理者
                        var token = new JwtSecurityToken(
                            issuer: "http://localhost:6060",//JWT地址
                            audience: "http://localhost:5000",//webApi地址
                            claims: claims,
                            notBefore: DateTime.Now,
                            expires: DateTime.Now.AddHours(1),
                            signingCredentials: new SigningCredentials(key, SecurityAlgorithms.HmacSha256)
                        );
                        var jwtToken = new JwtSecurityTokenHandler().WriteToken(token);
                        return ApiResultHelper.Success(jwtToken);
                    }
                    else
                    {
                        return ApiResultHelper.Error("账号或密码错误");
                    }
                }
            }
        }

    (2)JWT鉴权
    在MyNews.WebApi项目Startup类中添加app.UseAuthentication();//鉴权
        using Microsoft.AspNetCore.Authentication.JwtBearer;
        using Microsoft.AspNetCore.Builder;
        using Microsoft.AspNetCore.Hosting;
        using Microsoft.AspNetCore.HttpsPolicy;
        using Microsoft.AspNetCore.Mvc;
        using Microsoft.Extensions.Configuration;
        using Microsoft.Extensions.DependencyInjection;
        using Microsoft.Extensions.Hosting;
        using Microsoft.Extensions.Logging;
        using Microsoft.IdentityModel.Tokens;
        using Microsoft.OpenApi.Models;
        using MyNews.IRepository;
        using MyNews.IService;
        using MyNews.Repository;
        using MyNews.Service;
        using MyNews.WebApi.Utility._AutoMapper;
        using SqlSugar.IOC;
        using System;
        using System.Collections.Generic;
        using System.Linq;
        using System.Text;
        using System.Threading.Tasks;

        namespace MyNews.WebApi
        {
            public class Startup
            {
                public Startup(IConfiguration configuration)
                {
                    Configuration = configuration;
                }

                public IConfiguration Configuration { get; }

                // This method gets called by the runtime. Use this method to add services to the container.
                public void ConfigureServices(IServiceCollection services)
                {

                    services.AddControllers();
                    services.AddSwaggerGen(c =>
                    {
                        c.SwaggerDoc("v1", new OpenApiInfo { Title = "MyNews", Version = "v1" });
                        #region Swagger使用鉴权组件
                        c.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
                        {
                            In = ParameterLocation.Header,
                            Type = SecuritySchemeType.ApiKey,
                            Description = "直接在下框中输入Bearer {token}(注意两者之间是一个空格)",
                            Name = "Authorization",
                            BearerFormat = "JWT",
                            Scheme = "Bearer"
                        });
                        c.AddSecurityRequirement(new OpenApiSecurityRequirement
                        {
                        {
                            new OpenApiSecurityScheme
                            {
                            Reference=new OpenApiReference
                            {
                                Type=ReferenceType.SecurityScheme,
                                Id="Bearer"
                            }
                            },
                            new string[] {}
                        }
                        });
                        #endregion

                    });
                    #region 注入SqlSugarIOC
                    services.AddSqlSugar(new IocConfig()
                    {
                        //ConfigId="db01"  多租户用到
                        ConnectionString = this.Configuration["SqlConn"],
                        DbType = IocDbType.SqlServer,
                        IsAutoCloseConnection = true//自动释放
                    });
                    #endregion
                    #region IOC依赖注入
                    services.AddCustomIOC();
                    #endregion
                    #region JWT鉴权
                    services.AddCustomJWT();
                    #endregion
                    #region 注入AutoMapper
                    services.AddAutoMapper(typeof(CustomAutoMapperProfile));
                    #endregion
                }

                // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
                public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
                {
                    if (env.IsDevelopment())
                    {
                        app.UseDeveloperExceptionPage();
                        app.UseSwagger();
                        app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "MyNews v1"));

                    }

                    app.UseHttpsRedirection();

                    app.UseRouting();

                    app.UseAuthentication();//鉴权

                    app.UseAuthorization();

                    app.UseEndpoints(endpoints =>
                    {
                        endpoints.MapControllers();
                    });
                }
            }

            public static class IOCExtend
            {
                public static IServiceCollection AddCustomIOC(this IServiceCollection services)
                {
                    services.AddScoped<INewsRepository, NewsRepository>();
                    services.AddScoped<INewsTypeRepository, NewsTypeRepository>();
                    services.AddScoped<IWriterRepository, WriterRepository>();
                    services.AddScoped<INewsService, NewsService>();
                    services.AddScoped<INewsTypeService, NewsTypeService>();
                    services.AddScoped<IWriterService, WriterService>();
                    return services;
                }

                public static IServiceCollection AddCustomJWT(this IServiceCollection services)
                {
                    services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
                        .AddJwtBearer(options =>
                        {
                            options.TokenValidationParameters = new TokenValidationParameters
                            {
                                ValidateIssuerSigningKey = true,
                                IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("SDMC-CJAS1-SAD-DFSFA-SADHJVF-VF")),
                                ValidateIssuer = true,
                                ValidIssuer = "http://localhost:6060",
                                ValidateAudience = true,
                                ValidAudience = "http://localhost:5000",
                                ValidateLifetime = true,
                                ClockSkew = TimeSpan.FromMinutes(60)
                            };
                        });
                    return services;
                }
            }
        }

    # 9.AutoMapper(官网https://automapper.org/)

    (1)安装Nuget AutoMapper.Extensions.Microsoft.DependencyInjection

    定义一个类,继承Profile
        public class CustomAutoMapperProfile:Profile
        {
            public CustomAutoMapperProfile()
            {
                base.CreateMap<Writer, WriterDTO>();
            }
        }

    (2)在服务中注册
    services.AddAutoMapper(typeof(CustomAutoMapperProfile));

    构造函数注入
    private readonly IMapper _mapper;

        public StudentsController(IMapper mapper)
        {
          this._mapper = mapper;
        }

    (4)复杂映射

    base.CreateMap<Admin, AdminDto>()
            .ForMember(dest => dest.RoleMsg, sourse => sourse.MapFrom(src => src.RoleInfo.RoleMsg));
  • 相关阅读:
    HangFire快速入门
    HangFire概述
    Lodop错误汇总
    微信支付过程遇到的问题
    动态规划算法
    几句话~
    Welcom To My Blog
    【技巧】关于素数
    安徽省小学组省赛2014年第一题 木板面积(C++)
    洛谷 P1425 小鱼的游泳时间
  • 原文地址:https://www.cnblogs.com/duhaoran/p/15513452.html
Copyright © 2020-2023  润新知