maintain AD(将一个账号移动到另一个群组)

本文介绍了一种使用C#在Web应用程序中实现AD域用户和组管理的方法,包括用户列表展示、组成员添加、移除及保存等功能。通过DirectoryEntry和DirectorySearcher类操作AD域,实现了动态获取和更新用户及组信息。

using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Web;
using System.Web.SessionState;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
using System.DirectoryServices;
using ActiveDs;
using System.Text;
using System.Data.SqlClient;
using System.Security.Principal;
namespace ACDR
{

 public class domain : System.Web.UI.Page
 {
  protected System.Web.UI.WebControls.Button btnadd;
  protected System.Web.UI.WebControls.Button btnremove;
  protected System.Web.UI.WebControls.Button btnsave;
  protected System.Web.UI.WebControls.ListBox lstall;
  protected System.Web.UI.WebControls.ListBox lstgroup;
  protected System.Web.UI.WebControls.DropDownList DrpGroup;
  private void Page_Load(object sender, System.EventArgs e)
  {
   //DirectoryEntry de=new DirectoryEntry("LDAP://DC=aopen,DC=com");
  
   
   if (Session["Uid"]==null)
   {
    //Response.Write(Session["Uid"]);
     Response.Redirect("logon.aspx");
   }
   DirectoryEntry domain = new DirectoryEntry("LDAP://DC=Hipro,DC=com");
             
   //int usr=(int) domain.Properties[""]
   
   if(!Page.IsPostBack)
   {

//    string tab = "    ";
//    foreach(string key in domain.Properties.PropertyNames)
//    {
//     Response.Write(tab + key + " = ");
//    }
                //groups
//    
    btnadd.Enabled=false;
    btnremove.Enabled=false;
    btnsave.Enabled=false;
    DirectorySearcher src = new DirectorySearcher(domain,"(objectCategory=group)");
    //int val = (int) (ActiveDs.ADS_GROUP_TYPE_ENUM.ADS_GROUP_TYPE_GLOBAL_GROUP);    
    //string query = "(&(objectCategory=group)(groupType:1.2.840.113556.1.4.804:=" + val.ToString() + "))";
    int val = (int) (ActiveDs.ADS_GROUP_TYPE_ENUM.ADS_GROUP_TYPE_GLOBAL_GROUP| ActiveDs.ADS_GROUP_TYPE_ENUM.ADS_GROUP_TYPE_SECURITY_ENABLED);
    string query = "(&(objectCategory=group)(groupType=" + val.ToString() + "))";

    src.Filter = query;
    
    ListItem item=new ListItem("","");
    DrpGroup.Items.Add(item);
    foreach(SearchResult res in src.FindAll())
    {
     //Response.Write(res.Path);
     string strFilter="I";
     DirectoryEntry group = new DirectoryEntry(res.Path);
     if(group.Properties["sAMAccountName"].Value.ToString().ToUpper().IndexOf(strFilter)>=0)
     {
      item=new ListItem(group.Properties["sAMAccountName"].Value.ToString(),res.Path);
      DrpGroup.Items.Add(item);
     }
    }
      //users
    DirectorySearcher dirsearcher = new DirectorySearcher(domain);
    //dirsearcher.Filter = ("(objectclass = user)");
    dirsearcher.Filter ="(&(objectclass=user)(objectcategory=person))";
    dirsearcher.SearchScope = SearchScope.Subtree;
    dirsearcher.Sort =new SortOption("sAMAccountName", SortDirection.Ascending ); //Sort by Name
    foreach (SearchResult result in dirsearcher.FindAll())
    {
     DirectoryEntry de = result.GetDirectoryEntry();
                  
     //sb.Append("UserName: ");
     item=new ListItem(de.Properties["sAMAccountName"].Value.ToString(),de.Path);
    
     lstall.Items.Add(item);
     //sb.Append("<br />");
    }
     
   }

  }
   
 
  #region Web Form 設計工具產生的程式碼
  override protected void OnInit(EventArgs e)
  {
   //
   // CODEGEN: 此為 ASP.NET Web Form 設計工具所需的呼叫。
   //
   InitializeComponent();
   base.OnInit(e);
  }
  
