天天看点

Introduction to System.DirectoryServices.Protocols (S.DS.P) 系统目录服务协议类库——部分翻译Introduction to System.DirectoryServices.Protocols (S.DS.P)介绍系统目录服务协议类库

Introduction to System.DirectoryServices.Protocols (S.DS.P)介绍系统目录服务协议类库

Establishing an LDAP Connection(建立一个LDAP连接)

Request and Response Classes(请求响应类)

A fundamental part of interacting withadirectory service via LDAP is creating and sending requests andreceivingresponses. The synchronous S.DS.P method for sending a request is SendRequest.A directory server thenreturns a response that you can cast into theappropriate response object.

通过LDAP与目录服务交互的一个基本组成部分是创建、发送请求和接收响应。同步S.DS.P方法是SendRequest发送请求。目录服务器返回的响应,你可以丢在适当的响应对象。

When you call the SendRequest methodofan LdapConnection, the method ships an LDAP operation to adirectoryserver and the server returns aDirectoryResponseobject. Theobject returned aligns in structure with the type of request. Forexample, ifyou supply the SendRequest method with an AddRequest object,the directory serverreturns a DirectoryResponse objectthat isstructurally equivalent to an AddResponseobject. You must then castthe returned DirectoryResponse base classinto an AddResponse objectbeforeyou inspect the response. The pattern for this is: 

当你调用LdapConnection的SendRequest方法,该方法对目录服务运行一个Ldap操作并且这个服务返回一个DirectoryResponse的对象。返回的对象与其请求的类型在结构上是一致的。例如,如果你提供带有AddRequest对象的SendRequest方法,目录服务返回一个DirectoryResponse对象,在结构上相当于一个AddResponse对象。在你检查响应之前,你必须把返回的DirectoryResponse基类投射到一个AddResponse对象。该模式是:

DirectoryRequestType request = new DirectoryRequestType(parameters…);
DirectoryResponseType response = (DirectoryResponseType)connection.SendRequest(request);

           

The following code snippet demonstrates how to implement this pattern using the AddRequest and AddResponse objects. The values of the dn and dirClassType are defined elsewhere and are not shown here to avoid obscuring the pattern:

下面的代码片断演示了如何使用AddRequest和AddResponse对象实现这种模式。dn和dirClassType的值定义在其他地方,这里没有显示,以避免混淆模式:

// build an addrequest object 创建一个 AddRequest对象
AddRequest addRequest = new AddRequest(dn, dirClassType);
                
// cast the response into an AddResponse object to get the response 把响应变成一个AddResponse对象来获取响应
AddResponse addResponse = (AddResponse)connection.SendRequest(addRequest);


           

The following request classes map to the listed response classes appearing in Table 1:

以下请求类映射到出现在表1中的列出的响应类:

Table 1. DirectoryRequest and Corresponding DirectoryResponse Classes

表1: 目录请求类与对应的目录响应类

Introduction to System.DirectoryServices.Protocols (S.DS.P) 系统目录服务协议类库——部分翻译Introduction to System.DirectoryServices.Protocols (S.DS.P)介绍系统目录服务协议类库

The .NET Framework SDK Class Library Reference describes the purpose of each request and response class. In addition, I demonstrate how to use all of these request objects except the last two DSML request objects. For more information on S.DS.P architecture, see "System.DirectoryServices.Protocols Architecture" at http://msdn2.microsoft.com/en-us/library/ms257187.aspx.

这个.NET 框架 SDk类库参考描述每个请求和响应的目的类。此外,我将演示如何使用所有这些请求的对象,除了最后两个DSML请求对象。对于S.DS.P架构的更多信息,请参阅“系统目录服务协议体系结构”http://msdn2.microsoft.com/en-us/library/ms257187.aspx.

Management Tasks 管理任务

Common directory services management tasks include creating, adding, moving, modifying and deleting directory objects. While S.DS provides all of these capabilities, S.DS.P allows you to use common LDAP programming constructs to perform the same tasks. S.DS is easier for these code tasks, but seeing how to complete these familiar tasks with S.DS.P is a great way to introduce key members of this namespace.

常见的目录服务管理任务包括创建,增加,移动,修改,删除目录对象。虽然S.DS 提供所有这些功能,S.DS.P允许你使用常见的LDSP编程构造来执行相同的任务。S.DS更容易进行这些代码的任务,但是现在看看,如果用S.DS.P完成这些类似的任务,S.DS.P是强大的途径来介绍这些命名空间的关键成员。

