如何为复杂的 Json 有效负载设置属性及其值并进行序列化?

Posted

技术标签:

【中文标题】如何为复杂的 Json 有效负载设置属性及其值并进行序列化?【英文标题】:How can I set the attributes and its values for a complex Json payload and serialize? 【发布时间】:2020-07-02 02:29:13 【问题描述】:

我的框架中有以下结构。我有一个助手,其中有以下属性代码、解析器代码和序列化方法。在问题的另一部分链接到这个How to create one model class to use with multiple API methods that require different JSON payloads?

我现在有任何 API 采用带有根对象的大有效负载。我如何使用 SerializeForApiMethod 方法,因为它有根对象。我正在尝试为此 Jsonpayload 设置相同模型对象引用中的值。

//这里是Json架构


  "tagNode": 
    "query": null,
    "type": 0,
    "filter": null,
    "ldapPaths": null,
    "editPermissions": 0,
    "id": 0,
    "disallowed": false,
    "name": "NewTag"
  ,
  "parentId": 0


//Model class
public class TagModel

   public static TagModel mode = new TagModel
   
            endpointIds = new List<int>  -2147483612, -2147483611 ,
            tagIds = new List<int>  35, 37 , 
            id = -2147483639,
            parentId = 37,
            nodeId = 1,
            oldParentId = null,
            isEndpoint = false,
            state = 2,
            destinationTag = 2,



   ;

    //This Object I am Confused on how to Serialize as above schema it in the 
   //same class whichI w ant to set the values inside the TagModel instance. 
    //Also has same attributes like id and parentId used already in the 
    //other methods and also this complex payload has a class TagNode which is 
    //the root object. 
     [UseWithApiMethods("UpdateTag")]
     public TagNode tagNode  get; set; 
     public object query  get; set; 
     public int type  get; set; 
     public object filter  get; set; 
     public object ldapPaths  get; set; 
     public int editPermissions  get; set; 
     public int id  get; set; 
     public bool disallowed  get; set; 
     public string name  get; set; 
     public int parentId  get; set; 



             //For this Object I am able to serialize it
           [UseWithApiMethods("UpdateTagToRoot")]
            public int nodeId  get; set; 
            [UseWithApiMethods("UpdateTagToRoot")]
            public object oldParentId  get; set; 
            [UseWithApiMethods("UpdateTagToRoot")]
            public bool isEndpoint  get; set; 
            [UseWithApiMethods("UpdateTagToRoot")]
            public int state  get; set; 
            [UseWithApiMethods("UpdateTagToRoot")]
            public int destinationTag  get; set; 



              //For this Object I am able to serialize it
            [UseWithApiMethods("UpdateEndpointsToTags")]
            public List<int> endpointIds  get; set; 
            [UseWithApiMethods("UpdateEndpointsToTags")]
            public List<int> tagIds  get; set; 


          //For this Object I am able to serialize it
           [UseWithApiMethods("UpdateEndpointsFromTags")]
           public int id  get; set; 
           [UseWithApiMethods("UpdateEndpointsFromTags")] 
           public int parentId  get; set; 






【问题讨论】:

为什么要粘贴图片?它们不仅很烦人,而且会适得其反,我们无法在其中复制和粘贴数据,搜索引擎无法索引内容 @MichaelRandall 我已删除图像并将有效负载与对象放在一起 您打算将此模型用于哪些 API 方法?哪些属性应该使用哪些 API 方法进行序列化?我看不出有什么会阻止您在这个复杂模型上使用 [UseWithApiMethods] 属性,这与使用简单模型不同。您具体对什么感到困惑? @BrianRogers 我对如何在使用我拥有“TagModel”的同一个模型类中实现它感到困惑。另外,因为我在另一个有效负载中使用了一些属性。它确实允许我再次使用那些相同的,除非我将它们重命名为 id 和 parentId。我可以用另一种方式分配它们吗?我更新了关于我想要实现的目标的问题。 TagNode类的定义是什么? 【参考方案1】:

