Reputation: 3788
I'm trying to generate some methods using CodeDom, I have a problem generating custom attributes for these methods.
I can manage simple empty attributes, such as
[DataMember()]
or attributes with string value arguments,
[DataContract(Namespace = "http://somenamespace")]
But there are more complex attributes I need to generate, such as
[WebInvoke(Method = "POST", UriTemplate = "SomeTemplate", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
and
[FaultContract(typeof(Collection<MyFault>))]
For the arguments with enum values ResponseFormat = WebMessageFormat.Json
I've tried similar approach to what I did for strings, creating a CodePrimitiveExpression instance:
CodeAttributeDeclaration webInvoke = new CodeAttributeDeclaration()
{
Name = "WebInvoke",
Arguments =
{
new CodeAttributeArgument
{
Name = "Method",
Value = new CodePrimitiveExpression("POST")
},
new CodeAttributeArgument
{
Name = "UriTemplate",
Value = new CodePrimitiveExpression(method.Name)
},
new CodeAttributeArgument
{
Name = "RequestFormat",
Value = new CodePrimitiveExpression(WebMessageFormat.Json)
},
new CodeAttributeArgument
{
Name = "ResponseFormat",
Value = new CodePrimitiveExpression(WebMessageFormat.Json)
}
}
};
However, this does not work, I get an exception saying
Invalid Primitive Type: System.ServiceModel.Web.WebMessageFormat. Consider using CodeObjectCreateExpression.
I did consider using CodeObjectCreateExpression, but I don't know how. It expects either a string or a CodeTypeReference, and as a second parameter an array of CodeExpression parameters. I have no idea what parameters to put there.
As for the other attribute, the one with typeof(Colleciton<MyFault>)
, I don't even know where to start. Any help would be appreciated.
EDIT: Someone suggested I call CustomAttributeData.GetCustomAttributes on the methods I'm trying to mimic, so I did that. For the sake of efficiency and clarity, I'll provide the data in a screenshot. This gave me a somewhat better idea of what I'm dealing with, but I'm still unsure about how to implement it.
Upvotes: 4
Views: 1547
Reputation: 244767
Expressions like WebMessageFormat.Json
look like accessing a static field, so that's how you have to write it:
new CodeAttributeArgument
{
Name = "RequestFormat",
Value = new CodeFieldReferenceExpression(
new CodeTypeReferenceExpression("WebMessageFormat"), "Json")
}
The typeof
expression is a special type of expression, so it has its own CodeDOM type:
new CodeAttributeDeclaration(
"FaultContract",
new CodeAttributeArgument(new CodeTypeOfExpression("Collection<MyFault>")))
To see the list of all expression types available in CodeDOM, look at the inheritance hierarchy in the docs of CodeExpression
.
Upvotes: 3