LDAP Directory Management Tasks LDAP目录管理任务

Code examples in this section will build on one another to familiarize you with the common patterns. For instance, the first example will show you how to create 100 user accounts in just a few lines of code by using the AddRequest object, but it won't show you how to get a response back about the task from a directory server. The next example returns to the essence of the first create users task by demonstrating how to add any valid object to the directory, and it also shows how to get a response back about the task. A later example introduces you to the ModifyRequest object for managing an attribute, but it doesn't demonstrate how to get a response back about whether the attribute was successfully modified. Immediately following that example, I introduce the ModifyResponse object. This incremental approach, I believe, will help you better understand how to build on the examples to create more complex and useful code.

本节中的代码示例将建立在彼此熟悉的常见模式。例如,第一个例子将告诉你,如何在短短的几行代码中,使用AddRequest对象创建100个用户帐号,但是它不会告诉你如何从目录服务器的任务得到响应。下一个例子返回第一次创建用户任务的本质,通过演示如何增加一些有效的对象目录,这也说明了如何得到响应的任务。后面的例子向您介绍ModifyRequest对象的属性管理,但这并不说明如何得到一个响应返回的属性是否被成功修改。紧跟着,示例中,我将介绍ModifyResponse对象。我相信,这种循序渐进的方式,将会帮助你更好的理解如何构建示例来创建更复杂和有用的代码。

Creating Users Accounts  创建用户帐号

A classic initial demonstration of directory services programming techniques often involves generating many user accounts with only a few lines of code. As S.DS.P is arguably the most radical departure from traditional directory services coding in the .NET Framework, I think a multi-user creation example is a good starting point. I think you would agree that it's more useful than writing Hello World to an attribute!

一个经典的初始目录服务编程技术示范通常包括生成许多用户帐户,只需要几行代码。由于S.DS.P从传统的编码。NET框架中的目录服务可以说是最根本的出发,我认为一个多用户创建的例子是一个很好的起点。我想你会同意,这比编写Hello World的属性更有用!

The following code example demonstrates how to create 100 user accounts in just a few lines of code:

下面的代码示例演示了如何创建100个用户账户在短短几行代码:

  1. Establish an LDAP connection to a directory server.

    建立LDAP连接到目录服务器 

    In an Active Directory domain, the Locator service provides the host name of a domain controller in the specified domain for the connection.

    在ActiveDirectory域,定位器服务提供的连接在指定的域的域控制器的主机名。

  2. Declare and initialize the dn variable with the distinguishedName value of each user account to create.

    声明并初始化distinguishedName值,每个用户帐户创建的DN变量。

  3. Call the SendRequest method of the connection object to transport each request to a directory server.

    调用SendRequest连接对象的方法,运送到目录服务器的每个请求。

    You pass a directory request (in this case an AddRequest) to the SendRequest method. TheSendRequest method then automatically binds to a domain controller in the targeted domain using the current user's credentials.  

    你传递一个目录请求(在这种情况下,一个AddRequest)的SendRequest方法。SendRequest方法自动绑定到在目标域使用当前用户凭证的域控制器。

Example 1. Creating 100 user accounts

示例1.创建100个用户帐户。

LdapConnection connection = new LdapConnection("fabrikam.com");
for (int i = 1; i <= 101; i++)
{
    string dn = "cn=user" + i + ",ou=UserAccounts,dc=fabrikam,dc=com";
    connection.SendRequest(new AddRequest(dn, "user"));
}

           

If you were to run this code, you wouldn't get any return results and the user accounts created in the fabrikam.com Active Directory domain would be disabled. Obviously, this is a pedantic example, but it effectively demonstrates that even a namespace as sophisticated as S.DS.P provides a simple and elegant model to complete significant directory management tasks.

如果你要运行此代码,你不会得到任何返回结果和用户帐户将被禁用在fabrikam.com的Active Directory域的创建。很显然,这是个迂腐的例子,但是它有效地表明,即使是一个复杂的S.DS.P的命名空间,也提供了一个简单而优雅的模型,来完成重要的目录管理任务。

Adding an Object to a Directory将对象添加到目录

