通过WCF传递匿名类型的实例

And*_*rey 20 wcf anonymous-types datacontract datacontractserializer

我有一个WCF服务方法,它期望一个对象,然后使用反射检索其属性.

在客户端,我创建了一个匿名类型对象

var obj = new {FirstName="John", LastName="Doe"}
Run Code Online (Sandbox Code Playgroud)

并将其传递给方法.我得到一个例外:

Type '<>f__AnonymousType0`2[System.String,System.String]' cannot be serialized. 
Consider marking it with the DataContractAttribute attribute, and marking all 
of its members you want serialized with the DataMemberAttribute attribute.  
See the Microsoft .NET Framework documentation for other supported types.
Run Code Online (Sandbox Code Playgroud)

我无法使用序列化属性标记类型或其成员,因为实际上没有明确声明的类型或属性.有没有办法克服这个问题?

cas*_*One 19

该提示答案,你不能在WCF使用匿名类型是错误的.

如果您使用默认值DataContractSerializer来序列化频道上的类型,那么答案是正确的.这是因为DataContractSerializer支持以下场景:

  1. 使用属性序列化的类型Serializable
  2. 使用XML序列化序列化的类型
  3. 使用属性序列化的类型DataContract
  4. Plain-Old-C#-Object(POCO)序列化

由于以下原因,它们分别因匿名类型而失败:

  1. 您不能将属性应用于匿名类型.
  2. XML Serialization需要一个默认的无参数构造函数,匿名类型没有.
  3. 与1相同.
  4. 与2相同.

但是,您不必DataContractSerializer在WCF中使用序列化消息.您可以创建自定义消息格式化程序,您可以使用它自己执行序列化.

如果您作为请求结果发送的类型是匿名类型,则会出现问题.当你得到结果时,它将在命名空间中具有明确的名称(不是在.NET意义上,而是在SOA意义上),并且您将不得不将该具体类型的映射处理回匿名类型.但是,因为您无法访问实际的匿名类型或在代码中构造它的方法(至少以动态方式),所以除了将它作为对象传递给它时,别无选择,如果它被传递给您,使它变得毫无价值,因为每个人都必须使用诸如动态之类的不良实践(本身并不是一种不好的做法,但是在这种情况下绕过这些限制,是的),或者按示例进行演绎.

所以最后我会说尽管可以序列化匿名类型并通过网络发送它们,但是调用的工作通常是不值得的.

  • 提及任何技术都应该考虑分享知识,而不是嘲笑.此外,甚至驱魔人也需要了解恶魔. (5认同)
  • +1表示技术上正确的答案.-1提到一种纯粹邪恶的技术.我担心有人会读到这个并忽略"不良做法"警告 - 忘记重构,你需要一个驱魔人. (3认同)

kyo*_*ryu 17

不要这样做.

这是一种聪明的尝试.别.只需声明您需要的数据类型,然后使用它.如果您需要更松散定义的数据类型,只需使用某种键值映射.

你需要花5分钟时间写一些可以解决这个问题的东西.使用这样的任何技术都会花费你几个小时的调试时间.