要使用来自其他问题的自定义解析器获取所需的 JSON 有效负载,您的类结构需要如下所示:

public class TagModel

    [UseWithApiMethods("UpdateTag")]
    public TagNode tagNode  get; set; 

    public class TagNode
    
        [UseWithApiMethods("UpdateTag")]
        public object query  get; set; 

        [UseWithApiMethods("UpdateTag")]
        public int type  get; set; 

        [UseWithApiMethods("UpdateTag")]
        public object filter  get; set; 

        [UseWithApiMethods("UpdateTag")]
        public object ldapPaths  get; set; 

        [UseWithApiMethods("UpdateTag")]
        public int editPermissions  get; set; 

        [UseWithApiMethods("UpdateTag")]
        public int id  get; set; 

        [UseWithApiMethods("UpdateTag")]
        public bool disallowed  get; set; 

        [UseWithApiMethods("UpdateTag")]
        public string name  get; set; 
    

    [UseWithApiMethods("UpdateEndpointsFromTags", "UpdateTag")]
    public int parentId  get; set; 

    ... (other properties for your other API methods) ...

请注意,您必须将[UseWithApiMethods("UpdateTag")] 放在根类中的tagNode 属性上以及放在要包含在JSON 中的TagNode 子类中的所有属性上。 (这是必要的,因为解析器只会包含您专门用 [UseWithApiMethods] 属性标记的属性。因此,如果您想全部包含它们,则需要将它们全部标记)。

对于parentId 属性,您已经将它用于UpdateEndpointsFromTags 方法,但这没问题;您还可以将其重用于其他方法,例如UpdateTag。您只需将方法名称添加到 [UseWithApiMethods] 属性,如下所示:

    [UseWithApiMethods("UpdateEndpointsFromTags", "UpdateTag")]
    public int parentId  get; set; 

这是一个演示:https://dotnetfiddle.net/6TqbFz

希望这是您正在寻找的并解决您的困惑。

【讨论】:

好吧有道理。如果我想在“UpdateTag”和“UpdateEndpointsFromTags”中为 parentId 使用不同的值怎么办。目前我已设置为 37。但我想将其设置为另一个数字。不影响“UpdateEndpointsFromTags”方法。这样做的原因是我想一键运行它们。 然后创建一个新的 TagModel 实例并将属性设置为您需要的任何值。请参阅我的答案中的小提琴。它表明正是这样做的。 是的,我检查了小提琴。这正是我想要做的,但无法在不允许的类下使用相同的参考名称“模型”创建。它抛出一个错误 "The class already contains a definition for model" 。我错过了什么吗? 您是否尝试在 TagModel 类中创建多个具有相同属性名称 model 的 TagModel 静态实例?如果是这样,你不能那样做。为静态属性指定不同的名称(例如,您可以调用一个 defaultModel 和另一个 modelForUpdate),或者创建 TagModel 类的模型实例 outside 而不是使用静态实例(此是更典型的解决方案),或者制作一个或多个工厂方法来创建模型实例。有很多可能的解决方案。 好的,我更改了静态属性名称。因为我现在想将所有属性及其值保存在同一个类中。但是今天我收到了 ***Exception。我的测试没有运行。我发布了一个不同的问题。这可能是由于 getter 和 setter 过载吗? ***.com/questions/60802619/…

以上是关于如何为复杂的 Json 有效负载设置属性及其值并进行序列化?的主要内容,如果未能解决你的问题,请参考以下文章

如何为可变长度有效负载格式化 NDEF 消息?

Firebase Cloud Messaging to Android 工作,但 iOS 失败。如何为 iOS 构建有效负载?

如何为 JSON 公开 REST 服务?

代码优先迁移:如何为新属性设置默认值?

如何为 Laravel / Eloquent 模型设置默认属性值?

Angular - 如何为可选输入属性设置默认值