As you saw in the previous create user example, when you call the SendRequest method, you pass the method an AddRequest object to create a user by the specified name. The second parameter in the AddRequest can either be an array of attributes to assign to the object or the lDAPDisplayName of the class schema object from which the object should be derived.

正如你看到的在前面创建的用户的例子,当你调用SendRequest方法,你给方法传递一个AddRequest对象来创建一个用户指定的名称。AddRequest的第二个参数可以是一个属性数组分配的对象或者对象应得的类架构对象LdapDisplayName.

In order to get a response from a directory server about the success or failure of the requested operation, you cast the returned DirectoryResponse base class into the proper response type based on the type of DirectoryRequest object you pass to theSendRequest method.

为了得到响应从目录服务器所请求的操作是成功还是失败,你投递的返回到适当的响应类型的类型的DirectoryResponse对象传递给SendRequest方法的基础上DirectoryResponse基类.

The following code example demonstrates how to add a directory object named Seasoned derived from the organizationalUnit class schema object to the directory below the techwriters ou in the fabrikam.com domain:

下面的代码示例演示了如何增加一个目录对象,命名为经验丰富的organizationalUnit类架构对象目录下面的techwriters fabrikam.com域中的OU:

  1. Declare and initialize some string variables used later in the example.

    声明和初始化在本例中使用的一些字符串变量。

    The corresponding code download allows you to pass these and other values in as command line arguments.

    下载相应的代码,使您可以通过这些和其他值作为命令行参数。

  2. Create an LdapConnection object for connecting to a domain controller in the fabrikam.com domain.

    创建一个连接到fabrikam.com域中的域控制器的LdapConnection对象。

    Because a specific domain controller was not declared for the hostordomainName variable, the Active Directory Locator will find an available domain controller for the binding operation. This is referred to as serverless binding.

    由于特定的域控制器没有声明hostordomainName变量。Active Directory定位器将找到一个可用的域控制器绑定操作。这是被称为服务器绑定。

  3. Create an AddRequest object and pass it the distinguished name stored in the dn variable and the lDAPDisplayName of the class schema object to instantiate.

    创建一个AddRequest的对象并将其传递的可分辨名称存储在dn变量,并实例化一个类结构对象LdapDisplayName,

  4. Call the SendRequest method of the connection object and cast the returned DirectoryResponse as an AddResponse object.

    调用连接对象的SendRequest方法并投射返回DirectoryResponse 作为AddResponse对象。

    An implicit bind occurs here.

    这里出现隐式绑定。

  5. Display information about the request. The response from the directory server is contained in theResultCode property of the addResponse object.

    显示有关请求的信息。从目录服务器的响应包含在AddResponse对象的ResultCode属性中。

    The AddResponse class contains an ErrorMessage response property that you can display for more information on any error that might be returned from the directory server.   

    AddResponse类包含一个错误信息的响应属性,您也许能从目录服务器返回更多的关于错误信息。

Example 2. Adding an OrganizationalUnit object 

示例2. 添加OrganizationalUnit对象

string hostOrDomainName = "fabrikam.com";
string dn = "ou=Seasoned,ou=techwriters,dc=fabrikam,dc=com";
string dirClasstype = "organizationalUnit";

// establish a connection to the directory 建立一个连接到该目录
LdapConnection connection = new LdapConnection(hostOrDomainName);

try
{
    // create an addrequest object  创建一个addrequest对象
    AddRequest addRequest = new AddRequest(dn, dirClassType);

    // cast the returned DirectoryResponse as an AddResponse object
    //将返回DirectoryResponse作为一个AddResponse对象
    AddResponse addResponse = (AddResponse)connection.SendRequest(addRequest);

    Console.WriteLine("A {0} with a dn of\n {1} was added successfully " + 
       "The server response was {2}",
        dirClassType, dn, addResponse.ResultCode);
}
catch (Exception e)
{    Console.WriteLine("\nUnexpected exception occured:\n\t{0}: {1}",
                      eGetType().Name, e.Message);
}


           

Adding an Object to a Directory Using a Different AddRequest Constructor 

 使用不同的AddRequest 的构造函数,将一个对象添加到一个目录中

Before delving into another code example, let's step back for a moment and consider how the definition of class schema objects plays an important role in directory object creation. This is essential to understand before you try to use the alternative AddRequest constructor to create directory objects.

