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

Blazor中使用EditForm结合C#和PostgreSQL插入数据失败求助

Blazor EditForm 数据无法插入PostgreSQL的问题修复

问题根源梳理

  1. 数据来源错误:你在Razor代码里单独定义了空的username、password、email字段,但插入数据库时调用的是这些空值,而非绑定了用户输入的Register2模型属性,这是数据插不进去的核心原因。
  2. 模型职责越界:Register2的构造函数里硬编码执行插入操作,每次实例化模型都会往数据库插一条固定测试数据,完全违背了模型仅作为数据载体的职责。
  3. 同步操作阻塞UI:Blazor中使用同步数据库操作会卡住页面,应该改用异步方法。
  4. 语法错误:Razor代码里private string pass = "hidden"末尾缺少分号,直接导致编译报错。
  5. 无错误捕获机制:出现异常时无法定位具体问题,不利于排查。
  6. 密码明文存储:直接存储明文密码存在严重安全隐患。

修复后的代码

1. 精简后的Register2模型(仅做数据载体)

namespace Login.Models;

// 模型仅用于承载表单数据,数据库操作单独抽离
public class Register2
{
    public string Username { get; set; } = string.Empty;
    public string Password { get; set; } = string.Empty;
    public string Email { get; set; } = string.Empty;
}

2. 修正后的Razor注册页面

@page "/register"
@using Login.Models;
@using Npgsql;
@using BCrypt.Net;
@inject NavigationManager NavigationManager
@inject ILogger<Register> Logger

<PageTitle>Register</PageTitle>

<EditForm Model="RegisterModel" OnValidSubmit="RegisterFormAsync" FormName="Register" Enhance>
    <DataAnnotationsValidator />
    <ValidationSummary />

    <label for="username">用户名:</label>
    <InputText id="username" @bind-Value="RegisterModel.Username" class="form-control mb-2"/>

    <label for="email">邮箱:</label>
    <InputText id="email" @bind-Value="RegisterModel.Email" class="form-control mb-2"/>

    <label for="password">密码:</label>
    <InputText type="password" id="password" @bind-Value="RegisterModel.Password" class="form-control mb-2"/>

    <button type="submit" class="btn btn-primary">注册</button>
</EditForm>

@code
{
    [SupplyParameterFromForm] 
    private Register2 RegisterModel { get; set; } = new();
    
    // 建议从appsettings.json读取连接字符串,此处为示例硬编码
    private readonly string _connectionString = "host=localhost;username=postgres;password=NewPass123;database=individual_assignment_db";
    private const string _tableName = "users";

    private async Task RegisterFormAsync()
    {
        try
        {
            using var connection = new NpgsqlConnection(_connectionString);
            await connection.OpenAsync();

            // 参数化查询,防止SQL注入
            var insertSql = $@"INSERT INTO {_tableName}(username, email, password) VALUES(@Username, @Email, @PasswordHash)";
            
            using var cmd = new NpgsqlCommand(insertSql, connection);
            // 使用模型中绑定的用户输入数据
            cmd.Parameters.AddWithValue("@Username", RegisterModel.Username);
            cmd.Parameters.AddWithValue("@Email", RegisterModel.Email);
            // 密码哈希处理(需先安装BCrypt.Net NuGet包)
            var passwordHash = BCrypt.HashPassword(RegisterModel.Password);
            cmd.Parameters.AddWithValue("@PasswordHash", passwordHash);

            await cmd.ExecuteNonQueryAsync();
            
            NavigationManager.NavigateTo("/User");
        }
        catch (Exception ex)
        {
            Logger.LogError(ex, "注册时插入数据库失败");
            // 可在此添加用户可见的错误提示,比如弹窗或页面文本
        }
    }
}

额外优化建议

  • 连接字符串存入配置文件:将数据库连接字符串写入appsettings.json,通过IConfiguration注入,避免硬编码。
  • 添加数据验证:给Register2的属性添加[Required]、[EmailAddress]等数据注解,配合DataAnnotationsValidator实现前端输入校验。
  • 抽离数据库操作逻辑:把插入等数据库操作放到单独的仓储类中,遵循单一职责原则,便于后续维护和测试。
  • 强制密码哈希:必须使用BCrypt、Argon2等强哈希算法存储密码,绝对禁止明文存储。

内容的提问来源于stack exchange,提问作者Nick Gatsfield

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 23:44:59