【问题标题】:How to parse JSON received in MVC Controller如何解析在 MVC 控制器中收到的 JSON
【发布时间】:2018-03-01 16:51:46
【问题描述】:

我有一个 JSON 文件,它通过来自客户端的 POST 请求发送到 MVC 控制器。由于没有在 C# 中存储 JSON 的直接方法,因此我正在尝试创建模型来存储数据。这是 JSON 的结构:

{
    "SubscriptionsType1": {
        "Obj1": {
            "Value1": "3454234",
            "Value2": "345643564",
            "Value3": "665445",
            "Value4": "True"
        },
        "Obj2": {
            "Value1": "3454234",
            "Value2": "345643564",
            "Value3": "665445",
            "Value4": "True"
        },
        "Obj3": {
            "Value1": "3454234",
            "Value2": "345643564",
            "Value3": "665445",
            "Value4": "True"
        }
    },
"SubscriptionsType2": {
                "Obj1": {
                    "Value1": "3667635",
                    "Value2": "34563456",
                    "Value3": "234545",
                    "Value4": "False"
                },
                "Obj2": {
                    "Value1": "97865",
                    "Value2": "356356",
                    "Value3": "665757445",
                    "Value4": "True"
                },
                "Obj3": {
                    "Value1": "3454234",
                    "Value2": "345643564",
                    "Value3": "665445",
                    "Value4": "False"
                }
            },
    //etc..

    }

型号如下:

  public class RootObject {
        public IEnumerable<SubscriptionObj> Subscriptions { get; set; }
}


public class Subscriptions {
    IEnumerable<SubscriptionObj> objs;
}


public class SubscriptionObj
{
    public Int64 Value1 {get;set;}
    public Int64 Value2 {get;set;}
    public Int64 Value3 {get;set;}
    public Boolean Value4 {get;set;}
}

由于某种原因,如果我使用这种结构创建模型类,根对象在从控制器传递 JSON 对象后仍然为空。 但是,当我显式创建属性来存储 JSON 对象的每个值时,它就可以工作了。由于 JSON 对象没有固定数量的元素,因此我需要一种方法来动态存储每个属性。 如何做到这一点?

【问题讨论】:

  • @L.B 我已经用过那个网站了。它不使用动态大小的集合来存储属性。它仅对模型进行硬编码以专门适合 JSON 对象。

标签: c# asp.net json http model-view-controller


【解决方案1】:

由于根对象和订阅中的键不同,您应该使用字典。

public class RootObject : Dictionary<string, Subscriptions> { }

public class Subscriptions : Dictionary<string, SubscriptionObj> { }

public class SubscriptionObj {
    public Int64 Value1 {get;set;}
    public Int64 Value2 {get;set;}
    public Int64 Value3 {get;set;}
    public Boolean Value4 {get;set;}
}

以上内容将序列化为 OP 中的 JSON,但您会丢失强类型键/属性名称

