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() == )
{
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 == ? : 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 - > ? pageindex - : ;
var pageend = pagestart + >= pagecount ? pagecount : pagestart + ;
}
<ul class="pagination">
<li class="prev previous_page @(pageindex == 1 ? "disabled" : "")">
<a href="@(pageindex==1?"#":$"{path}page={pageindex - }")">&#; 上一页</a>
</li>
<li @(pageindex == ? "class=active" : "")><a rel="start" href="@(path)page=1"></a></li>
@if (pagestart > )
{
<li class="disabled"><a href="#">&hellip;</a></li>
}
@for (int i = pagestart; i < pageend; i++)
{
if (i > )
{
<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 > )
{
<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 + }")">下一页 &#;</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.</RuntimeFrameworkVersion>

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

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

ASP.NET Core 开源论坛项目 NETCoreBBS的更多相关文章

  1. Asp.Net Core 2.0 项目实战(1) NCMVC开源下载了

    Asp.Net Core 2.0 项目实战(1) NCMVC开源下载了 Asp.Net Core 2.0 项目实战(2)NCMVC一个基于Net Core2.0搭建的角色权限管理开发框架 Asp.Ne ...

  2. ASP.NET Core 开源项目整理

    前言: 对 .NET Core 的热情一直没有下降过,新起的项目几乎都是采用 Core 来做开发. 跨平台是一个方面,另外就是 Core 很轻,性能远超很多开发语言(不坑). 一.ASP.NET Co ...

  3. Asp.Net Core 2.0 项目实战(10) 基于cookie登录授权认证并实现前台会员、后台管理员同时登录

    1.登录的实现 登录功能实现起来有哪些常用的方式,大家首先想到的肯定是cookie或session或cookie+session,当然还有其他模式,今天主要探讨一下在Asp.net core 2.0下 ...

  4. Asp.Net Core 2.0 项目实战(11) 基于OnActionExecuting全局过滤器,页面操作权限过滤控制到按钮级

    1.权限管理 权限管理的基本定义:百度百科. 基于<Asp.Net Core 2.0 项目实战(10) 基于cookie登录授权认证并实现前台会员.后台管理员同时登录>我们做过了登录认证, ...

  5. Asp.Net Core 2.0 项目实战(9) 日志记录,基于Nlog或Microsoft.Extensions.Logging的实现及调用实例

    本文目录 1. Net下日志记录 2. NLog的使用     2.1 添加nuget引用NLog.Web.AspNetCore     2.2 配置文件设置     2.3 依赖配置及调用     ...

  6. Asp.Net Core 2.0 项目实战(8)Core下缓存操作、序列化操作、JSON操作等Helper集合类

    本文目录 1.  前沿 2.CacheHelper基于Microsoft.Extensions.Caching.Memory封装 3.XmlHelper快速操作xml文档 4.Serializatio ...

  7. Asp.Net Core 2.0 项目实战(7)MD5加密、AES&DES对称加解密

    本文目录 1. 摘要 2. MD5加密封装 3. AES的加密.解密 4. DES加密/解密 5. 总结 1.  摘要 C#中常用的一些加密和解密方案,如:md5加密.RSA加密与解密和DES加密等, ...

  8. Asp.Net Core 2.0 项目实战(6)Redis配置、封装帮助类RedisHelper及使用实例

    本文目录 1. 摘要 2. Redis配置 3. RedisHelper 4.使用实例 5. 总结 1.  摘要 由于內存存取速度远高于磁盘读取的特性,为了程序效率提高性能,通常会把常用的不常变动的数 ...

  9. Asp.Net Core 2.0 项目实战(4)ADO.NET操作数据库封装、 EF Core操作及实例

    Asp.Net Core 2.0 项目实战(1) NCMVC开源下载了 Asp.Net Core 2.0 项目实战(2)NCMVC一个基于Net Core2.0搭建的角色权限管理开发框架 Asp.Ne ...

随机推荐

  1. Android 图片加载框架Picasso基本使用和源码完全解析(巨细无比)

    写在之前 原本打算是每周更新一篇博文,同时记录一周的生活状态,但是稍微工作忙一点就顾不上写博客了.悲催 还是说下最近的状况,最近两周一直在接公司申请的计费点, 沃商店,银贝壳,微信等等,然后就是不停的 ...

  2. Python初探

    Q:DBA是运维数据库,为什么还要懂开发? A: 维护:维护的机器太多了,很多重复的操作,需要开发出工具来实现 监控:所有机器的运行情况和健康状况都需要了解,全盘掌握cup.内存.磁盘.网络流量.数据 ...

  3. 开发Activity步骤

    第一步:写一个累继承Activity第二步:重写onCreate方法第三步:在主配置文件中注册activity <activity android:name=".类名" an ...

  4. JavaScript中对事件简单的理解(2)

    事件(event) event对象 (1)什么是event对象? Event 对象代表事件的状态,比如事件在其中发生的元素.键盘按键的状态.鼠标的位置.鼠标按钮的状态.事件通常与函数结合使用,函数不会 ...

  5. js实现整数转化为小数

    toFixed 方法 返回一个字符串,代表一个以定点表示法表示的数字. number .toFixed(i) 参数 bumber 必选项.一个 Number 对象. i 可选项.小数点 后的数字位数. ...

  6. 非滤波单目视觉slam笔记1

    非滤波单目视觉slam 主要分为以下8部分 数据类型 数据关联 初始化 位姿估计 地图维护 地图生成 失效恢复 回环检测 数据类型 直接法(稠密,半稠密) 基本原理是亮度一致性约束,\(J(x,y) ...

  7. ArcGIS Earth(原谷歌地球)如何获取高精度矢量地图数据?(shp文件/要素类/kml)

    大家好,这次来分享干货.做地理分析的同学,或者需要使用地图却不知道哪里有矢量数据的时候,怎么办呢? 这次,我就告诉大家哪里能自己手工制作矢量点线面数据!注意哦,是自己绘制的. 使用到的软件: ArcG ...

  8. python cookbook第三版学习笔记 一

    数据结构 假设有M个元素的列表,需要从中分解出N个对象,N<M,这会导致分解的值过多的异常.如下: record=['zhf','zhf@163.com','775-555-1212','847 ...

  9. Paxos Made Simple(译)

    The Paxos algorithm, when presented in plain English, is very simple. 我叫Leslie Lamport,我最屌. 1. 简介 用于 ...

  10. ecshop调用指定分类和个数的文章列表

    举例如首页调用方法: 1.先打开index.php文件找到以下代码: $smarty->assign('new_articles', index_get_new_articles()); // ...