返回文章列表文章索引阅读全文
STARBLOG / 阅读手记
StarBlog博客开发笔记

StarBlog Blog Development Notes (3): Model Design

Series Articles Developing a Blog Project with .NetCore: StarBlog - (1) Why Do You Need to Write Your Own Blog? Developing a Blog Project with .NetCore: StarBlog - (2) Environment Setup and Project Creation Developing a Blog Project with .NetCore: StarBlog - (3) Model Design ... Developing a Blog Project with .NetCore: StarBlog - API Response Wrapping Developing a Blog Project with .NetCore: StarBlog - Upload

曦远 (DealiAxy)约 24 分钟
目录8 个章节

Series Articles

  • Developing a Blog Project with .NetCore: StarBlog - (1) Why Do You Need to Write Your Own Blog?
  • Developing a Blog Project with .NetCore: StarBlog - (2) Environment Setup and Project Creation
  • Developing a Blog Project with .NetCore: StarBlog - (3) Model Design
  • ...
  • Developing a Blog Project with .NetCore: StarBlog - API Response Wrapping
  • Developing a Blog Project with .NetCore: StarBlog - Image Upload Feature
  • Developing a Blog Project with .NetCore: StarBlog - Authentication Feature
  • Developing a Blog Project with .NetCore: StarBlog - Frontend Related
  • Developing a Blog Project with .NetCore: StarBlog - Frontend Development (1) Preparation
  • Developing a Blog Project with .NetCore: StarBlog - Frontend Development (2) Page Routing
  • Developing a Blog Project with .NetCore: StarBlog - Frontend Development (3) SASS and SCSS
  • Developing a Blog Project with .NetCore: StarBlog - Frontend Development (4) FontAwesome Icons
  • Developing a Blog Project with .NetCore: StarBlog - Frontend Development (5) Axios Request Wrapper
  • Developing a Blog Project with .NetCore: StarBlog - Frontend Development (6) Login Page
  • Developing a Blog Project with .NetCore: StarBlog - Frontend Development (7) Main Page
  • Developing a Blog Project with .NetCore: StarBlog - Frontend Development (8) Vuex and State Management
  • Developing a Blog Project with .NetCore: StarBlog - Frontend Development: File Upload
  • Developing a Blog Project with .NetCore: StarBlog - Frontend Development: Waterfall Image List
  • Developing a Blog Project with .NetCore: StarBlog - Frontend Development: Navigation Guards
  • ...

Preface

The previous article introduced (filler) the steps of creating a new project. This article finally gets to the real topic—time to start writing code!

Oh, and a friend left a comment on the previous article asking what the admin username and password are. That was an oversight on my part—I didn't add a convenient project initialization feature. Currently, to log in to the admin panel you need to create a user in the User table of the database. Later I'll improve the roles and permissions part, then add some command-line tools to the project, like django-admin.

OK, this article covers the model design of the StarBlog blog project.

Model Design

Based on the blog's functional requirements, the data falls into three categories:

  • Post-related (posts, post categories)
  • Photography/album-related
  • Featured content configuration (featured posts, categories, photos; pinned posts, categories)

Code

Since I haven't learned DDD yet, (I may refactor with new techniques later after learning the Abp vNext framework), I'll start by planning the project with a traditional MVC architecture~

Looking back at the previous article, we created several projects. Now, we'll put the data models in the StarBlog.Data project.

Open the IDE, create a new directory named Models in the StarBlog.Data project. All subsequent data models will go in this directory/namespace.

Since the project code is already open-sourced on GitHub, I won't paste all the data model code here. Let's first look at the directory structure after creation.

The code can be viewed here: https://github.com/Deali-Axy/StarBlog/tree/master/StarBlog.Data/Models

Models
├── Category.cs			 # 文章分类
├── FeaturedCategory.cs  # 推荐分类
├── FeaturedPhoto.cs     # 推荐图片
├── FeaturedPost.cs      # 推荐文章
├── Photo.cs             # 摄影图片
├── Post.cs              # 文章
├── TopPost.cs           # 置顶文章
└── User.cs              # 用户

To help readers understand the project design and the relationships between models, let's go over a few key ones.

Category.cs

Post category. Full code: https://github.com/Deali-Axy/StarBlog/blob/master/StarBlog.Data/Models/Category.cs

StarBlog supports batch importing markdown, then using the directory structure as post categories. The directory name is the category name, and multi-level categories are supported.

Partial code as follows:

public class Category {
    public int Id { get; set; }
    public string Name { get; set; }
    public int ParentId { get; set; }
    public bool Visible { get; set; } = true;
}

Post.cs

Full code: https://github.com/Deali-Axy/StarBlog/blob/master/StarBlog.Data/Models/Post.cs

For a blog site, the most important thing is posts. Partial code of the post model is as follows

namespace StarBlog.Data.Models;

public class Post {
    // 省略部分字段...
    public string? Status { get; set; }
    public bool IsPublish { get; set; }
    public string? Path { get; set; }
    public DateTime CreationTime { get; set; }
    public DateTime LastUpdateTime { get; set; }
    public string? Categories { get; set; }
}

First look at the Status and IsPublish fields. One is the post status (unfinished, unmodified, unpublished), and the other is whether it's published. What ultimately determines whether a post is displayed on the site is the IsPublish field, so what's the point of the Status field?