  /// <summary>
  /// 此為設計工具支援所必須的方法 - 請勿使用程式碼編輯器修改
  /// 這個方法的內容。
  /// </summary>
  private void InitializeComponent()
  {   
   this.DrpGroup.SelectedIndexChanged += new System.EventHandler(this.DrpGroup_SelectedIndexChanged);
   this.btnsave.Click += new System.EventHandler(this.btnsave_Click);
   this.btnadd.Click += new System.EventHandler(this.btnadd_Click);
   this.btnremove.Click += new System.EventHandler(this.btnremove_Click);
   this.Load += new System.EventHandler(this.Page_Load);

  }
  #endregion


  private void DrpGroup_SelectedIndexChanged(object sender, System.EventArgs e)
  {
   lstgroup.Items.Clear();
   if(DrpGroup.SelectedIndex!=0)
   {
    btnadd.Enabled=true;
    btnremove.Enabled=true;
    btnsave.Enabled=true;
    DirectoryEntry group = new DirectoryEntry(DrpGroup.SelectedValue);
    object members = group.Invoke("members",null);
    ListItem item;    
    foreach( object member in (IEnumerable) members)
    {
     DirectoryEntry x = new DirectoryEntry(member);     
     item=new ListItem(x.Properties["sAMAccountName"].Value.ToString(),x.Path);
     lstgroup.Items.Add(item);
    }

   }
   else
   {
    btnadd.Enabled=false;
    btnremove.Enabled=false;
    btnsave.Enabled=false;
   }
   
  }

  private void btnadd_Click(object sender, System.EventArgs e)
  {
      bool Flg=true;
   int j;
   foreach(ListItem item in lstall.Items)
   {
    if(item.Selected)
    {
     Flg=true;
     for (j=0;j<= lstgroup.Items.Count-1;j++)
     {
      if (lstgroup.Items[j].Value==item.Value)//如果右邊框已經有選中的item則不添加過去,沒有則添加過去
      {
       Flg=false;
       break;
      }
     }
     if(Flg==true){
      lstgroup.Items.Add(new ListItem (item.Text,item.Value));}
    }
   }
  }

  private void btnremove_Click(object sender, System.EventArgs e)
  {
      int count=lstgroup.Items.Count;
   int i=count-1;
   while(i>-1)
   {
             ListItem item=lstgroup.Items[i];
    if(item.Selected)
    {
           lstgroup.Items.RemoveAt(i);
    }
     i=i-1;
   }
  }

  //保存users到group
  private void btnsave_Click(object sender, System.EventArgs e)
  {
   //remove users from group
   if(DrpGroup.SelectedIndex!=0)
   {
    try
    {
     DirectoryEntry group= new DirectoryEntry(DrpGroup.SelectedValue,"Administrator","");

     object members = group.Invoke("members",null);
     foreach( object member in (IEnumerable) members)
     {
      DirectoryEntry x = new DirectoryEntry(member);
      String userDN = x.Properties["distinguishedName"].Value.ToString();
      group.Properties["member"].Remove(userDN);
      group.CommitChanges();
     }
     //add users
     foreach(ListItem item in lstgroup.Items)
     {
      DirectoryEntry x = new DirectoryEntry(item.Value);
      group.Properties["member"].Add(x.Properties["distinguishedName"].Value);
      //Commit the changes to the directory.     
      group.CommitChanges();
     }
     Response.Write("<script>alert('AD Account Modify Success!');</script>");
    }
    catch(Exception ex)        
     {
     //Response.Write(ex.ToString() );
     Response.Write("<script>alert('AD Account Modify Fail,Pls Contact Your Administrator Error:'+ '" + ex.Message+"');</script>");
     
     //throw new Exception( ex.Message);
     }
     
    }
  }


 }

}

转载于:https://www.cnblogs.com/yeskele/archive/2005/09/16/238322.html

