1

我正在编写 WCF 服务以从 Active Directory 返回有关人员的信息。除了返回此人的详细信息外,我还希望它返回其经理的用户名和全名。

我开始将其编码为:...

[DataContract]
public class ADPerson
{
    Guid objectGuid;
    Guid managerObjectGuid;
    string username;
    string displayname;

    [DataMember]
    public string Username 
    { 
        get { return this.username; }
        set { this.username = value; }
    }
    [DataMember]
    public string DisplayName
    { 
        get { return this.displayName; }
        set { this.displayName = value; }
    }
    [DataMember]
    public ADPerson Manager
    { 
        get { return new ADPerson(this.managerObjectGuid); }
        set { this.managerObjectGuid = value.objectGuid; }
    }

    /* ... */

}

...但后来意识到这没有停止条件;即,它将一直遍历对象图,直到到达未定义经理的用户(即 CEO)。

有没有一种很好的方法来放置这个停止条件,同时仍然能够重用 ADPerson 类,或者我是否需要提供另一种获取经理详细信息的方法(例如,将我希望看到的那些详细信息放入他们自己的字段中并从 Manager 属性中删除 DataMember,或者创建一个 ADManager 类,该类显示不是经理的经理的 ADPerson 字段的子集?

这是解决问题很简单的另一种情况,但知道问题的最佳解决方案是什么让我很烦恼。

提前致谢,

JB

4

2 回答 2

2

鉴于循环引用( “员工 A 有经理 B,要打印经理 B,您必须打印他的员工,其中之一是员工 A...”),在 XML 中使用继承必然会变得混乱。

此代码演示,使用 DataContractSerializer,这将不起作用:

[ServiceContract]
public class NestedDataService
{
    [OperationContract]
    public Person FindPerson()
    {
        var person = new Person { Name = "E.M. Ployee" };
        var manager = new Person { Name = "M.A. Nager" };

        manager.Employees = new List<Person>();
        manager.Employees.Add(person);

        person.Manager = manager;

        return person;
    }
}

[DataContract]
public class Person
{
    [DataMember]
    public String Name { get; set; }

    [DataMember]
    public Person Manager { get; set; }

    [DataMember]
    public List<Person> Employees { get; set; }
}

我会使用AD中的一些(?) G/UUID 并使用该 ID 在客户端将它们重新链接在一起。然后 Employee A 将不再具有public ADPerson Manager属性(或者至少就序列化程序而言没有),但是public UUID ManagerID可以像这样实现:

public UUID ManagerID 
{ 
    get 
        { 
            return Manager != null ? Manager.UUID : null;
        }
}

这限制了您返回一个人,因为您必须发送一份ADPersons是否有与所请求的人相关的人的列表,以便能够查找他们。

于 2012-10-08T12:51:44.750 回答
1

在我看来,根据给出的信息,最好的解决方案是让你想要序列化的属性在手头的类上可见,并从管理器中删除 DataMember 属性,如下所示:

[DataContract] 
public class ADPerson 
{ 
    Guid objectGuid; 
    Guid managerObjectGuid; 
    string username; 
    string displayname; 

    [DataMember] 
    public string Username  
    {  
        get { return this.username; } 
        set { this.username = value; } 
    } 
    [DataMember] 
    public string DisplayName 
    {  
        get { return this.displayName; } 
        set { this.displayName = value; } 
    } 
    public ADPerson Manager 
    {  
        get { return new ADPerson(this.managerObjectGuid); } 
        set { this.managerObjectGuid = value.objectGuid; } 
    } 
    [DataMember] 
    public string ManagerUsername
    {  
        get { return this.Manager.Username; } 
    } 
    [DataMember] 
    public string ManagerName
    {  
        get { return this.Manager.DisplayName; } 
    } 
} 

public如果您不希望它们出现,它们甚至不必出现。

于 2012-10-08T12:52:04.863 回答