Answer: to preserve the post status from before import.

This project's blog supports importing an entire directory of markdown files as posts. My habit is to write the post's status at the very beginning of the markdown filename. For example, an unfinished post would have the filename: (未完成)StarBlog博客开发笔记(3):模型设计, so the Status field is for identifying and extracting that status from (未完成) (specifically using regular expressions, which will be covered later).

Next is the Path field. This field represents the relative location of the post before it was imported as a markdown file. For example, if we imported all posts from the D:\blog directory, and that directory's structure looks like this:

blog
├── Asp-Net-Core学习笔记
│   ├── Asp-Net-Core学习笔记:1.MVC入门篇.md
│   ├── Asp-Net-Core学习笔记:2.MVC视图、模型、持久化、文件、错误处理、日志.md
│   ├── Asp-Net-Core学习笔记:3.使用SignalR实时通信框架开发聊天室.md
│   ├── Asp-Net-Core学习笔记:4.Blazor-WebAssembly入门.md
│   ├── Asp-Net-Core学习笔记:5.构建和部署.md
│   ├── Asp-Net-Core学习笔记:WebApi开发实践.md
│   ├── Asp-Net-Core学习笔记:身份认证入门.md
│   ├── Asp-Net-Core学习笔记:部署,早知道,还是docker,以及一点碎碎念.md
├── Asp-Net-Core开发笔记
│   ├── Asp-Net-Core开发笔记:使用NPM和gulp管理前端静态文件.md
│   ├── Asp-Net-Core开发笔记:在docker部署时遇到一个小坑.md
│   └── Asp-Net-Core开发笔记:接口返回json对象出现套娃递归问题.md
├── 不吹不黑,跨平台框架AspNetCore开发实践杂谈.md
├── 梦想家装平台开发记录,Asp-Net-Core上手实践.md
├── (未修改)How-to-Connect-to-MySQL-from--NET-Core.md
├── (未修改)使用Ocelot实现Api网关.md
├── (未发布)跨域配置.md
├── (未完成)ASP-NET-Core-使用-Hangfire-定时任务.md
├── (未完成)Core-定时任务之HangFire.md
├── (未完成)使用-ASP-NET-Core-和-Hangfire-实现-HTTP-异步化方案.md
├── (未完成)使用Sentry.md
└── (未完成)在xunit里使用依赖注入.md

Then, for the post (未发布)跨域配置.md under the blog/AspNetCore directory, its Path field is AspNetCore

For posts under the blog/AspNetCore/Asp-Net-Core学习笔记 directory, the Path field is AspNetCore/Asp-Net-Core学习笔记

The purpose of the Path field is to implement the multi-level categories mentioned earlier. Meanwhile, the Categories field at the bottom is also prepared for implementing multi-level categories.

During post import, directory names are used as category names to create post categories, and the category ID is recorded in the post's CategoryId field. For multi-level categories, the post's CategoryId field records the last category; parent categories are not in this CategoryId. Although Category has a ParentId field to find parent categories, it's rather inconvenient in practice, so I added this Categories field to record the post's category hierarchy. Its content looks like 1,2,3, with category IDs separated by commas.

This way, when displaying on the frontend, you only need to use services to process the Categories field into a List<Category>.

Photo.cs

Oh, and there's also the photo model. Since I take photos in my spare time, I added a photography sharing feature. This model stores uploaded images.

Partial code as follows

public class Photo {
    // 省略部分字段...
    public string Location { get; set; }
    public string FilePath { get; set; }
    public long Height { get; set; }
    public long Width { get; set; }
}

I didn't consider the image height and width fields at first, but when implementing the waterfall layout I found that without width and height it wouldn't work. So I found the SixLabors.ImageSharp library to read image information. This library is quite powerful—highly recommended~

The Location shooting location currently has to be entered manually. I previously made an album project with Python that could read GPS info from the image's Exif data, then reverse-geocode it to get the shooting address. I'll note this as a todo for now and implement it later~

Others

The three that start with Featured are recommendation-related and can be configured in the admin panel;

Then, pinned posts and pinned categories can each only have one set, displayed on the site homepage.

That's about it. See you in the next article~

Meanwhile, all project code has been uploaded to GitHub. Stars/Forks from you all are welcome!

_EOF_

StarBlog Blog Development Notes (3): Model Design

本文作者:
程序设计实验室
版权声明:
本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!

相关文章

StarBlog博客开发笔记(27):使用JWT保护接口

前言 这是StarBlog系列在2023年的第二篇更新😂 这几个月都在忙,更新变得很不勤快,但是拖着不更新我的心里更慌,很久没写,要开头就变得很难😑 说回正题,之前的文章里,我们已经把博客关键的接口都开发完成了,但还少了一个最关键的「认证授权」,少了这东西,网站就跟筛子一样,谁都可以来添加和删除数据,乱套了~ 关于「认证授权」的知识,会比较复杂,要学习这块的话,建议分几步: 基础概念 AspN

2023-05-03 · StarBlog博客开发笔记 · 约 1 分钟

讨论

共 0 条

良言一句三冬暖,恶语伤人六月寒。

加载评论中…