【讨论】:

    【解决方案2】:

    与你的 c# 类对应的 json 应该使用数组,比如

    {
        "Subscriptions": [ 
        {  "Obj": [   
            {
                "Value1": "3454234",
                "Value2": "345643564",
                "Value3": "665445",
                "Value4": "True"
            },
            {
                "Value1": "3454234",
                ...
            },
            {
                "Value1": "3454234",
                ...
            } ] 
        },  //end of Subscription 1
        {  "Obj": [   
            {
                "Value1": "3454234",
                ...
            },
            {
                "Value1": "3454234",
                ...
            },
            {
                "Value1": "3454234",
                ...
            } ] 
        }  //end of Subscription 2
        ] 
    }
    

    与您的没有数组的 json 对应的 c# 类看起来像:

    public class ObjType
    {
        public string Value1 { get; set; }
        public string Value2 { get; set; }
        public string Value3 { get; set; }
        public string Value4 { get; set; }
    }
    
    public class SubscriptionsType
    {
        public ObjType Obj1 { get; set; }
        public ObjType Obj2 { get; set; }
        public ObjType Obj3 { get; set; }
    }
    
    public class RootObject
    {
        public SubscriptionsType SubscriptionsType1 { get; set; }
        public SubscriptionsType SubscriptionsType2 { get; set; }
    }
    

    【讨论】:

    • JSON 确实需要重组,但您拥有的模型不是动态的,这是我解析具有任意数量对象的 JSON 对象所需要的。
    【解决方案3】:

    对于该数据结构,我会将对象反序列化为动态的。那么你可以检查是否有“SubscriptionsType1”或“SubscriptionsType2”,...

    我将使用动态创建模型类并将它们填充到自酿的反序列化方法/类中。

    模型的设计不是序列化友好的,你可以通过改变与调用者的合同来改变你将得到的json吗?

    如果是这样,这是我的建议:

    { "Subscriptions": [
        {
        "Objects": [{
            "Value1": "3454234",
            "Value2": "345643564",
            "Value3": "665445",
            "Value4": "True"
        },
        {
            "Value1": "3454234",
            "Value2": "345643564",
            "Value3": "665445",
            "Value4": "True"
        },
        {
            "Value1": "3454234",
            "Value2": "345643564",
            "Value3": "665445",
            "Value4": "True"
        }
        ]
    },
    {
                "Objects": [
                {
                    "Value1": "3667635",
                    "Value2": "34563456",
                    "Value3": "234545",
                    "Value4": "False"
                },
                {
                    "Value1": "97865",
                    "Value2": "356356",
                    "Value3": "665757445",
                    "Value4": "True"
                },
                {
                    "Value1": "3454234",
                    "Value2": "345643564",
                    "Value3": "665445",
                    "Value4": "False"
                }]
            },
    //etc..
    ]
    }
    

    您的模型将更改为:

    public class RootObject {
            public Subscriptions SubscriptionCollection { get; set; }
    }
    
    
    public class Subscriptions {
        IEnumerable<SubscriptionObj> objs;
    }
    
    public class SubscriptionObj
    {
        public Int64 Value1 {get;set;}
        public Int64 Value2 {get;set;}
        public Int64 Value3 {get;set;}
        public Boolean Value4 {get;set;}
    }
    

    这就是你想要得到的吗?

    【讨论】:

    • +1 用于 JSON 的重组。为了正确进行序列化,这是必要的。这些模型虽然不起作用,但根据 Nkosi 的回答,似乎实际上需要字典。
    【解决方案4】:

    从您的 JSON 文件中,我们可以提取以下模型类:

    public class RootModel{
        public SubscriptionTypeModel SubscriptionsType1 { get; set; }
    
        public SubscriptionTypeModel SubscriptionsType2 { get; set; }
    
        //etc...
    }
    
    public class SubscriptionTypeModel {
        public ObjectModel Obj1 { get; set; }
        public ObjectModel Obj2 { get; set; }
        public ObjectModel Obj3 { get; set; }
    }
    
    public class ObjectModel {
        public string Value1 { get; set; }
        public string Value2 { get; set; }
        public string Value3 { get; set; }
        public bool Value4 { get; set; }
    }
    

    如果订阅列表是动态的,那么您应该将 JSON 文件更改为如下所示:

    [
    {"Subscriptions": [
        {
            "Value1": "3454234",
            "Value2": "345643564",
            "Value3": "665445",
            "Value4": "True"
        },
        {
            "Value1": "3454234",
            "Value2": "345643564",
            "Value3": "665445",
            "Value4": "True"
        },
        {
            "Value1": "3454234",
            "Value2": "345643564",
            "Value3": "665445",
            "Value4": "True"
        }
    ]}, { "Subscriptions":[
                {
                    "Value1": "3667635",
                    "Value2": "34563456",
                    "Value3": "234545",
                    "Value4": "False"
                },
                {
                    "Value1": "97865",
                    "Value2": "356356",
                    "Value3": "665757445",
                    "Value4": "True"
                },
                {
                    "Value1": "3454234",
                    "Value2": "345643564",
                    "Value3": "665445",
                    "Value4": "False"
                }
            ]}
    ]
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-03-19
      • 2013-02-04
      • 2013-09-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多