深究另一个代码示例之前,让我们回顾一下,并考虑如何定义的类架构对象起着重要的作用在目录中创建对象。这是必须了解的,在你试图使用替代AddRequest的构造函数来创建目录对象之前。

The attributes of a class schema object define the object. A key part of that definition is the attributes that the object must or may contain. When you instantiate a directory object from a class schema object, you or the directory service must provide values for any attributes that the directory object must contain (mandatory attributes) when it is created. 

一个类架构对象的属性定义的对象。该定义的一个关键部分是对象的属性必须或者可能包含。当你从一个类架构对象实例化一个目录对象,你必须提供目录服务器创建时必须包含的属性值(强制属性)。

In the prior code example (Example 2), I demonstrate how to add an OrganizationalUnit object to the directory by using the AddRequest constructor. In that case, the constructor takes the distinguishedName of the object to create and the type of object class from which the object is derived. If you take a close look at the organizationalUnit class schema object in an Active Directory or ADAM schema, you will see that theinstanceType,objectCategory,nTSecurityDescriptor,objectClass andou attributes must be defined for the object in order for it to be created. TheorganizationalUnit class inherits from theTop schema class object, which defines the first four of those attributes as mandatory and theorganizationalUnit class defines theou attribute as mandatory. You must provide values for theou attribute and theobjectClass attribute, and directory services takes care of providing the other values.

在之前的代码示例(例2)中,我演示了如何用AddRequest构造函数增加一个OrganizationalUnit对象到目录中。 既然这样,构造函数将distinguishedName对象的创建和对象类的类型,从该对象派生。如果你仔细看organizationalUnit类模式对象在Active

Directory或ADAM模式,你将会看到instanceType, objectCategory, nTSecurityDescriptor, objectClass and ou 属性必须被定义的对象,以便它被创建。organizationalUnit类继承自Top模式类对象,它定义的前四的属性是强制的并且organizationalUnit类定义的ou属性也是必须的。你必须提供ou属性值和objectClass属性值,并且目录服务负责提供其他值。

Now that you know the mandatory attributes and who has to set what, you can make use of the AddRequest constructor that takes the distinguished name of the object you want to create and an array of DirectoryAttribute objects. The array of objects must include values for any mandatory attributes that directory services will not set for you or that are not defined as part of the distinguished name of the new object. Considering the previous organizationalUnit example, the following code snippet shows how you can define the one required directory attribute (objectClass) by creating a DirectoryAttribute object:

现在,你已经了解了强制属性,你可以使用AddRequest构造函数来设置它。该函数接收你想创建的对象的可辨别名称和 目录属性对象数组。该对象的数组必须包含强制属性的值,目录服务器不会对你或者没有定义的 新对象的可辨别名称的一部分的设置。考虑前面示例organizationalUnit,下面代码片段演示了如何定义一个所需的目录属性(对象类)创建一个DirectoryAttribute对象:

DirectoryAttribute objectClass =  new DirectoryAttribute("objectClass", "organizationalUnit");

           

You can then pass that to the AddRequest object, like so:

然后,你可以通过这样到AddRequest对象,像这样:

addRequest = new AddRequest(dn, objectClass);

           

You might notice that this doesn't add much to the prior code example ( Error! Reference source not found.). It gets more interesting when you encounter a directory object that contains more mandatory attributes, such as an object derived from the User class schema object, which also requires other mandatory attributes (i.e., sAMAccountName), or you want to add additional optional attributes to an object when it's created. In the following code snippet I define two optional attributes, the city (" l") directory attribute and description directory attribute, and pass those along with the objectClass mandatory directory attribute when I call the AddRequest constructor to create an OU:

你也许会注意到,没有增加太多的事先的代码示例(错误!未找到引用源。)。它变得更加有趣,当你遇到了一个目录对象,它包含更多的强制属性, 例如一个对象来自User  Class 模式对象,这也需要其他的强制性属性(如,sAMAccountName),或者你想添加额外的可选属性来创建一个对象的时候。在下面的代码片段,我定义了两个可选属性,城市("l")目录属性和描述目录属性,并沿用objectClass强制目录属性 ,当我调用 AddRequest构造函数创建一个OU:

DirectoryAttribute l = 
    new DirectoryAttribute("l", "Redmond");

DirectoryAttribute description = 
    new DirectoryAttribute("description", "Writers with 3 years of experience");

