Wcf 向DataContract添加动态datamembers

Wcf 向DataContract添加动态datamembers,wcf,json,Wcf,Json,我有返回Json的WCF服务 数据合同定义如下 [DataContract] public class OptionData { [DataMember] public string Book { get; set; } [DataMember] public string Id { get; set; } [DataMember] public string DealId { g

我有返回Json的WCF服务

数据合同定义如下

  [DataContract]
    public class OptionData
    {
        [DataMember]
        public string Book { get; set; }
        [DataMember]
        public string Id { get; set; }
        [DataMember]
        public string DealId { get; set; }
        [DataMember]
        public string DeliveryDate { get; set; }
        [DataMember]
        public string ExpiryDate { get; set; }
   }
以及定义如下的运营合同

[Description("Returns List of Options by user id")]
        [WebGet(UriTemplate = "{sessionId}/Application/{applicationId}?start={start}&limit={limit}&page={page}", ResponseFormat = WebMessageFormat.Json)]
        public List<OptionData> GetAllTask(string sessionId, string applicationId)
[说明(“按用户id返回选项列表”)]
[WebGet(UriTemplate=“{sessionId}/Application/{applicationId}?start={start}&limit={limit}&page={page}”,ResponseFormat=WebMessageFormat.Json)]
公共列表GetAllTask(字符串sessionId、字符串applicationId)
我需要向OptionData类动态添加新的DataMember字段


最好的做法是什么?

我认为这是不可能的

让我们先考虑一下您的DataContract是什么:它是您的服务如何定义它所知道的内容的——无论是作为输入还是输出。客户机必须通过元数据交换发现或从您提供的静态代理类(可能在dll中)中找到这一点

如果您随时更改合同,您的服务将无法让其客户知道合同已更改。根本没有办法即时更改合同

即使您在运行中更改了类的定义,包括适当的属性等,客户机也无法找到它,因为合同之前已经发布

我无法想象需要什么样的机制来与客户机实时交流这样的更改


我能想到的唯一解决办法是使用一个参数,该参数接受字符串,并允许客户端以XML或类似格式传递数据,而XML或类似格式可以是任何形式。这是一个相当令人讨厌的黑客行为…

如果您需要动态控制RESTful服务返回的数据结构,我认为您唯一的选择是返回类似XDocument的内容。您的服务操作可以创建任意结构的XDocument并返回该文档。尽管如此,我不确定当WCF尝试将XDocument序列化为JSON时会发生什么

只要接收json的客户端知道如何处理动态添加的类成员,您就可以使用此问题的公认答案中概述的Expando对象策略。它使用ServiceStack库,但您可以提取必要的代码来做您想做的事。ExpandoObject的简单键/值对方法如中所述


编辑:我应该指出,这种方法不依赖于WCF,因此根据问题的上下文,它可能不是您所需要的。

如果您知道需要JSON,您可以自己控制序列化(请参阅)-只需使用现有库返回JSON字符串即可

另一种选择是,如果您知道所有可能的字段名,就只告诉我们

最后一种选择是使用WCF用于的相同模式-只需将所有未知属性附加到单个集合对象(
ExtensionData
ExtensionData
只是一个键/值对字典。不幸的是-
ExtensionData
不能直接写入。这将是我模拟
IExtensibleDataObject
正在做什么的方法

[DataContract]
public class OptionData 
{
    [DataMember]
    public string Book { get; set; }
    [DataMember]
    public string Id { get; set; }
    [DataMember]
    public string DealId { get; set; }
    [DataMember]
    public string DeliveryDate { get; set; }
    [DataMember]
    public string ExpiryDate { get; set; }
    [DataMember]
    public Dictionary<string, string> Metadata { get; set;}
} 
[DataContract]
公共类选项数据
{
[数据成员]
公共字符串书{get;set;}
[数据成员]
公共字符串Id{get;set;}
[数据成员]
公共字符串DealId{get;set;}
[数据成员]
公共字符串DeliveryDate{get;set;}
[数据成员]
公共字符串过期日期{get;set;}
[数据成员]
公共字典元数据{get;set;}
} 

我最近在这里发布的文章中遇到了这个问题:


我的解决方案是使用ExpandoObject。但是,我必须使用Newtsoft.json进行json序列化,然后我必须让我的Web服务返回原始文本(而不是依赖WCF序列化)。如果你愿意,我很乐意发布我的代码。也许有一种方法可以实现动态数据契约,但我无法理解。但我的解决方案起到了作用

根据他的代码示例,他正在使用REST,因此不会有元数据交换或代理类。这看起来仍然是一件危险的事情。这是真的。相反,我建议使用一种更为RESTful的方法,它依赖于链接在应用程序中实现此功能。客户机将使用这些链接访问所需的任何特例类结构。当然,这不是格雷戈里要问的问题:)我谦恭地要求得到代码,因为它正是我目前正在学习的东西。。谢谢也许我在这里的回答会有所帮助: