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

C# 如何在点击事件中批量调用多个ActiveDirectory方法以精简代码?

优化方案

当前写法的核心问题如下:

  • 重复传递searchUsernametxt.Text参数,冗余度高
  • 每次新增AD属性查询都要新增一行调用语句,代码会越来越臃肿
  • 多数AD查询方法的底层逻辑都是读取域用户属性,多次调用会重复发起AD查询请求,性能损耗大
  • UI交互、参数校验、业务查询逻辑耦合在同一个事件方法里,后续维护成本高

方案1:封装统一批量查询方法(性价比最高,改造成本低)

步骤1:定义AD用户信息存储实体

public class AdUserInfo
{
    public string SamAccountName { get; set; }
    public bool IsUserEnabled { get; set; }
    public Guid ObjectGuid { get; set; }
    public string Sid { get; set; }
    public DateTime? PasswordExpirationDate { get; set; }
    public bool IsLockedOut { get; set; }
    public string EmployeeId { get; set; }
    public string CusAtt1 { get; set; }
    public string CusAtt2 { get; set; }
    public string CusAtt3 { get; set; }
    public string CusAtt4 { get; set; }
}

步骤2:在ActiveDirectory工具类中新增批量查询方法

只需要发起一次AD查询,一次性读取所有需要的用户属性,返回上面定义的实体对象即可,原有单个查询方法可以保留兼容其他场景调用。

public static AdUserInfo GetUserAllInfo(string userName)
{
    // 原有判断用户存在的逻辑可以合并到这里,不存在直接返回null即可
    if (!DoesUserExist(userName)) return null;
    
    // 一次性查询所有需要的属性,填充AdUserInfo对象返回
    return new AdUserInfo
    {
        SamAccountName = // 读取对应AD属性赋值
        // 其他属性依次赋值即可
    };
}

步骤3:改造点击事件代码

private void metroButton1_Click(object sender, EventArgs e)
{
    // 控件状态操作封装成单独方法
    DisableAllInputTextBox();
    
    // 参数校验
    if (string.IsNullOrWhiteSpace(searchUsernametxt.Text))
    {
        MessageBox.Show("Domain or Username has not been completed, Please try again!",
            "Validation Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
        return;
    }
    
    // 一次性查询所有用户信息
    var userInfo = ActiveDirectory.GetUserAllInfo(searchUsernametxt.Text);
    if (userInfo == null) return;
    
    // 统一给控件赋值
    samAccountNametxt.Text = userInfo.SamAccountName;
    userenabledtxt.Text = userInfo.IsUserEnabled.ToString();
    GUIDtxt.Text = userInfo.ObjectGuid.ToString();
    SIDtxt.Text = userInfo.Sid;
    passlstsettxt.Text = userInfo.PasswordExpirationDate?.ToString("yyyy-MM-dd HH:mm") ?? "无";
    metroCheckBox1.Checked = userInfo.IsLockedOut;
    employeeidtxt.Text = userInfo.EmployeeId;
    cusatt1txt.Text = userInfo.CusAtt1;
    cusatt2.Text = userInfo.CusAtt2;
    cusatt3.Text = userInfo.CusAtt3;
    cusatt4.Text = userInfo.CusAtt4;
}

private void DisableAllInputTextBox()
{
    foreach (MetroFramework.Controls.MetroTextBox item in groupBox1.Controls
        .OfType<MetroFramework.Controls.MetroTextBox>())
    {
        item.Enabled = false;
    }
}

如果后续需要新增属性查询,只需要:

  1. 在AdUserInfo实体中新增对应字段
  2. 在GetUserAllInfo方法中补充属性读取逻辑
  3. 最后在赋值部分加一行控件赋值即可,不需要额外新增AD调用方法

方案2:进一步简化赋值逻辑(适合后续会新增大量属性的场景)

可以提前配置属性和控件的映射关系,用遍历自动赋值,后续新增属性只需要加一行映射配置即可,不需要修改赋值逻辑:

// 提前定义映射关系
private readonly Dictionary<Func<AdUserInfo, object>, Control> _adPropertyControlMap = new()
{
    {u => u.SamAccountName, samAccountNametxt},
    {u => u.IsUserEnabled, userenabledtxt},
    {u => u.ObjectGuid, GUIDtxt},
    // 其他映射依次添加即可
};

// 赋值时直接遍历
foreach (var map in _adPropertyControlMap)
{
    var value = map.Key(userInfo)?.ToString() ?? string.Empty;
    if (map.Value is CheckBox chk) chk.Checked = Convert.ToBoolean(value);
    else map.Value.Text = value;
}

内容的提问来源于stack exchange,提问作者Tom Dobing

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 07:39:02