Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is a blank constructor required for WCF [DataContract] classes? Why?

I was told by someone that a blank constructor was required for serializable objects that included getters and setters, such as below:

[DataContract]
public class Item
{
    [DataMember]
    public string description { get; set; }

    public Item() {}

    public Item(string description)
    {
        this.description = description;
    }
}

And the reason this was told me was that this allowed for construction of objects using the setter. However, I have found that the Item when defined like this:

[DataContract]
public class Item
{
    [DataMember]
    public string description { get; set; }

    public Item(string description)
    {
        this.description = description;
    }
}

Can be constructed without calling the constructor, when made available as a proxy class via a WCF service reference:

Item item = new Item {description = "Some description"};

Questions:

  1. What exactly is that block of code I'm writing after declaring new Item
  2. Is a blank constructor required for [DataContract] classes? If so, what does this blank constructor do?

I have found that I can't create an object without the constructor if the class is NOT a proxy class.

like image 800
Zach Smith Avatar asked Mar 10 '23 00:03

Zach Smith


1 Answers

What exactly is that block of code I'm writing

Item item = new Item {description = "Some description"};

Is equal and gets compiled to:

Item item = new Item();
item.description = "Some description";

So it requires a parameterless constructor. If the class doesn't have one, but has a parameterized one, you must use that one:

Item item = new Item("Some description");

Using named parameters, it would look like this:

Item item = new Item(description: "Some description");

You can still combine that with the object initializer syntax:

var item = new Item("Some description")
{
    Foo = "bar"
};

Is a blank constructor required for [DataContract] classes?

Yes. The default serializer, DataContractSerializer, doesn't use reflection to instantiate a new instance, but still requires a parameterless constructor.

If it can't find a parameterless constructor, it can't instantiate the object. Well, it can, but it doesn't. So if you were to actually use this Item class in a service operation:

public void SomeOperation(Item item)
{
}

Then WCF will throw an exception once you invoke this operation from a client, because the serializer can't find a parameterless constructor on Item.

like image 95
CodeCaster Avatar answered Apr 30 '23 11:04

CodeCaster