You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将MySQL存储的RTF富文本正确加载到WPF RichTextBox控件中

问题根源
    1. SQL字符串拼接导致RTF内容损坏:RTF格式字符串中本身包含单引号'字符,直接拼接进SQL语句会提前闭合字段的引号边界,导致最终存入数据库的RTF内容被截断、残缺,读取时无法被正常解析。同时该写法存在严重的SQL注入风险。
    1. 编码选择错误:使用7位ASCII编码转换RTF字节流,若RTF包含中文、特殊符号等超出ASCII范围的字符,会被直接替换为乱码,破坏RTF结构完整性。
    1. 加载逻辑缺陷:清空RichTextBox内容后,直接基于空文档的首尾位置创建TextRange,加载时无法正确插入RTF内容。
    1. 存储逻辑不合理:仅当inpSupplierCode.Text不为空时才读取富文本内容,否则直接将Memo置空,不符合业务逻辑预期。
修复方案

1. 优先修改SQL为参数化查询(最核心修复)

无论你的Database封装类如何实现,必须停止直接拼接用户输入内容到SQL语句,改为参数传递,避免RTF中的特殊字符破坏SQL结构。示例修改如下(若你的Database类暂不支持参数,需自行扩展对应能力):

private void ToolbarButtonSave(object sender, RoutedEventArgs e)
{
    string ContentSupplierMemo = "";
    // 单独判断富文本内容,不要和SupplierCode绑定
    TextRange tr = new(inpSupplierMemo.Document.ContentStart, inpSupplierMemo.Document.ContentEnd);
    if (!tr.IsEmpty)
    {
        using (MemoryStream ms = new())
        {
            tr.Save(ms, DataFormats.Rtf);
            // 替换ASCII为UTF8编码,避免字符损坏
            ContentSupplierMemo = Encoding.UTF8.GetString(ms.ToArray());
        }
    }

    Database dbConnection = new Database
    {
        TableName = DatabaseTable
    };
    dbConnection.Connect();
    // 使用参数化SQL,不要拼接值
    dbConnection.SqlCommandString = @"UPDATE " + DatabaseTable + @" SET 
        supplier_Code = @supplier_Code,
        supplier_Name = @supplier_Name,
        supplier_Address1 = @supplier_Address1,
        supplier_Address2 = @supplier_Address2,
        supplier_Zip = @supplier_Zip,
        supplier_City = @supplier_City,
        supplier_Url = @supplier_Url,
        supplier_Memo = @supplier_Memo
        WHERE supplier_Id = @supplier_Id";
    
    // 示例为常见的参数添加方式,可根据你的Database类实现调整
    dbConnection.AddParameter("@supplier_Code", inpSupplierCode.Text);
    dbConnection.AddParameter("@supplier_Name", inpSupplierName.Text);
    dbConnection.AddParameter("@supplier_Address1", inpSupplierAddress1.Text);
    dbConnection.AddParameter("@supplier_Address2", inpSupplierAddress2.Text);
    dbConnection.AddParameter("@supplier_Zip", inpSupplierZip.Text);
    dbConnection.AddParameter("@supplier_City", inpSupplierCity.Text);
    dbConnection.AddParameter("@supplier_Url", inpSupplierUrl.Text);
    dbConnection.AddParameter("@supplier_Memo", ContentSupplierMemo);
    dbConnection.AddParameter("@supplier_Id", int.Parse(valueSupplierId.Text));

    _ = dbConnection.UpdateMySqlDataRecord();
    DataTable dtSupplierCodes = dbConnection.LoadMySqlData();
    SupplierCode_DataGrid.DataContext = dtSupplierCodes;
    SupplierCode_DataGrid.SelectedIndex = int.Parse(valueSupplierId.Text) - 1;
    SupplierCode_DataGrid.Focus();
}

2. 修改富文本加载逻辑

调整加载时的文档处理逻辑,确保RTF能正确写入:

private void SupplierCode_DataGrid_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    DataGrid dataGrid = (DataGrid)sender;
    if (dataGrid.SelectedItem is not DataRowView Row_Selected)
    {
        return;
    }

    valueSupplierId.Text = Row_Selected["supplier_Id"].ToString();
    inpSupplierCode.Text = Row_Selected["supplier_Code"].ToString();
    inpSupplierName.Text = Row_Selected["supplier_Name"].ToString();
    inpSupplierAddress1.Text = Row_Selected["supplier_Address1"].ToString();
    inpSupplierAddress2.Text = Row_Selected["supplier_Address2"].ToString();
    inpSupplierZip.Text = Row_Selected["supplier_Zip"].ToString();
    inpSupplierCity.Text = Row_Selected["supplier_City"].ToString();
    inpSupplierUrl.Text = Row_Selected["supplier_Url"].ToString();
    
    string ContentSupplierMemo = Row_Selected["supplier_Memo"].ToString();
    inpSupplierMemo.Document.Blocks.Clear();
    
    if (!string.IsNullOrEmpty(ContentSupplierMemo))
    {
        // 和存储时对应使用UTF8编码
        byte[] byteArray = Encoding.UTF8.GetBytes(ContentSupplierMemo);
        using (MemoryStream ms = new(byteArray))
        {
            // 直接加载到新的FlowDocument再赋值,避免空范围问题
            FlowDocument doc = new FlowDocument();
            TextRange tr = new TextRange(doc.ContentStart, doc.ContentEnd);
            tr.Load(ms, DataFormats.Rtf);
            inpSupplierMemo.Document = doc;
        }
    }
}

3. 可选优化

如果你的业务场景中富文本包含大量特殊格式,可将MySQL中存储字段从LONGTEXT改为BLOB类型,直接存储RTF的字节流,跳过字符串编码转换环节,彻底避免编码导致的内容损坏问题。

内容的提问来源于stack exchange,提问作者Herbert Nijkamp

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.11 10:18:03