質問

I'm writing a WCF service to return information about a person from Active Directory. As well as returning the person's details I also want it to return their manager's username and full name.

I began coding this as:...

[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; }
    }

    /* ... */

}

...but then realised that this has no stop condition; i.e. it will traverse all the way up the object graph until it reaches a user for whom no manager is defined (i.e. the CEO).

Is there a good way to put this stop condition in place whilst still being able to reuse the ADPerson class, or do I need to provide an alternative way of getting the manager's details (e.g. putting those details I want to be visible into their own fields and removing DataMember from the Manager property, or creating an ADManager class which presents a subset of the ADPerson fields which doesn't the manager's manager?

This is another case where solving the problem is simple, but knowing what the best solution to the problem is is vexing me.

Thanks in advance,

JB

役に立ちましたか?

解決

In my opinion, based on the information given, the best solution is to make the properties you want serialized visible on the class at hand and remove the DataMember attribute from the manager, like this:

[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; } 
    } 
} 

And they don't even have to be public if you don't want them to.

他のヒント

Using inheritance in XML is bound to get messy, given the circular references ("Employee A has Manager B, to print Manager B you'll have to print his emplyees, one of which is Employee A...").

This code demonstrates that, using the DataContractSerializer, this won't work:

[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; }
}

I would use some (the?) G/UUID from the AD and re-link them toghether at the client side using that ID. Then Employee A won't have a public ADPerson Manager property anymore (or at least not as far as the serializer is concerned), but a public UUID ManagerID which can be implemented like this:

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

This limits you in returning one person, because you'll have to send a list of ADPersons if there are people related to the requested person, in order to be able to look them up.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top