我尝试使用CodeDom生成一些方法,我在为这些方法生成自定义属性时遇到问题。
我可以管理简单的空属性,例如
[DataMember()]
或带有字符串值参数的属性
[DataContract(Namespace = "http://somenamespace")]
但是我需要生成更复杂的属性,例如
[WebInvoke(Method = "POST", UriTemplate = "SomeTemplate", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
和
[FaultContract(typeof(Collection<MyFault>))]
对于枚举值ResponseFormat = WebMessageFormat.Json
的参数,我尝试过类似于字符串的方法,创建CodePrimitiveExpression实例:
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)
}
}
};
然而,这不起作用,我得到一个例外
无效的基元类型:System.ServiceModel.Web.WebMessageFormat。考虑使用CodeObjectCreateExpression。
我确实考虑过使用CodeObjectCreateExpression,但我不知道如何使用。它需要字符串或CodeTypeReference,并且第二个参数是CodeExpression参数的数组。我不知道放在那里的参数。
至于其他属性,typeof(Colleciton<MyFault>)
的属性,我甚至不知道从哪里开始。任何帮助将不胜感激。
编辑:有人建议我在我试图模仿的方法上调用CustomAttributeData.GetCustomAttributes,所以我这样做了。为了提高效率和清晰度,我将在屏幕截图中提供数据。这让我对我正在处理的内容有了更好的了解,但我仍然不确定如何实现它。
答案 0 :(得分:3)
像WebMessageFormat.Json
这样的表达式看起来像访问一个静态字段,因此您需要编写它:
new CodeAttributeArgument
{
Name = "RequestFormat",
Value = new CodeFieldReferenceExpression(
new CodeTypeReferenceExpression("WebMessageFormat"), "Json")
}
typeof
表达式是一种特殊类型的表达式,因此它有自己的CodeDOM类型:
new CodeAttributeDeclaration(
"FaultContract",
new CodeAttributeArgument(new CodeTypeOfExpression("Collection<MyFault>")))
要查看CodeDOM中可用的所有表达式类型的列表,请查看the inheritance hierarchy in the docs of CodeExpression
。