这段时间在折腾零点博客的数据同步,想把几个外站的 CMS 数据聚合过来,本来打算直接用 PHP 调 PHP,但为了方便客户端调用,还是决定转成 C# 后端来统一管理。在这个过程中,踩了不少坑,特别是关于 SQL注入防护JSON解析 的问题。今天就把这次开发的源码分享和核心逻辑给大家盘一遍,全是干货。

一、 为什么要写这个工具?

我们要对接的是一款基于 PHP 的老牌博客系统 EMLOGEMLOG 自带的 API 比较老旧,不支持直接跨域 POST 数据。如果你直接拼接 SQL 字符串,一旦别人在表单里传个 admin' OR '1'='1,你的数据库就炸了。所以,今天主要讲两个核心点:预处理语句防注入JSON数据清洗

二、 核心痛点:C# 处理 EMLOG 的防注入

很多新手在用 C# 操作 MySQL 时,容易犯一个低级错误:直接用字符串拼接 SQL。在 PHP 里我们习惯 $sql = "SELECT * FROM user WHERE name = '" . $name . "'",但在 C# 里,这绝对是禁忌。必须使用参数化查询。

1. 错误示范(千万别学)

string sql = "SELECT * FROM blog_article WHERE title LIKE '%" + keyword + "%'";
// 这种写法一旦 keyword 变量里包含恶意的 SQL 片段,后果不堪设想

2. 正确姿势:参数化查询

零点博客的后端开发中,我封装了一个通用的查询方法。大家注意看下面的代码,参数是单独传的,而不是拼在 SQL 里的。这样数据库引擎会自动处理转义,彻底杜绝 SQL注入防护 失效的问题。

using (MySqlConnection conn = new MySqlConnection(connectionString))
{
    conn.Open();
    string sql = "SELECT aid, title, content FROM " + DBPrefix + "blog WHERE status = 0";

    // 如果有搜索关键词,使用参数化拼接
    if (!string.IsNullOrEmpty(keyword))
    {
        sql += " AND title LIKE @keyword";
    }

    MySqlCommand cmd = new MySqlCommand(sql, conn);

    if (!string.IsNullOrEmpty(keyword))
    {
        // 关键点:使用参数添加,而不是字符串拼接
        cmd.Parameters.AddWithValue("@keyword", "%" + keyword + "%"); 
    }

    MySqlDataReader reader = cmd.ExecuteReader();
    while (reader.Read())
    {
        // 读取数据并处理...
    }
}

三、 前后端交互:JSON 解析与封装

拿到数据库数据后,我们需要按照前端要求返回 JSON/XML 格式。为了不重复造轮子,我直接返回了 JSON,因为其轻量级特性更适合爬虫开发或移动端接口。

// 构建简单的响应对象
var response = new 
{ 
    code = 200, 
    message = "success", 
    data = new List<object>()
};

while (reader.Read())
{
    response.data.Add(new 
    { 
        id = reader["aid"],
        title = reader["title"],
        date = reader["date"].ToString()
    });
}

// 将对象序列化为 JSON 字符串
string jsonResult = Newtonsoft.Json.JsonConvert.SerializeObject(response);
Response.Write(jsonResult);

四、 进阶实战:简易爬虫与正则清洗

除了对接数据库,零点博客还开发了一个简易的内容爬虫。当发现某些字段含有 HTML 标签时,就需要用正则表达式把这些标签干掉,只保留纯文本。

// 使用正则剔除 HTML 标签
string rawContent = "<p>Hello World</p>";
string cleanContent = Regex.Replace(rawContent, "<[^>]+>", "");
// 结果: Hello World

五、 源码分享与避坑指南

如果你正在做类似的在线工具开发,或者想给博客增加数据交互能力,这份代码可以直接用。下面附上我整理好的核心类,记得在 NuGet 里安装 Pomelo.EntityFrameworkCore.MySql 或者 MySql.Data

  • 避坑 1: 连接 MySQL 时,一定要在连接字符串里指定 Allow User Variables=True (视情况而定) 或者确保字符集是 utf8mb4,不然中文会乱码。
  • 避坑 2: C# 的 JSON 解析非常慢,如果数据量大,建议直接用流式处理,不要一次性 ToList() 把几万条数据全塞内存里。
  • 避坑 3: EMLOG 的文章 ID (aid) 是自增的,但在导入数据时,最好用时间戳或者 UUID 做唯一键,避免主键冲突。

以上就是零点博客关于 C# EMLOG对接 的全部复盘。代码不算复杂,但安全细节很多。希望大家在建站开发的过程中,不要为了赶进度而忽略了 SQL注入防护。如果有拿不下的技术难点,欢迎来 零点博客 抛砖引玉讨论。