ASP.NET Core 开源论坛项目 NETCoreBBS

ASP.NET Core 轻量化开源论坛项目,ASP.NET Core Light forum NETCoreBBS

采用 ASP.NET Core + EF Core Sqlite + Bootstrap 开发。

GitHub: https://github.com/linezero/NETCoreBBS

开发

  1. git clone https://github.com/linezero/NETCoreBBS.git

  2. 使用 Visual Studio 2017 打开 NetCoreBBS.sln

  3. 点击 调试->开始调试 即可运行起来,或者直接点击工具栏上的NetCoreBBS即可。

注意:默认为80端口,可能会和本地端口冲突,可以到Program.cs 中更改 .UseUrls("http://*:80"),然后更改启动URL既可。

功能

  1. 节点功能

  2. 主题发布

  3. 主题回复

  4. 主题筛选

  5. 用户登录注册

  6. 主题置顶

  7. 后台管理

  8. 个人中心

技术点大合集

架构 Clean Architecture

 

1. Areas

重点代码:

            app.UseMvc(routes =>{routes.MapRoute(name: "areaRoute",template: "{area:exists}/{controller}/{action}",defaults: new { action = "Index" });routes.MapRoute(name: "default",template: "{controller=Home}/{action=Index}/{id?}");});

增加一个 areaRoute ,然后添加对应的Areas 文件夹,然后Areas里的控制器里加上  [Area("Admin")] 。

2. ViewComponents

在项目里的ViewComponents 文件夹,注意对应视图在 Views\Shared\Components 文件夹里。

3. Middleware

RequestIPMiddleware 记录ip及相关信息的中间件

    public class RequestIPMiddleware{       
 
private readonly RequestDelegate _next;      
  
private readonly ILogger _logger;      
  
public RequestIPMiddleware(RequestDelegate next){_next = next;_logger = LogManager.GetCurrentClassLogger();}      

       
public async Task Invoke(HttpContext httpContext){            
   
var url = httpContext.Request.Path.ToString();        
   
if (!(url.Contains("/css") || url.Contains("/js") || url.Contains("/images") || url.Contains("/lib"))){_logger.Info($"Url:{url} IP:{httpContext.Connection.RemoteIpAddress.ToString()} 时间:{DateTime.Now}");}          
 
await _next(httpContext);}}  

  
public static class RequestIPMiddlewareExtensions{      
       
public static IApplicationBuilder UseRequestIPMiddleware(this IApplicationBuilder builder){      
        
return builder.UseMiddleware<RequestIPMiddleware>();}}

4. Identity

集成Identity ,扩展User表,自定义用户表。

权限策略

            services.AddAuthorization(options =>{options.AddPolicy(                    "Admin",authBuilder =>{authBuilder.RequireClaim("Admin", "Allowed");});});

注册登录密码复杂度

            services.AddIdentity<User, IdentityRole>(options =>{options.Password = new PasswordOptions() {RequireNonAlphanumeric = false,RequireUppercase=false};}).AddEntityFrameworkStores<DataContext>().AddDefaultTokenProviders();

 

5. EF Core

EF Core 采用Sqlite 数据库。

读取配置文件

services.AddDbContext<DataContext>(options => options.UseSqlite(Configuration.GetConnectionString("DefaultConnection")));

使用代码初始化数据库

        private void InitializeNetCoreBBSDatabase(IServiceProvider serviceProvider){          
        
using (var serviceScope = serviceProvider.GetRequiredService<IServiceScopeFactory>().CreateScope()){            
         
var db = serviceScope.ServiceProvider.GetService<DataContext>();db.Database.Migrate();    
           
if (db.TopicNodes.Count() == 0){db.TopicNodes.AddRange(GetTopicNodes());db.SaveChanges();}}}

项目分层 DataContext 在 Infrastructure,使用dotnet  ef 命令注意事项 

dotnet ef migrations add InitMigration --startup-project ../NetCoreBBS/NetCoreBBS.csproj

