ASP. NET Core Open Source Forum project NETCoreBBS, corenetcorebbs
ASP. NET Core lightweight Open Source forum project, ASP. NET Core Light forum NETCoreBBS
Developed Using ASP. NET Core + EF Core Sqlite + Bootstrap.
GitHub: https://github.com/linezero/NETCoreBBS
Development
Note: The default value is port 80, which may conflict with the local port. You can change it in Program. cs..UseUrls("http://*:80")
And then change the startup URL.
Features and technologies big collection Architecture Clean Architecture
1. Areas
Key code:
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?}"); });
Add an areaRoute, add the corresponding Areas folder, and add [Area ("Admin")] to the Controller in Areas.
2. ViewComponents
In the ViewComponents folder of the project, note that the corresponding view is in the Views \ Shared \ Components folder.
3. Middleware
Middleware for RequestIPMiddleware that records ip addresses and related information
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 ()} Time: {DateTime. now} ") ;}await _ next (httpContext) ;}} public static class RequestIPMiddlewareExtensions {public static IApplicationBuilder UseRequestIPMiddleware (this IApplicationBuilder builder) {return builder. useMiddleware <RequestIPMiddleware> ();}}
View Code4. Identity
Integrates Identity, extends User tables, and customizes User tables.
Permission Policy
services.AddAuthorization(options => { options.AddPolicy( "Admin", authBuilder => { authBuilder.RequireClaim("Admin", "Allowed"); }); });
Complexity of Logon password Registration
services.AddIdentity<User, IdentityRole>(options => { options.Password = new PasswordOptions() { RequireNonAlphanumeric = false, RequireUppercase=false }; }).AddEntityFrameworkStores<DataContext>().AddDefaultTokenProviders();
5. EF Core
EF Core uses the Sqlite database.
Read configuration files
services.AddDbContext<DataContext>(options => options.UseSqlite(Configuration.GetConnectionString("DefaultConnection")));
Use code to initialize a database
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(); } } }
Project Tiering DataContext in Infrastructure, precautions for using the dotnet ef command
dotnet ef migrations add InitMigration --startup-project ../NetCoreBBS/NetCoreBBS.csproj
Update a specified field. You do not need to query the object first.
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
Read the link string Configuration. GetConnectionString ("DefaultConnection ")
7. Partial Views
_ LoginPartial. cshtml head logon distribution View
_ PagerPartial. cshtml page distribution View
@ {Var pageindex = Convert. ToInt32 (ViewBag. PageIndex); var pagecount = Convert. ToInt32 (ViewBag. 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 = 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 previus_page @ (pageindex = 1? "Disabled": "") "> <a href =" @ (pageindex = 1? "#": $ "{Path} page = {pageindex-1}") ">&# 8592; previous Page </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}") "> next page & #8594; </a> </li> </ul>
It is not well written and can be optimized to TagHelper.
8. Injecting Services Into Views
@inject SignInManager<User> SignInManager
@ Inject keyword
9. Dependency Injection and Controllers
public IActionResult Index([FromServices]IUserServices user)
FromServices can be injected in a specified Action or using constructor.
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. Release
I have previously written the corresponding Publishing Article ASP. NET Core and published it to the Ubuntu System in the Linux production environment.
Since project. json is changed to csproj, the release changes.
By default, the release is still the same as the dotnet publish, and csproj is changed during the release.
Edit NetCoreBBS. csproj
<RuntimeIdentifiers>ubuntu.14.04-x64</RuntimeIdentifiers>
The following is also the dotnet publish-r ubuntu.14.04-x64
Note that this node is released by default, and the server must also install the same version of runtime.
<RuntimeFrameworkVersion>1.0.0</RuntimeFrameworkVersion>
Some of the code can be mined by yourself.
NETCoreBBS started at RC2, and many people should have read this project. This article gives you a better understanding of this project.