0

I've got a basic WCF service. I've split out my data contracts and one of them is a class with a large amount of public properties. If I want to make these properties available to the client I'm assuming all of these will need to have [DataMember]. So, as there's a large number of these properties, is there any way of bulk decorating them with [DataMember]? something like:

[DataMember]
(
    public string Title { get; set; }
    public Guid ID { get; set; }
    public Description { get; set; }

    //more properties...
)

I've only ever seen:

[DataMember]
public string Title { get; set; }
[DataMember]
public Guid ID { get; set; }
[DataMember]
public Description { get; set; }
sr28
  • 4,728
  • 5
  • 36
  • 67

2 Answers2

2

Yes. You can use Aspect Oriented Programming technique for this. Here is the solution when you use PostSharp. PostSharp can be installed via nuget (postsharp express is free).

You need to write an aspect first. See the code below.

namespace AspectOrientedProgramming
{
 [Serializable]
    [MulticastAttributeUsage (MulticastTargets.Class)]
    public sealed class DataContractAspect:TypeLevelAspect, IAspectProvider
    {
        public IEnumerable<AspectInstance> ProvideAspects(object targetElement)
        {
            var targetType = (Type) targetElement;

            var introduceDataContractAspect =
                new CustomAttributeIntroductionAspect(
                    new ObjectConstruction(typeof(DataContractAttribute).GetConstructor(Type.EmptyTypes)));
            var introduceDataMemberAspect =
                new CustomAttributeIntroductionAspect(
                    new ObjectConstruction(typeof(DataMemberAttribute).GetConstructor(Type.EmptyTypes)));

            yield return new AspectInstance(targetType, introduceDataContractAspect);

            foreach (var property in targetType.GetProperties(BindingFlags.Public | BindingFlags.DeclaredOnly | BindingFlags.Instance))
            {
                if (property.CanWrite && !property.IsDefined(typeof(NotADataMemberAttribute), false))
                {
                    yield return new AspectInstance(property, introduceDataMemberAspect);
                }
            }
        }
    }
}

Now create a Not a datamember attribute.

 [AttributeUsage(AttributeTargets.Property)]

    public sealed class NotADataMemberAttribute:Attribute
    {

    }

Decorate those few properties that you don't want to be DataMembers with [NotADataMember].

Add the following line in AssemblyInfo.cs file. Replace YourNameSpaces with appropriate to your project specific.

[assembly: DataContractAspect(AttributeTargetTypes = "YourNamespaces.DataContracts.*")]

Thats it.

With this approach, You don't have to decorate every member with DataMember attribute. Also, you don't have to decorate every class with DataContract.

0

No, unfortunately, it's not possible to mark the group of properties with the attribute.

Max Brodin
  • 3,903
  • 1
  • 14
  • 23
  • Thanks for the reply. What do you base that on? Admittedly after a bit of research I'm coming to the same conclusion but I've not seen it stated as yet that this can't be done. – sr28 Nov 13 '14 at 16:10
  • If you have Resharper, you can create little templates that aid the process. Then there's always column edit mode where you can insert it for a bunch of properties. These will help out some. – Cameron Nov 13 '14 at 16:21
  • If you're using 3.5SP1+, it's not necessary to attribute anything- all public members will be serialized on types that aren't otherwise serializable and aren't marked DataContract/DataMember – Max Brodin Nov 13 '14 at 16:31
  • 1
    Whilst your right that it's not necessary you do lose a lot of capabilities, some listed here: http://stackoverflow.com/questions/4836683/when-to-use-datacontract-and-datamember-attributes – sr28 Nov 13 '14 at 16:41