更新指定字段,不用先查询实体。

        public IActionResult EditSave(Topic topic){_context.Attach(topic);_context.Entry(topic).Property(r => r.Title).IsModified = true;_context.Entry(topic).Property(r => r.Content).IsModified = true;_context.SaveChanges();    
       
return RedirectToAction("Index");}

 

6. Configuration

读取链接字符串 Configuration.GetConnectionString("DefaultConnection")

7. Partial Views

_LoginPartial.cshtml 头部登录部分分布视图

_PagerPartial.cshtml 分页分布视图


@{   
 
var pageindex = Convert.ToInt32(ViewBag.PageIndex);    var pagecount = Convert.ToInt32(ViewBag.PageCount);pagecount = pagecount == 0 ? 1 : pagecount;pageindex = pageindex > pagecount ? pagecount : pageindex;    

var path = Context.Request.Path.Value;  
  
var query = string.Empty;  
 
var querys = Context.Request.Query;  
 
foreach (var item in querys){    
   
if (!item.Key.Equals("page")){query += $"{item.Key}={item.Value}&";}}query = query == string.Empty ? "?" : "?" + query;path += query;  
 
var pagestart = pageindex - 2 > 0 ? pageindex - 2 : 1;
   
var pageend = pagestart + 5 >= pagecount ? pagecount : pagestart + 5; }<ul class="pagination"><li class="prev previous_page @(pageindex == 1 ? "disabled" : "")"><a href="@(pageindex==1?"#":$"{path}page={pageindex - 1}")">&#8592; 上一页</a></li><li @(pageindex == 1 ? "class=active" : "")><a rel="start" href="@(path)page=1">1</a></li>@if (pagestart > 2){        <li class="disabled"><a href="#">&hellip;</a></li>}@for (int i = pagestart; i < pageend; i++){        if (i > 1){            <li @(pageindex == i ? "class=active" : "")><a rel="next" href="@(path)page=@i">@i</a></li>}}@if (pageend < pagecount){      
  
<li class="disabled"><a href="#">&hellip;</a></li>}@if (pagecount > 1){        <li @(pageindex == pagecount ? "class=active" : "")><a rel="end" href="@(path)page=@pagecount">@pagecount</a></li>}    <li class="next next_page @(pageindex==pagecount?"disabled":"")"><a rel="next" href="@(pageindex==pagecount?"#":$"{path}page={pageindex + 1}")">下一页 &#8594;</a></li> </ul>

写的不是很好,可以优化成TagHelper。

8. Injecting Services Into Views

@inject SignInManager<User> SignInManager

@inject 关键字

9. Dependency Injection and Controllers

public IActionResult Index([FromServices]IUserServices user)

FromServices 在指定Action注入,也可以使用构造函数注入。


private ITopicRepository _topic;  
    
private IRepository<TopicNode> _node;  
     
public UserManager<User> UserManager { get; }
     
public HomeController(ITopicRepository topic, IRepository<TopicNode> node, UserManager<User> userManager){_topic = topic;_node = node;UserManager = userManager;}

 

10.发布

之前写过对应的发布文章 ASP.NET Core 发布至Linux生产环境 Ubuntu 系统

由于project.json 改成csproj,发布有所变动。

默认发布还是相同 dotnet publish,自带运行时发布时更改csproj。

编辑 NetCoreBBS.csproj

<RuntimeIdentifiers>ubuntu.14.04-x64</RuntimeIdentifiers>

后续同样是 dotnet publish -r ubuntu.14.04-x64

注意这个节点,默认发布的,服务器也要安装相同版本的runtime。

<RuntimeFrameworkVersion>1.0.0</RuntimeFrameworkVersion>

 

代码里面还有一些大家可以自己去挖掘。

NETCoreBBS 在RC2 的时候就已经开始了,有很多人应该已经看过这个项目,这篇文章是让大家更清楚的了解这个项目。

原文地址:http://www.cnblogs.com/linezero/p/NETCoreBBS.html


.NET社区新闻,深度好文,微信中搜索dotNET跨平台或扫描二维码关注

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/324563.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

使用相对长度单位em布局网页内容