DirectoryAttribute objectClass =
    new DirectoryAttribute("objectClass", "organizationalUnit");

// create a DirectoryAttribute array and pass in three directory attributes
//创建DirectoryAttribute 数组并且赋值这3个目录属性
DirectoryAttribute[] dirAttribs = new DirectoryAttribute[3];
dirAttribs[0] = l;
dirAttribs[1] = description;
dirAttribs[2] = objectClass;

// create an addrequest object
//创建一个addrequest对象
addRequest = new AddRequest(dn, dirAttribs);


           

Note that there is not a corresponding code sample with the code download for this variation on creating an AddRequest object. Start with the AddObject method in the code sample and this information to create a method that uses this AddRequest constructor.

请注意,没有这种变化,创建一个AddRequest对象的代码下载相应的代码示例。开始AddObject方法中的代码示例和信息,以创建一个方法使用这个AddRequest构造函数。

Adding an Attribute to a Directory Object

将属性添加到目录对象

After creating an object in a directory, you might want to add optional attributes to it. For all attributes that an object may contain (optional attributes), you can add them using the ModifyRequest object. 

在目录中创建一个对象后,你也许想要给它增加一个可选属性。对于一个对象也许包含所有的属性(可选属性),你能将它们添加使用ModifyRequest对象。

To add an attribute to an existing directory object, create a ModifyRequest object and in that object specify the distinguished name of the object you want to modify along with the Add value of theDirectoryAttributeOperation enumeration, the attribute name and value to add.

要添加到现有目录对象的属性,创建一个ModifyRequest对象,该对象中指定的可辨别名称的对象,你想要修改伴随着增加DirectoryAttributeOperation枚举的值,增加属性名称和值

The DirectoryAttributeOperation enumeration contains three values: Add, Delete and Replace. If an attribute already exists in an object, specifying anAdd DirectoryAttributeOperation will throw a DirectoryOperationException error. Therefore, if you want to update an existing attribute, use theReplace DirectoryAttributeOperation value instead.

DirectoryAttributeOperation枚举包含三个值:增加,删除和替换。如果一个属性在对象中已经存在,指定一个增加DirectoryAttributeOperation将会抛出一个DirectoryOperationException错误。因此,如果你想要更新一个已经存在的属性,使用Replace DirectoryAttributeOperation 值代替。

The following code sample demonstrates how to add a department attribute and value of Human Resources to a user account object named John Doe in the TechWriters OU of the fabrikam.com domain:

下面的代码示例演示了如何增加一个部门人力资源的属性和值的用户帐户对象名为John Doe在fabrikam.com域中的TechWriters  OU:

  1. Create an LdapConnection object for connecting to a domain controller in the fabrikam.com domain.

    创建一个连接到fabrikam.com域中的域控制器的LdapConnection对象 

  2. Create a ModifyRequest object and pass it the distinguished name stored in the dn variable, the Add value of theDirectoryAttributeOperation enumeration, thelDAPDisplayName of the attribute to add and the value to assign the attribute.

    创建一个ModifyRequest对象,并把它传递的可辨别名称存储在dn变量中,添加DirectoryAttributeOperation枚举值,添加lDAPDisplayName的属性和价值分配属性。

  3. Call the SendRequest method of the connection object and pass it the modRequest object.

    调用连接对象的SendRequest方法,并传递modRequest对象。

    If the attribute has not been assigned to the user account, the send request will succeed. Otherwise, a DirectoryOperationException will be thrown.

    如果属性没有被分配过给用户帐户,发送请求会成功。否则,将会抛出一个DirectoryOperationException.

  4. If a DirectoryOperationException occurs, it might be because the attribute has already been assigned to the object. Therefore, create a new ModifyRequest object and leave all parameters the same except call the Replace value of theDirectoryAttributeOperation enumeration.

    如果DirectoryOperationException出现,它可能是因为该属性已经被分配给该对象。因此,创建一个新的ModifyRequest对象,并保留所有参数相同,除非调用了替换DirectoryAttributeOperation枚举值。

    An additional try catch block appears inside the request to modify an existing attribute in case this attempt also throws a DirectoryOperationException error.

    一个额外的try catch块出现在请求修改存在的属性,假如这个尝试也会抛出DirectoryOperationException异常。

  5. If no errors are thrown, report that the operation was successful.

    如果没有抛出异常,说明操作会成功。

    This result might not be correct, as the code does not consult the server to verify that the LDAP operation was successful or not. The next section explores how to get a response back from a directory server. 

    这个结果可能不正确,因为这个代码并不会验证LDAP 操作服务是否成功。下一节将探讨如何从目录服务器得到响应。

