Json 使用 Json.Net 反序列化 html 字符串的问题

Problem with Json Deserialization of html string using Json.Net

我不是 json 方面的专家,实际上我上周开始使用它,但我发现自己在尝试将以下 Json 映射到 class 时遇到了麻烦.

S 到目前为止,我已经将浏览器中的数据复制到不同的 Json 文件中(隔离数据以查看问题)并且我意识到 属性 Config 打乱反序列化过程。如果我 (1) 抓取整个数据并 (2) 将其放入文件并 (3) 添加扩展名 .json 然后稍后 (4) 只需删除配置 属性,一切正常一个魅力。但我希望能够反序列化整个东西。

为了读取 url,我正在使用 Flurl 从响应中生成一个字符串,正如我在之前 using the GetStringAsync() and for generating the Classes I just paste the response from Flurl or Postman into a Json2Csharp converter.现在对于反序列化,我使用 Json.Net 尝试了以下操作。

//Test 1
string cleanseStr = Regex.Unescape(FlurlResponse);
var myObj = JsonConvert.DeserializeObject<MyModel>(cleanseStr );

//Test 2
FlurlResponse= FlurlResponse.Replace("\\\", "\\");            
FlurlResponse= FlurlResponse.Replace("\\", "\");
var myObj = JsonConvert.DeserializeObject<MyModel>(FlurlResponse);```

//Test 3
FlurlResponse= FlurlResponse.Replace("\\\", "\\");            
string cleanseStr = Regex.Unescape(FlurlResponse);
var myObj = JsonConvert.DeserializeObject<MyModel>(cleanseStr );

到目前为止,我没有运气。我在 json 的 beginningend 得到 errors 说 "cannot convert string into [MyModel]"。我还从 Test1Test2 中获取了响应值(如果我没记错的话)并使用 "Json" 到 "Unserialized print_r" 作为我的设置,并将它们与我手动反序列化(在使用 JsonConvert.DeserializeObject 之前)进行比较,我得到了相同的结果。

此刻我一直在想 为了正确反序列化 HTML 字符串 我错过了什么在配置 属性 的 Json 中。可能过去遇到过同样问题的人可以帮助我反序列化或提供任何建议。

Error: Newtonsoft.Json.JsonSerializationException: 'Error converting value blah and 4millions characters later... "value":"<span fontWeight=\" to type TestingAPI.MyModel'. Path '', line 1, position 250 (for Test2) or 1950 (for Test1 and 3, 1950 means the end of the file).

ConfigProperty.json,真正重要的是格式而不是字符串的单词,我将所有符号都保留为原始 属性。

"{\"Config\":[{\"id\":1,\"description\":\"Title\",\"value\":\"blah, blah\"},{\"id\":2,\"description\":\"Dislcaimer\",\"value\":\"<span fontWeight=\\"bold\\"> blah- </span>\r\n<br/><br/>blah 101 bl.ah. <span fontWeight=\\"bold\\"> blah (blah) blah 101 blah\r\n blah blah (blah)</span> blah, blah,\r\n blah. blah.\r\n blah, blah. blah, blah\r\n blah.\r\n<br/><br/>blah, blah, blah, blah blah\r\n blah blah-ah blah. blah (bl-ah blah, bl-ah blah, bl-ah blah, and >blah)\r\n blah.\r\n<br/><br/>blah, blah\r\n blah. \r\n<br/><br/>blah:<a 
href=\\"http://blah.blah.blah/blah/blah/blah.htm#blah\\">http://blah.blah.blah/blah/blah/blah.htm#blah</a>\"}]}"

编辑

我以一种不太愉快的方式解决了我的问题,手动反序列化:

string cleanseStr= Regex.Unescape(FlurlResponseString);
cleanseStr= cleanseStr.Replace("\r\n", "");
cleanseStr= cleanseStr.Replace("\\\", "\\");
cleanseStr= cleanseStr.Replace("=\"", "=\\"");
cleanseStr= cleanseStr.Remove(0, 1);
cleanseStr= cleanseStr.Remove(scapedJson.Length - 1, 1);
MyModel _myModel= new MyModel();
JsonConvert.PopulateObject(cleanseStr, _myModel);

正确的方法是@BrianRogers提出的,谢谢@BrianRogers

我认为这里真正的问题是原来的JSON被双序列化了。也就是说,它从对象序列化为 JSON,然后 JSON 字符串再次被序列化 ,导致字符串中出现额外的反斜杠和引号。

因此,要反序列化它,您需要执行相反的操作:将下载的双序列化 JSON 反序列化为普通 JSON 字符串,然后将该字符串反序列化为对象。

我能够使用以下代码成功完成此操作 (Flurl.Http + Json.Net):

string json = await "https://gis.cdc.gov/grasp/fluView6/GetFlu6AllDataP".GetStringAsync();
json = JsonConvert.DeserializeObject<string>(json);
MyModel model = JsonConvert.DeserializeObject<MyModel>(json);

使用以下模型类:

public class MyModel
{
    public List<Group> Group { get; set; }
    public List<Season> Season { get; set; }
    public List<Age> Age { get; set; }
    public List<VirusType> VirusType { get; set; }
    public List<VirusData> VirusData { get; set; }
    public List<Config> Config { get; set; }
    public List<LastWeek> LastWeek { get; set; }
}

public class Group
{
    public string Name { get; set; }
    public int ID { get; set; }
}

public class Season
{
    public int SeasonID { get; set; }
    public string Description { get; set; }
    public int StartWeek { get; set; }
    public int EndWeek { get; set; }
    public bool Enabled { get; set; }
    public string Label { get; set; }
    public bool ShowLabType { get; set; }
}

public class Age
{
    public int AgeID { get; set; }
    public string Label { get; set; }
    public string Color_HexValue { get; set; }
    public bool Enabled { get; set; }
}

public class VirusType
{
    public int VirusID { get; set; }
    public string Description { get; set; }
    public string Label { get; set; }
    public int StartMMWRID { get; set; }
    public int EndMMWRID { get; set; }
    public int DisplayOrder { get; set; }
    public string ColorName { get; set; }
    public string Color_HexValue { get; set; }
    public int LabTypeID { get; set; }
    public int SortID { get; set; }
}

public class VirusData
{
    public int VisrusID { get; set; }
    public int AgeID { get; set; }
    public int Count { get; set; }
    public int MMWRID { get; set; }
    public int Seasonid { get; set; }
    public int PublishYearWeekID { get; set; }
    public string LoadDateTime { get; set; }
}

public class Config
{
    public int ID { get; set; }
    public string Description { get; set; }
    public string Value { get; set; }
}

public class LastWeek
{
    public int MMWRID { get; set; }
    public DateTime WeekEnd { get; set; }
    public int WeekNumber { get; set; }
    public DateTime WeekStart { get; set; }
    public int Year { get; set; }
    public string YearWeek { get; set; }
    public int SeasonID { get; set; }
}