views:

105

answers:

2

I'm really new to web services and need to create a webservice that can deal with object graphs. My canonical example would be a CRM web service that given a customer number would return an "object" of type Company with a collection property of Contacts.

ie:

[WebService]
public Company GetCompanyByCustomerNumber( string customerNumber ) {...}

would return an instance of:

public class Company
{
....
  public List<Contact> Contacts { get { ... } }
}

It would be really nice to be able to create the webservice so that it easily can be consumed from Visual Studio so that it can work directly with the company and related contacts...

Is this possible?

Thanks Fredrik

+2  A: 

Instead of ASMX web services, you would be better off using Windows Communication Foundation (WCF). With that, you can define Data Contracts with attributes like this:

[DataContract]
public class Company
{
    [DataMember]
    public Contact[] Contacts { get; set; }
}
Mark Seemann
Is there tool-support in the consumer side that will understand the "graph" in there so it can be used "as is" by the caller? Also If the contact has a property like ParentCompany is that supported, I read somewhere that circular dependencies does not work?Thanks
Fredrik T
Also, is it possible to apply those attributes dynamically, since my Company and Contact really are "Entities" of the same kind "Entity" but with diffrent properties availiable via ICustomTypeDescriptor?
Fredrik T
Yes, there's tool support in Visual Studio 2008+. I added a link where you can read more.
Mark Seemann
Circular references don't serialize well, so those are not supported. IIRC, neither are dynamic attributes, but you can fall back from the so-called DataContractSerialize to XmlSerializer by implementing IXmlSerializable.
Mark Seemann
Test this well if the Contacts class has a DataMember that is the Company. The fact quesion asks about "graphs" not "trees" is setting alarm bells of...
Ian Ringrose
+1  A: 

It seems the fix in .NET Framework 3.5 SP1 wich adds support for the IsReference attribute on the DataContract is exactly what I need!

so I can write:

[DataContract(IsReference=true)]
public class Contact
{
    Company parentCompany;
    [DataMember]
    public Company ParentCompany
    {
        get { return parentCompany; }
        set { parentCompany = value; }
    }

    string fullName;
    [DataMember]
    public string FullName
    {
        get { return fullName; }
        set { fullName = value; }
    }
}

[DataContract(IsReference = true)]
public class Company
{
    string name;
    [DataMember]
    public string Name
    {
        get { return name; }
        set { name = value; }
    }

    List<Contact> contacts = new List<Contact>();
    [DataMember]
    public List<Contact> Contacts
    {
        get { return contacts; }
    }
}

Thanks for all the help which set me of in the right direction!

// Fredrik

Fredrik Tonn