Example 3. Adding or replacing the department attribute of a user account

示例3. 添加或者替换用户帐户的部分属性

string hostOrDomainName = "fabrikam.com";
string dn = "cn=john doe,ou=techwriters,dc=fabrikam,dc=com";
string attributeName = "department";
string attributeValue = "Accounting";

// establish a connection to the directory
//建立一个连接到该目录
LdapConnection connection = new LdapConnection(hostOrDomainName);

try
{
    ModifyRequest modRequest = new ModifyRequest(
            dn, DirectoryAttributeOperation.Add,
            attributeName, attributeValue);
    
    // example of modifyrequest not using the response object...
    //modifyrequest例子不使用响应对象.... 
    connection.SendRequest(modRequest);
    Console.WriteLine("{0} of {1} added successfully.", 
        attributeName, attributeValue);
}
catch (DirectoryOperationException)
{
    try
    {
        ModifyRequest modRequest = new ModifyRequest(
                dn, DirectoryAttributeOperation.Replace,
                attributeName, attributeValue);

        connection.SendRequest(modRequest);
        Console.WriteLine("The {0} attribute in:\n{1}\nreplaced " +
            "successfully with a value of {2}",
            attributeName, dn, attributeValue);
    }
    catch (DirectoryOperationException e)
    {
        Console.WriteLine("\nUnexpected exception occured:\n\t{0}: {1}",
                          e.GetType().Name, e.Message);
    }

}

catch (Exception e)
{
    Console.WriteLine("\nUnexpected exception occured:\n\t{0}: {1}",
                      e.GetType().Name, e.Message);
}
           

Important Consider using the code example appearing next (Example 4) as a starting point for building robust code for adding or replacing attributes. That example uses the directory response object to determine if the attribute has already been set and to check if the directory operation was successful.

重要 考虑下一个示例(示例4)会使用此代码作为出发点,为构建健壮的代码,添加或替换属性。这个例子使用目录响应对象,以确定是否这个属性已经被设置,并且检查目录操作是否成功。

Getting Feedback from a Directory Server from an Object Modify Request

从目录服务器的一个对象修改请求得到反馈

The example appearing in Example 3 does not demonstrate the pairing of the ModifyRequest and ModifyResponse classes or how you can leverage theDirectoryOperationException class to determine more about an error response. While the code catches errors, it doesn't directly display responses from a directory server as a result of modifying an object. The pattern for using a ModifyResponse object to properly cast a returned directory response from a ModifyRequest is identical to the pattern I demonstrated for casting a directory response from an AddRequest into an AddResponse. The code download with this article contains theAddAttribute2 method so that you have a complete example using theModifyRequest andModifyResponse classes. The following code snippet shows how you use the ModifyResponse object in an example similar to Example 3:

例3中出现的例子并不表明ModifyRequest和ModifyResponse是配对的类,或者你可以利用DirectoryOperationException类获取更多的错误的响应。虽然这段代码捕获异常,它并不能直接从目录服务器得到响应,作为一个修改对象的结果。使用ModifyResponse对象正确转换一个返回目录从ModifyRequest响应中,相同的模型,我演示了对铸造一个目录响应从AddRequest 到AddResponse。本文的代码下载包含方法,以便让你有一个完整的例子使用ModifyRequest和ModifyResponse类。下面的代码片段显示了,你如何使用这个ModifyResponse对象在类似例3的例子中:

// build a modifyrequest object 
//创建一个modifyrequest对象
ModifyRequest  modRequest =
        new ModifyRequest(dn, DirectoryAttributeOperation.Add,
        attributeName, attributeValue);

// cast the returned directory response into a ModifyResponse type named modResponse
//将传回的目录响应到一个类名为modifyResponse的ModifyResponse类型中
ModifyResponse modResponse = (ModifyResponse)connection.SendRequest(modRequest);

Console.WriteLine("The {0} attribute in {1} added successfully " +
        "with a value of {2}. The server response was {3}",
        attributeName, dn, attributeValue, modResponse.ResultCode);

           

