0

I'm building a WCF. I have a class called Result

public class ReturnData 
{
     public string key { get; set; }
     public string[] value { get; set; }
}
public class TagDetailData 
{
     public string key { get; set; }
     public string description { get; set; }
}

public object Data { get; set; }    

The response gives back property Data and I would like to be able to convert a List<ReturnData> or List<TagDetailData> to Data in the response.

Client is demanding that the result is all in Data, and depending on their inputs I either process ReturnData or TagDetailData.

Can I convert a List into a object? Maybe I need another approach?

When I try

var newData = new List<TagDetailData>();

newData.Add(new TagDetailData
                            {
                                key = "Test",
                                description = "Tester"
                            });

this.Data = (List<TagDetailData>)newData;

The service simply fails to load response data and I don't get any Exceptions.

Mad Dog Tannen
  • 7,129
  • 5
  • 31
  • 55
  • 2
    Why are you using a simple "object" in a service? You should communicate with a specified type/object. – etalon11 Feb 16 '16 at 07:56
  • @etalon11 Thanks for your reply.This is my issue, depending on user inputs it should return either a `List` or `List` but within the same property called `Data`. I assume the property `object` is wrong in this case and this is what i need help with, which approach should i use? – Mad Dog Tannen Feb 16 '16 at 07:59
  • 1
    Those `ReturnData` and `TagDetailData` share something in common? Can you think in superclassing them? If not, you should have two different properties to return the data in the appropriate format – Rubens Farias Feb 16 '16 at 07:59
  • Make a `Data` base class which contains the key. Then you can inherit from that – Alexander Derck Feb 16 '16 at 08:03
  • To make it simple, can you think in returning an object with all the key, description and values props, and differentiate those objects based on which properties are not null? – Rubens Farias Feb 16 '16 at 08:04

3 Answers3

2

You'll need to be more specific than "object" for the WCF payload. Try using a generic wrapper like this:

public class Result<T> where T : class
{
    public Result() { }

    public Result(T data)
    {
        this.Data = data;
    }

    public T Data { get; set; }

}

This way, you can create a result of the type you want, such as:

var data = new List<TagDetailData>();

data.Add(new TagDetailData
{
    key = "Test",
    description = "Tester"
});

return new Result<List<TagDetailData>>(data);

The type of T can be inferred by the constructor here and the <ListTagDetailData>> is actually unnecessary. I keep it here to illustrate that the data is of any type that is a class. Also, the parameterless constructor is still required in this class for the serializer to work.

The WFC serializer cannot serialize type "object" or type "dynamic". This is why your contract method produces no output. Generic types resolve to real types that are themselves serializable.

It was suggested that you might use a base class. I haven't tried this, but I suspect it won't work since the data contract won't match what you're actually trying to serialize.

It's been a while since I've worked in WCF. You probably need to decorate my Result wrapper with DataContract and DataMember attributes.

If your endpoints are strictly web-based (HTTP and HTTPS), consider using WebAPI instead.

S. Brentson
  • 454
  • 4
  • 7
  • This is the most effective solution. I've been using this approach since 2010 with one of our base DTOs at work. Note that `[DataContract]` is not required in WCF 3.5 or later - I use it to make things clear, but at the outset I didn't and my generic result class serialized just fine (as long as `T` was an object that could be serialized). – Tim Feb 16 '16 at 17:57
1

Did you try to enable WCF logging? See how-to-turn-on-wcf-tracing

You probably need to add attributes to tell the data-contract-serializer what types of data to expect. See this MSDN blog for example

Community
  • 1
  • 1
Ziriax
  • 1,012
  • 10
  • 19
1

You could go with:

public class ReturnItem
{
     public string   key         { get; set; }
     public string   description { get; set; }
     public string[] value       { get; set; }
}

public ReturnItem[] Data { get; set; }

Later, you can test description for a null value and figure out which object it this; optionally, you could add an enum property to make this difference clear.

Rubens Farias
  • 57,174
  • 8
  • 131
  • 162