Custom datacontract / datamember name

Borat picture Borat · Jul 13, 2009 · Viewed 9.6k times · Source

I have a following problem. A customer requested a web service that returns data in following format:

<status>
 <name1>Some name</name1>
 ...
</status>

But when an error occurs they want to get a following message:

<status>
 <error>Error description</error>
</status>

I created a web service using WCF and in order to fulfill the requirements I defined a following service contract:


    [ServiceContract]
    public interface IPatronStatus
    {
        [OperationContract]
        [ServiceKnownType("GetKnownTypes", typeof(KnownTypesProvider))]
        [WebGet(UriTemplate = "/service/status?user={unilogin}")]
        StatusData GetPatronStatus(string unilogin);
    }

And also defined a following base class:


    [DataContract(Name="status")]
    public class StatusData
    {

    }

And two derrived classes:


public class PatronStatusData : StatusData
{
        private string _name;
        [DataMember(Name = "name1", Order = 0)]
        public string Name
        {
            get { return _name; }
            set { _name = value; }
        } 
...
}

And:


public class UniLoginNotFoundError : StatusData 
    {
        public UniLoginNotFoundError()
        { }

        private string _description = "UniLoginNotFoundError";
        [DataMember(Name = "error", Order = 0)]
        public string Description
        {
            get 
            {
                return _description;
            }

        }
    }

The problem is that when I pull the data from the web service the data contract name ("status") and the names of the data members are ignored and the type's and properties' names are used.

Is it possible to use the custome names?

Answer

Dmitry Ornatsky picture Dmitry Ornatsky · Jul 13, 2009

You should decorate both UniLoginNotFoundError and PatronStatusData with DataContract(Name="Something") to make this work. But you won't be allowed to set the same name ("status") for them. In your particular case I'd better use single class with unused properties set to null.

[DataContract(Name="status")]
public class StatusData
{
    private string _name;
    private string _errorDescription = null;


    [DataMember(Name = "name1", Order = 0, EmitDefaultValue=false)]
    public string Name
    {
        get { return _name; }
        set { _name = value; }
    }


    [DataMember(Name = "error", Order = 1, EmitDefaultValue=false)]
    public string Description
    {
        get{ return _errorDescription ;}
        set {_errorDescription =value ;}
    }
...
}