When an add operation fails, you can determine why by examining the server's directory response more closely. TheSendRequest method throws a DirectoryOperationException if the directory server returns a DirectoryResponse object containing an error. This directory response is packaged in theResponse property of the exception.

当增加操作失败,你可以通过检查服务器的目录中响应更加紧密来确定为什么。SendRequest方法抛出了一个DirectoryOperationException,如果目录服务器返回一个包含一个错误的DirectoryResponse对象。此目录响应被包装在异常的响应属性。

The ResultCode of the directory response returns a value contained in the ResultCode enumeration. This enumeration is rich with a plethora of error values. For example, an error equivalent to the AttributeOrValueExists value is returned if an attribute is assigned to an object.

目录服务器响应返回的结果代码值包含在ResultCode 枚举中,这个枚举是富含大量的误差值。例如,一个错误相当于AttributeOrValueExists值返回如果属性被分配到一个对象。

The following code example demonstrates how to use the ModifyResponse class to verify a directory object modification and how to use a directory response object containing an error code to handle a DirectoryOperationException. This code sample is similar to Error! Reference source not found., but provides a better starting point for building code that adds or replaces an attribute value:

下面的代码示例演示如何使用ModifyResponse类来验证目录对象修改和如何使用一个目录响应对象,它包含一个错误代码来处理一个DirectoryOperationException。下面的代码示例类似错误!未找到引用源。但提供一个更好的起点,为构建代码。添加或者替换属性值。

  1. Create an LdapConnection object for connecting to a domain controller in the fabrikam.com domain.

    创建一个连接到fabrikam.com域中的域控制器的LdapConnection对象 .

  2. Declare the ModifyRequest and ModifyResponse objects and name them modRequest and modResponse respectively.

    声明ModifyRequest和ModifyResponse对象,并用名字mofRequest和modResponse区分。

    These two objects are declared here because they could be used within two try catch blocks. This is more efficient than the code example appearing inError! Reference source not found. where there is a potential of creating two ModifyRequest objects, one for the attempted add operation and another for the replace operation.

    这两个对象都在这里声明,因为他们可以用在两个try catch代码块。这是更有效的代码示例中出现的

    错误!未找到引用源。那里是一个潜在的,创建两个ModifyRequest对象。一个企图添加操作,另一个用于替换操作。

  3. Initialize modRequest by passing it the distinguished name stored in the dn variable, the Add value of theDirectoryAttributeOperation enumeration, thelDAPDisplayName of the attribute to add and the value to assign the attribute.

    初始化modRequest 通过它的可分辨名称存储在dn变量,DirectoryAttributeOperation枚举增加的值,要添加的属性和属性值分配的LDAPDisplayName.

  4. Cast the returned directory response object into a ModifyResponse object named modResponse.

    If the attribute has not been assigned to the user account, the send request will succeed. Otherwise, the SendRequest throws a DirectoryOperationException.

    将返回的目录响应对象,命名为modResponse到一个ModifyResponse对象。

    如果这个属性没有被分配到用户帐户,发送请求会成功的。否则,SendRequest抛出一个DirectoryOperationException.

  5. Catch the DirectoryOperationException and name the returned object doe.

    抓住DirectoryOperationException,并用doe命名返回的对象

  6. Check the ResultCode property of the directory response object. If the result code is equivalent to the AttributeOrValueExists value in theResultCode enumeration, then attempt to replace the attribute value.

    The Response property of the DirectoryOperationException object named doe contains the directory response object.

    检查目录响应对象的ResultCode属性。如果结果代码与ResultCode枚举的AttributeOrValueExists值相同,然后尝试替换属性值。

    doe命名的 DirectoryOperationException对象的Response属性包含目录响应对象。

  7. Create a new ModifyRequest object and leave all parameters the same except call the Replace value of theDirectoryAttributeOperation enumeration.

    创建一个新的ModifyRequest对象,并将所有相同的属性替换为DirectoryAttributeOperation枚举值。

    An additional try catch block appears inside the request to modify an existing attribute in case other errors are thrown. However, you can more elegantly handle errors using other values of theResultCode enumeration. For example, if the object specified, cn=john doe,ou=techwriters,dc=fabrikam,dc=com in this example does not exist, the directory response will be equivalent to the NoSuchObject value of theResultCode enumeration. 

    另外一个catch块出现在请求修改一个现有属性,以防其他也会抛出错误。但是,你可以使用ResultCode列举的其他值更优雅的处理错误。例如,如果指定的对象,cn=john doe,ou=techwrites,dc=fabrikam,dc=com 在这个例子中不存在,目录响应的ResultCode枚举的NoSuchObject值是相等的。

