Reputation: 4516
I use the following command to generate a proxy class for a WCF service :
svcutil.exe" /out:C:\SomePath\.... /n:*,Internal.FooNameSpace
http://localhost/MyService.svc
The following class :
[ProtoContract]
[ServiceContract]
public class Foo
{
[ProtoMember(1)]
[DataMember(Order = 0)]
public string Bar { get; set; }
}
Becomes :
public partial class Foo : object, System.Runtime.Serialization.IExtensibleDataObject
{
private string BarField;
[System.Runtime.Serialization.DataMemberAttribute()]
public string Bar
{
get
{
return this.BarField;
}
set
{
this.BarField = value;
}
}
}
Is there a way to keep some specific attributes on the generated class ? (eg : ProtoMember
in this case). I could off course hack the proxy but it create maintenance problems.
Upvotes: 1
Views: 77
Reputation: 1062502
If you're adding that as a service reference, then nope: there's no way to retain that information - it simply isn't in the WCF endpoint.
IIRC, though, the WCF code-gen does actually come up with incremental Order
values when you have multiple properties - i.e. the next property would be [System.Runtime.Serialization.DataMemberAttribute(Order = 1)]
, then 2
etc. So one option is to in a different file (the beauty of partial class
), define (in the same namespace, etc) additional info about your type:
[ProtoContract(DataMemberOffset = 1)]
public partial class Foo { }
What this means is: when processing [DataMember]
, add 1
to every value - that means that you should get the required 1,2,3,4... and everything will be fine, and you haven't had to change the code.
Alternatively, you can be explicit:
[ProtoContract]
[ProtoPartialMember(1, nameof(Foo.Bar))]
[ProtoPartialMember(2, nameof(Foo.AnotherProp))]
public partial class Foo { }
This gives you a lot more flexibility to specify nuance about the properties.
As another alterative, you can configure everything at runtime:
RuntimeTypeModel.Default.Add(typeof(Foo), false)
.Add(1, nameof(Foo.Bar))
.Add(2, nameof(Foo.AnotherProp));
// or AddField to get the ValueMember that you can use to set
// fine-grained control
Finally, you can just ship the data contract dll, and tell svctil to use the types it already contains. You do this with the /reference:<file path>
command-line switch, or there's a similar feature when using the UI tools (that lets you choose from the available dlls).
As a second "finally" (because one is not enough): you could describe the data instead as a .proto schema, and just tell the recipient to do the codegen locally and tell svcutil to exclude it (/excludeType:
or /reference:
). Note that the in progress rewrite of "protogen" does not currently include [DataContract]
/[DataMember]
attributes, but I could get that added today if it would be useful.
Upvotes: 1