【问题标题】:Dynamically add a property to a class将属性动态添加到类
【发布时间】:2019-04-28 04:52:27
【问题描述】:

动态创建类属性的最佳方法是什么?

我必须创建基于 JSON 数据的 webhook 推送消息。 我创建了 2 个类,每个类都有多个属性,问题是即使没有填充属性(默认为 NULL),webhook push 格式错误。为避免这种情况,我必须根据需要创建属性。

有没有什么方法可以做到这一点? 描绘我需要的东西:

public class ChannelSettings
{
    public string channel { get; set; }
    public string username { get; set; }
    public string text { get; set; }
    public AttachSettings attachments { get; set; } //Here I would like to this property to be dynamic
}

public class AttachSettings
{
    public string fallback { get; set; }
    public string pretext { get; set; }
    public string text { get; set; }
    public string title { get; set; }
    public string author_name { get; set; }
    public string image_url { get; set; }
    public string author_icon { get; set; }
}
public string GenJSON(ChannelSettings channelSet)
{
    string output = JsonConvert.SerializeObject(channelSet);
    return output;
}

【问题讨论】:

  • 如果您添加一些示例数据以及您期望 JSON 的样子,这将更容易可视化...
  • "webhook push has wrong format" 我不明白这是什么意思。能否提供一些示例数据?
  • even if property is not filled (NULL by default)。你确定吗?似乎该属性存在于json中。否则不会有问题。 IMO 问题不应该是how to add a property to a class,而是how to define the properties that need to be serialized
  • 好的,所以基本上如果没有添加附加数据,那么我就有了那种 JSON:"{\"channel\":null,\"username\":\"user\" ,\"text\":\"test text\",\"attachments\":[{\"fallback\":null,\"pretext\":null,\"text\":null,\"title\ ":null,\"author_name\":null,\"image_url\":null,\"author_icon\":null,\"fields\":[]}]}",我想要的是:" {\"channel\":null,\"username\":\"user\",\"text\":\"test text\"}" 所以在没有数据的情况下不需要attachment section

标签: c# dynamic properties


【解决方案1】:

您可以使用ExpandoObject

    dynamic expandoObject = new ExpandoObject();
    expandoObject.NewProperty =  "newValue";

我认为example 对你有帮助。

【讨论】:

    【解决方案2】:

    我不知道我是否理解正确,但为什么不将此属性设为可选? 只需使用 AttachSettings?一切都会好起来的。

    【讨论】:

    • 因为类会序列化为 JSON。
    【解决方案3】:

    认为您真正想要的是将AttachSettings 用作字典之类的东西?:

    public class ChannelSettings
    {
        public string channel { get; set; }
        public string username { get; set; }
        public string text { get; set; }
        public Dictionary<string, string> attachments { get; set; } 
    }
    
    public ChannelSettings GetData()
    {
        return new ChannelSettings
        {        
            channel="one", username="user", text="text",
            attachments= new Dictionary<string, string>()
            {
                {"fallback","somevalue"},
                {"author_name","some author"},
                {"shoe_size","12},
                //...etc...
            }
        }
    }
    
    public string GenJSON(ChannelSettings channelSet)
    {
        string output = JsonConvert.SerializeObject(channelSet);
        return output;
    }
    

    这应该会产生类似于这样的 JSON:

    {
        "channel":"one",
        "username":"user",
        "text":"text",
        "attachments":[
            "fallbackvalue":"somevalue",
            "author_name":"some author",
            "shoe_size":"12"
        ]
    }
    

    【讨论】:

    • 谢谢,但是当附件中有数据时,JSON 字符串没有问题,问题是当没有数据时,我有很多空值。请检查我在主要消息下添加的示例。谢谢
    【解决方案4】:

    我能想到的最接近的是ExpandoObject。它似乎可以与任何弱类型的 WebService 一起使用,而且您确实提到了 JSON。

    在内部,它似乎比 Dictionary&lt;string, object&gt; 更多,带有一些语法糖、更改规则和隐式转换。所以当你有疑问时,你也可以只使用一个好的旧集合。

    【讨论】:

      【解决方案5】:

      您可以将参数类型设置为动态并对其进行序列化和反序列化,如下所示:

      class Program
      {
          static void Main(string[] args)
          {
              var channelSettings = new ChannelSettings();
      
              channelSettings.attachments = new AttachSettings();
              channelSettings.attachments.fallback = "test";
      
      
              var testSerialize = JsonConvert.SerializeObject(channelSettings);
      
              dynamic testDeserialize = JsonConvert.DeserializeObject<dynamic>(testSerialize);
      
              Console.WriteLine(testDeserialize.attachments.fallback); // here you can access the parameters
          }
      }
      
      public class ChannelSettings
      {
          public string channel { get; set; }
          public string username { get; set; }
          public string text { get; set; }
          public dynamic attachments { get; set; } //Here i would like to this property was dynamic
      }
      

      输出是:测试

      @GPW 也有另一种使用字典的解决方案,它适用于未知类型/大小的参数。

      【讨论】:

        【解决方案6】:

        感谢所有非常有用的帮助,我已经解决了我的问题,案例是频道类中的附件实例,我必须创建它的列表:

        public class ChannelSettings
        {
            public string channel { get; set; }
            public string username { get; set; }
            public string text { get; set; }
            public List<AttachSettings> attachments { get; set; }
        
        } 
        

        然后不实现它,如果在这种情况下 value 为空,我会得到我想要的结果。

        "{"channel":null,"username":"user","text":"测试文本","attachments":null}"

        一开始我想要的有点不同,但它的工作原理是一样的,所以不需要进一步的改变:)

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2011-01-15
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多