Example 4. A more robust example demonstrating how to add or replace an attribute of a directory object

示例4。一个更强大的例子演示了如何添加或更换目录对象的属性

string hostOrDomainName = "fabrikam.com";
string dn = "cn=john doe,ou=techwriters,dc=fabrikam,dc=com";
string attributeName = "department";
string attributeValue = "Accounting";

// establish a connection to the directory
//建立一个目录连接
LdapConnection connection = new LdapConnection(hostOrDomainName);

// declare the request and response objects here
//此处声明request和response对象
// they are used in two blocks
//他们使用在两个块中
ModifyRequest modRequest;
ModifyResponse modResponse;

try
{
    // initialize the modRequest object 
    //初始化modRequest对象
    modRequest =
        new ModifyRequest(dn, DirectoryAttributeOperation.Add,
        attributeName, attributeValue);

    // cast the returned directory response into a ModifyResponse type 
    // named modResponse    
    //投掷返回目录请求到类名为modResponse的ModifyResponse
    modResponse =
        (ModifyResponse)connection.SendRequest(modRequest);

    Console.WriteLine("The {0} attribute of {1} added successfully " +
        "with a value of {2}. The server response was {3}",
        attributeName, dn, attributeValue, modResponse.ResultCode);

}

// if the code enters this catch block, it might be 
// caused by the presence of the specified attribute. 
// The DirectoryAttributeOperation.Add enumeration fails
// if the attribute is already present.

//如果代码进入这个catch块,也许是由于指定属性已经存在。
//如果这个属性已经存在
//DirectoryAttributeOperation.Add枚举失败
catch (DirectoryOperationException doe)
{
    // The resultcode from the error message states that 
    // the attribute already exists

    //resultcode为错误消息指出,属性已经存在
    if (doe.Response.ResultCode == ResultCode.AttributeOrValueExists)
    {
        try
        {
            modRequest = new ModifyRequest(
                                dn,
                                DirectoryAttributeOperation.Replace,
                                attributeName,
                                attributeValue);

            modResponse =
                (ModifyResponse)connection.SendRequest(modRequest);

            Console.WriteLine("The {0} attribute of {1} replaced " +
                "successfully with a value of {2}. The server " +
                "response was {3}",
                attributeName, dn, attributeValue, modResponse.ResultCode);
        }
        // this catch block will handle other errors that you could
        // more elegantly handle with other values in the 
        // ResultCode enumeration.

        //这些catch块将会处理其他错误.
        //你能更优雅的处理ResultCode枚举中的其他值
        catch (Exception e)
        {
            Console.WriteLine("\nUnexpected exception occured:\n\t{0}: {1}",
              e.GetType().Name, e.Message);
        }
    }

}

catch (Exception e)
{
    Console.WriteLine("\nUnexpected exception occured:\n\t{0}: {1}",
                      e.GetType().Name, e.Message);
}


           

To keep the remaining code examples as simple as possible, I show just a few of the most common interrogations of the ResultCode property in a response object. In production code, you will want to examine many more result codes contained in a DirectoryOperationException. Use the examples I show as a starting point for handling other directory response result codes. Carefully review the ResultCode enumeration for other common directory responses.

为了让剩余的代码例子尽可能简单。我展示的只是一些常见的 ResultCode属性,在一个响应对象。在编写代码时,你将会检查更多的结果代码包含在一个DirectoryOperationException。使用展示的例子,我作为一个起点处理其他目录响应结果代码。请仔细阅读ResultCode枚举为其他常见目录响应。

In addition, the prior code example can be simplified with the PermissiveModifyControl directory control, which is explored in the next section.

此外,现有的代码示例可以简化与PermissiveModifyControl 目录控制,这是在下一节中探讨。

Adding Values to a Multi-Valued Attribute

To Be Continued。。。。

未完待续。。。。

小弟不才,翻译的不是很好。如果有更好的翻译,请大虾们不吝赐教。那我将感激不尽。希望共同进步。

继续阅读