使用可变属性名称反序列化JSON

时间:2017-11-27 09:32:13

标签: c# json json.net

我想从here.

中取出json

与此类似:

Note that this second technique will cause all files within a given application to be compiled in debug mode. The first technique will cause only that particular file to be compiled in debug mode.

Important: Running applications in debug mode does incur a memory/performance overhead. You should make sure that an application has debugging disabled before deploying into production scenario.

 Stack Trace: 


[NullReferenceException: Object reference not set to an instance of an object.]
   System.Xml.Schema.Preprocessor.BuildSchemaList(XmlSchema schema) +6527330
   System.Xml.Schema.Preprocessor.Execute(XmlSchema schema, String targetNamespace, Boolean loadExternals) +526
   System.Xml.Schema.XmlSchemaSet.PreprocessSchema(XmlSchema& schema, String targetNamespace) +168
   System.Xml.Schema.XmlSchemaSet.Add(String targetNamespace, XmlSchema schema) +60
   System.Xml.Schema.XmlSchemaSet.Add(XmlSchema schema) +197
   System.Collections.CollectionBase.System.Collections.IList.Add(Object value) +156
   ASP.defaultwsdlhelpgenerator_aspx.Page_Load(Object sender, EventArgs e) +1851
   System.Web.UI.Control.OnLoad(EventArgs e) +102
   System.Web.UI.Control.LoadRecursive() +67
   System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +3810

 Version Information: Microsoft .NET Framework Version:4.0.30319; ASP.NET Version:4.7.2110.0

}

我想反序列化:

{
"BW": {
    "Neujahrstag": {
        "datum": "2017-01-01",
        "hinweis": ""
    },
    "Heilige Drei K\u00f6nige": {
        "datum": "2017-01-06",
        "hinweis": ""
    },
    "Gr\u00fcndonnerstag": {
        "datum": "2017-04-13",
        "hinweis": "Gem\u00e4\u00df \u00a7 4 Abs. 3 des Feiertagsgesetzes von Baden-W\u00fcrttemberg[10] haben Sch\u00fcler am Gr\u00fcndonnerstag und am Reformationstag schulfrei. In der Regel legt das Kultusministerium die Ferientermine so fest, dass diese beiden Tage in die Osterferien bzw. in die Herbstferien fallen."
    },
    "Karfreitag": {
        "datum": "2017-04-14",
        "hinweis": ""
    }
},
"BY": {
    "Neujahrstag": {
        "datum": "2017-01-01",
        "hinweis": ""
    },
    "Heilige Drei K\u00f6nige": {
        "datum": "2017-01-06",
        "hinweis": ""
    }
}

但是由于属性名称没有修复,我无法做到这一点。

我也尝试过使用JObject.Parse(),但这对我没有帮助。

关于如何做到这一点的任何想法?

2 个答案:

答案 0 :(得分:3)

首先更新Holiday以处理属性名称

public class Holiday {
    [JsonProperty("datum")]
    public DateTime Date { get; set; }
    [JsonProperty("hinweis")]
    public string Note { get; set; }
}

接下来,您要反序列化为嵌套字典

var rawRoot = JsonConvert.DeserializeObject<Dictionary<string, Dictionary<string, Holiday>>>(json);

最后,您想要遍历词典以获得最终结果

var root = new Root {
    States = rawRoot.Select(stateKvp => new State() {
        Holidays = stateKvp.Value.Select(holidayKvp => holidayKvp.Value).ToArray()
    })
    .ToArray()
};
然而,你确实松开了钥匙,因为它们不属于你的最终模型。

答案 1 :(得分:1)

如果您将模型修改为:

public class Root : Dictionary<string, State> { }

public class State : Dictionary<string, Holiday> { }

public class Holiday {
    [JsonProperty(PropertyName = "datum")]
    public DateTime Date { get; set; }

    [JsonProperty(PropertyName = "hinweis")]
    public string Note { get; set; }
}

您可以使用此反序列化:

var root = JsonConvert.DeserializeObject<Root>(str);
var firstBwHoliday = root["BW"]?["Neujahrstag"].Date;