顺便问一下哈&#xff1f;那个辣椒酱大家感觉怎么样&#xff0c;你们也买了也尝了&#xff0c;是不是该反馈反馈啦~~如果还有想要的&#xff0c;可以联系我呐&#xff01;原文地址&#xff1a;自从有了这款辣椒酱&#xff0c;拌饭再也不用老干妈前言&#xff1a;在页面开发中&a…

史上最全的 MySQL 高性能优化实战总结

转载自 史上最全的 MySQL 高性能优化实战总结 一、前言 MySQL 对于很多 Linux 从业者而言&#xff0c;是一个非常棘手的问题&#xff0c;多数情况都是因为对数据库出现问题的情况和处理思路不清晰。在进行 MySQL 的优化之前必须要了解的就是 MySQL 的查询过程&#xff0c;很…

.NET Core快速入门教程 3、我的第一个.NET Core App (CentOS篇)

一、前言 本篇开发环境&#xff1f;1、操作系统&#xff1a;CentOS7&#xff08;因为ken比较偏爱CentOS7&#xff09;2、SDK版本&#xff1a;.NET Core 2.0 Preview你可能需要的前置知识1、了解如何通过Hyper-V安装CentOS虚拟机2、了解CentOS7基础命令/常用命令 二、安装 .NE…

RPC(远程过程调用)

1、RPC和HTTP对比 1.1 具体实现 RPC&#xff1a;可以基于TCP协议&#xff0c;也可以基于HTTP协议。 HTTP&#xff1a;基于HTTP协议 1.2 效率 RPC&#xff1a;自定义具体实现可以减少很多无用的报文内容&#xff0c;使得报文体积更小。 HTTP&#xff1a;如果是HTTP 1.1 报文中很…

【2018.3.24】模拟赛之四-ssl2548 旋转【暴力模拟】

正题 大意 给出一块黑块和白块组成的版&#xff0c;将其旋转90后和之前的黑块叠加&#xff0c;求最初始和每次旋转后的黑块数。 解题思路 暴力模拟不解释 代码 #include<cstdio> #include<iostream> using namespace std; int n,s; char c[51][51],a[51][51];…

使用相对长度单位rem布局网页内容

前言&#xff1a;上篇我们提到了相对单位em的用法&#xff0c;知道了em的概念&#xff0c;即是一个相对的单位&#xff0c;也知道了em的值不是固定的&#xff0c;p标签里的em和p里面的div下面的1em的px值并不是一样的。具体是多少呢&#xff1f;那就得看一下父级元素的值了&…

告诉你,Spring Boot 真是个牛逼货

转载自 告诉你&#xff0c;Spring Boot 真是个牛逼货 现在 Spring Boot 非常火&#xff0c;各种技术文章&#xff0c;各种付费教程&#xff0c;多如牛毛&#xff0c;可能还有些不知道 Spring Boot 的&#xff0c;那它到底是什么呢&#xff1f;有什么用&#xff1f;今天给大家…

集合还有这么优雅的运算法?

前言&#xff1a;在初中数学&#xff0c;我们也有集合的概念&#xff0c;非但如此&#xff0c;还有集合中的一些运算&#xff0c;例如交集、并集、差集等&#xff0c;那么我们java中的集合是否有这样的运算呢&#xff1f;今天我们就一起来看看&#xff01;01并集就是将两个集合…

.NET Core快速入门教程 2、我的第一个.NET Core App(Windows篇)

一、前言 本篇开发环境&#xff1f;1、操作系统&#xff1a; Windows 10 X642、SDK&#xff1a; .NET Core 2.0 Preview 二、安装 .NET Core SDK 1、下载 .NET Core下载地址&#xff1a;https://www.microsoft.com/net/download/core根据自己电脑情况选择对应版本即可.NET C…

【2018.3.24】模拟赛之六-ssl2550 重要人物【图论,最短路,SPFA】

正题 大意 有一个大人物&#xff0c;它要从经过一些地方&#xff0c;他所在的路会被封闭&#xff08;不可以进入&#xff0c;可以出&#xff09;。你要从一个点到到另一个点&#xff0c;求最短时间。 解题思路 求出每条路的封闭时间&#xff0c;然后SPFA 代码 #include<…

