如何在Windows Forms窗体间持久传递C# Credentials认证对象
Windows Forms 跨窗体传递认证凭证的解决方案
方法一:构造函数传递(推荐,符合依赖注入思想)
步骤1:确认Credentials类定义正确
确保你的Credentials是引用类型(类),属性具备正确的读写权限:
public class Credentials { public string Username { get; set; } public string Password { get; set; } }
步骤2:修改MainMenu的构造函数
在MainMenu窗体中添加接收Credentials的构造函数,将凭证存储为类级别的字段,方便后续所有方法调用:
public partial class MainMenu : Form { private readonly Credentials _userCredentials; // 带凭证参数的构造函数 public MainMenu(Credentials credentials) { InitializeComponent(); _userCredentials = credentials; // 可选:调试时验证是否获取到值 // MessageBox.Show($"当前登录用户:{_userCredentials.Username}"); } // 保留私有无参构造函数(仅用于窗体设计器,运行时不要直接调用) private MainMenu() { InitializeComponent(); } // 示例:在主菜单功能中使用凭证 private void ExecuteADOperation_Click(object sender, EventArgs e) { using (PrincipalContext pc = new PrincipalContext(ContextType.Domain, "DOMAIN REDACTED")) { bool isValid = pc.ValidateCredentials(_userCredentials.Username, _userCredentials.Password); // 执行后续AD操作... } } }
步骤3:在LoginMenu中传入验证后的凭证
修改登录按钮事件,将验证通过的auth对象传入MainMenu的构造函数:
void ButtonLogin_Click_1(object sender, EventArgs e) { Credentials auth = new() { Username = textBoxUsername.Text, Password = textBoxPassword.Text }; try { using (PrincipalContext pc = new PrincipalContext(ContextType.Domain, "DOMAIN REDACTED")) { bool isValid = pc.ValidateCredentials(auth.Username, auth.Password); if (isValid) { this.Hide(); // 传入凭证对象创建MainMenu实例 var mainmenu = new MainMenu(auth); mainmenu.FormClosed += (s, args) => this.Close(); mainmenu.Show(); } else { MessageBox.Show("登录失败,请检查用户名和密码后重试。"); auth.Username = string.Empty; auth.Password = string.Empty; } } } catch (Exception ex) { MessageBox.Show($"登录出错:{ex.Message}"); } }
方法二:全局静态类存储(适合多窗体频繁共享凭证)
如果应用内多个窗体都需要使用凭证,可创建全局静态类统一存储:
public static class AppGlobal { // 存储当前登录用户的凭证 public static Credentials CurrentUserCredentials { get; set; } }
登录验证通过后赋值:
if (isValid) { AppGlobal.CurrentUserCredentials = auth; this.Hide(); var mainmenu = new MainMenu(); mainmenu.FormClosed += (s, args) => this.Close(); mainmenu.Show(); }
在任意窗体中直接调用:
private void SomeFunction_Click(object sender, EventArgs e) { var credentials = AppGlobal.CurrentUserCredentials; if (credentials != null) { // 使用凭证执行操作 } }
常见问题排查
如果之前构造函数传递后凭证为空,检查以下几点:
- 确认
Credentials是**类(class)**而非结构体(struct),结构体是值类型,传递时会生成副本(虽不影响本次场景,但类更适合作为数据载体)。 - 检查MainMenu的构造函数是否正确将传入的对象赋值给类字段,而非重新创建空的Credentials实例。
- 验证LoginMenu中
textBoxUsername.Text和textBoxPassword.Text在点击登录时确实有输入值(可添加调试输出确认)。
内容的提问来源于stack exchange,提问作者SignalRaptor
相关产品推荐
相关产品推荐