<think>我们正在处理一个SAP BAPI调用创建工艺路线时报错的问题,错误提示需要输入一个操作号。根据SAP工艺路线创建的逻辑,操作号(Operation Number)是工艺路线中的关键字段,每个操作步骤都需要一个唯一的操作号。 可能的原因和解决方案如下: 1. **操作号未按顺序递增**:在创建工艺路线时,操作号必须是递增的,且不能有跳跃。例如,第一个操作号是10,下一个必须是大于10的数(如20),而不能是5。如果系统检测到操作号不连续或重复,可能会要求输入一个操作号。 - 解决方案:检查并确保操作号是递增的,且没有重复。 2. **遗漏了某个操作步骤**:在创建工艺路线时,可能遗漏了某个操作步骤,导致操作号序列出现空缺。例如,已有操作10和30,但缺少20,此时系统可能会提示需要输入操作20。 - 解决方案:检查操作序列,确保没有遗漏操作步骤。 3. **BAPI参数传递错误**:在调用BAPI(如`BAPI_ROUTING_CREATE`)时,传递的操作号列表(如`OPERATION`内表)可能没有按正确的顺序或缺少必要的操作号。 - 解决方案:检查传递给BAPI的操作号列表,确保其连续且递增。 4. **标准操作号配置问题**:在SAP中,工艺路线的操作号可以通过配置自动生成(如配置增量),但如果在BAPI调用中未指定自动生成操作号,则必须显式提供。 - 解决方案:检查是否需要在调用BAPI时设置自动生成操作号的标志,或者显式提供递增的操作号。 具体步骤: 1. **检查操作号序列**:在调用BAPI之前,确保你的操作内表(如`OPERATION`)中的操作号(字段`OPERATION`)是递增的,且没有空缺。例如,操作号序列应为10,20,30,... 或 1,2,3,...。 2. **检查BAPI调用参数**:确认在调用BAPI时,是否传递了正确的参数。特别是,操作内表中的每个操作步骤都必须有一个唯一的操作号。 3. **使用自动生成操作号功能**:如果不想手动管理操作号,可以尝试使用SAP提供的自动生成操作号功能。在调用BAPI时,设置相关标志(如`AUTOMATIC_OPERATION_NUMBERS`)为'X',让系统自动分配操作号。但请注意,不是所有BAPI都支持此功能,需要查阅具体BAPI的文档。 4. **查看错误详细信息**:当BAPI调用返回错误时,SAP通常会返回一个消息表(`RETURN`表)。检查该表中的具体错误消息,以确定是哪个操作号缺失。例如,错误消息可能会明确提示“需要操作号20”。 5. **调试**:如果上述方法无效,可以在调用BAPI时设置断点进行调试,检查传入的操作内表数据是否正确。 示例代码(伪代码): 假设使用`BAPI_ROUTING_CREATE`创建工艺路线,操作内表为`lt_operation`,其中必须包含递增的操作号。 如果使用自动生成操作号: ```abap DATA: ls_header TYPE bapi1012_rou_header, lt_operation TYPE TABLE OF bapi1012_oper, lt_return TYPE TABLE OF bapiret2. ls_header-material = 'MAT001'. ls_header-plant = '1000'. ls_header-automatic_operation_numbers = 'X'. " 自动生成操作号 " 添加操作步骤,此时可以不指定操作号(OPERATION字段留空)或者指定为0,系统会自动生成 APPEND INITIAL LINE TO lt_operation ASSIGNING FIELD-SYMBOL(<op>). <op>-activity = '0010'. " 其他必要字段 " ... 其他操作 CALL FUNCTION 'BAPI_ROUTING_CREATE' EXPORTING header = ls_header TABLES operation = lt_operation return = lt_return. " 检查返回消息 READ TABLE lt_return WITH KEY type = 'E' TRANSPORTING NO FIELDS. IF sy-subrc = 0. " 存在错误,处理错误 ELSE. CALL FUNCTION 'BAPI_TRANSACTION_COMMIT'. ENDIF. ``` 如果手动指定操作号,确保操作号连续递增: ```abap " 手动指定操作号,必须递增且不重复 APPEND INITIAL LINE TO lt_operation ASSIGNING <op>. <op>-operation = '0010'. " 操作号10 <op>-activity = '0010'. " ... 其他字段 APPEND INITIAL LINE TO lt_operation ASSIGNING <op>. <op>-operation = '0020'. " 下一个操作号20 <op>-activity = '0020'. " ... 其他字段 ``` 注意:以上代码仅为示例,具体字段和BAPI参数请参考SAP官方文档。 如果问题仍然存在,请提供具体的BAPI名称和错误消息的完整内容,以便进一步分析。 相关问题: 1. 如何调试SAP BAPI调用时的错误? 2. 在SAP中创建工艺路线需要哪些必备字段? 3. 如何配置SAP工艺路线的操作号自动生成?</think>针对SAP调用BAPI创建工艺路线时出现"需要输入一个操作号"的报错问题,以下是系统化的解决方案和关键排查点: --- ### **一、核心问题分析** 该错误通常发生在工艺路线创建时**操作序列不连续**或**操作号冲突**。工艺路线(Routing)要求操作号(Operation Number)必须满足: 1. 严格递增序列(如10→20→30) 2. 无重复操作号 3. 无跳跃间隔(如10→30缺少20) --- ### **二、解决方案步骤** #### **1. 检查操作号连续性** - 在BAPI调用前,**手动验证操作号序列**: ```abap DATA: lt_operation TYPE TABLE OF bapi1012_oper. " 假设操作号数据已填充到lt_operation SORT lt_operation BY operation. LOOP AT lt_operation ASSIGNING FIELD-SYMBOL(<op>) FROM 1 TO lines( lt_operation ) - 1. IF <op>-operation + 10 <> <op>+1-operation. " 检查是否间隔10 MESSAGE '操作号不连续' TYPE 'E'. ENDIF. ENDLOOP. ``` #### **2. 启用自动操作号生成** 在BAPI参数中强制系统自动生成操作号: ```abap DATA: ls_header TYPE bapi1012_rou_header. ls_header-automatic_operation_numbers = 'X'. " 关键参数 CALL FUNCTION 'BAPI_ROUTING_CREATE' EXPORTING header = ls_header TABLES operation = lt_operation return = lt_return. ``` #### **3. 处理子操作(Sub-Operation)** 若工艺路线包含子操作(如质检步骤): - 主操作号必须存在(如0010) - 子操作号需在**主操作号范围内**(如0010.001) - 使用字段 `SUB_OPERATION` 明确标识: ```abap <op>-operation = '0010'. " 主操作 <op>-sub_operation = '0001'. " 子操作 ``` #### **4. 验证参考工艺路线** 当使用`REFERENCE_ROUTING`参数复制现有工艺路线时: - 检查参考工艺路线的操作号是否连续 - 确保参考工艺路线状态为`4`(已释放) --- ### **三、关键排查点** | 检查项 | 正确示例 | 错误示例 | 解决方法 | |-----------------------|--------------|--------------|------------------------| | 操作号递增 | 10,20,30 | 10,30,20 | 排序操作号 | | 子操作归属 | 10.001,10.002| 10.001,20.001| 确保子操作号归属同一主操作 | | 自动生成标志 | `AUTOMATIC_OPERATION_NUMBERS = 'X'` | 未设置该参数 | 添加标志并置空操作号字段 | | 参考工艺路线状态 | Status=4 (Released) | Status=1 (Created) | 释放参考工艺路线 | --- ### **四、补充建议** 1. **使用BAPI`BAPI_ROUTING_MAINTAIN`替代创建接口** 该BAPI内置操作号校验逻辑,容错性更强 2. **捕获详细错误信息** 通过`RETURN`表获取具体错误位置: ```abap READ TABLE lt_return WITH KEY type = 'E'. IF sy-subrc = 0. WRITE: / '错误:', lt_return-message. ENDIF. ``` 3. **检查工艺路线计数器** 确保`GROUP_COUNTER`字段在相同内操作号唯一 > 提示:SAP工艺路线操作号设计遵循等差数列规则(通常间隔10),预留中间号便于后期插入操作[^1]。 --- ### **相关问题** 1. 如何通过BAPI批量修改SAP工艺路线的操作顺序? 2. SAP工艺路线中子操作(Sub-Operation)的配置标准是什么? 3. 使用BAPI维护工艺路线时如何避免状态锁定(Lock State)问题?
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值