今天 ,给大家变个魔术!!!

前言&#xff1a;在对网页进行布局时&#xff0c;当我们设置div的的宽为固定宽时&#xff0c;理论上&#xff0c;内容是不会超出div的&#xff0c;那你有没有见过内容超出div固定宽度的情况呢&#xff1f;今天我们就来看看到底是怎么一回事&#xff1f;看分析之前&#xff0c;我…

Google的面试题长啥样

转载自 Google的面试题长啥样 本文翻译自Google工程师/面试官Alex Golec的文章&#xff1a;Google Interview Questions Deconstructed: The Knight’s Dialer&#xff1b; 来源&#xff1a;实验楼&#xff0c;翻译&#xff1a;实验楼扫地阿姨 原文&#xff1a;https://medium…

Autofac+Castle实现AOP事务

一、前言 最近公司新项目&#xff0c;需要搭架构进行开发&#xff0c;其中需要保证事务的一致性&#xff0c;经过一番查找&#xff0c;发现很多博文都是通过Spring.Net、Unity、PostSharp、Castle Windsor这些方式实现AOP的。但是这不是我想要的&#xff0c;因此一番查找后&am…

今天,我们就来抽个奖!

前言&#xff1a;在日常生活中&#xff0c;我们经常会用到一些抽奖的功能&#xff0c;比如公司年会上的抽奖环节&#xff0c;班级随机点名回答问题的小程序&#xff0c;随机点名系统的程序可以看这里&#xff1a;&#xff0c;那你知道类似的抽奖功能是怎么实现的吗&#xff1f;…

Spring Boot 最核心的 3 个注解详解

转载自 Spring Boot 最核心的 3 个注解详解 最近面试一些 Java 开发者&#xff0c;他们其中有些在公司实际用过 Spring Boot, 有些是自己兴趣爱好在业余自己学习过。 然而&#xff0c;当我问他们 Spring Boot 最核心的 3 个注解是什么&#xff0c;令我失望的是鲜有人能答上来…

刚刚,改造了下BaseDao……

今天在上课的时候&#xff0c;带着学生们写底层的jdbc连接数据库并且对数据表进行增删改查&#xff0c;写的那就一个痛苦啊……从创建实体类到写Dao层代码再到表现层的Jsp页面&#xff0c; 写了好久好久……终于写完了&#xff01;&#xff01;&#xff01;其实吧&#xff0…

ssl2340-格子游戏【并查集】

正题 题目链接 大意 有两个人在玩游戏&#xff0c;在一个n*n的矩阵的点上画线&#xff0c;有如果有线封了圈那么游戏结束&#xff0c;给出一些操作&#xff0c;求在那一轮结束了游戏&#xff0c;或没有结束游戏。 解题思路 用并查集把点相连&#xff0c;直到并查集形成环为…

ASP.NET Core MVC 过滤器介绍

过滤器的作用是在 Action 方法执行前或执行后做一些加工处理。使用过滤器可以避免Action方法的重复代码&#xff0c;例如&#xff0c;您可以使用异常过滤器合并异常处理的代码。 过滤器如何工作&#xff1f; 过滤器在 MVC Action 调用管道中运行&#xff0c;有时称为过滤器管…

dubbo小项目

完整Dubbo项目演示 1 原型 1.1 部门显示&#xff0c;显示全部部门信息 1.2 员工新增 1.3 查看部门员工 2 按照分布式架构进行设计项目 设定员工管理和部门管理不在同一个模块中&#xff0c;需要有一个员工管理项目和一个部门管理项目。 为了方便&#xff0c;不去每个项…

如何构建一套高可用的 APP 消息推送平台

转载自 如何构建一套高可用的 APP 消息推送平台 消息推送作为移动 APP 运营中的一项关键技术&#xff0c;已经被越来越广泛的运用。本文追溯了推送技术的发展历史&#xff0c;剖析了其核心原理&#xff0c;并对推送服务的关键技术进行深入剖析&#xff0c;围绕消息推送时产生…