我的代码结构如下。
public class Stats { public string URL { get; set; } public string Status { get; set; } public string Title { get; set; } public string Description { get; set; } public int Length { get; set; } }
和
public class UrlStats { public string URL { get; set; } public int TotalPagesFound { get; set; } public List<Stats> TotalPages { get; set; } public int TotalTitleTags { get; set; } public List<Stats> TotalTitles { get; set; } public int NoDuplicateTitleTags { get; set; } public List<Stats> DuplicateTitles { get; set; } public int NoOverlengthTitleTags { get; set; } public List<Stats> OverlengthTitles { get; set; } }
基本上我正在扫描网站以获取统计信息,例如标题标签,重复标题等。
我正在使用JQuery并向Web服务进行AJAX调用并检索url统计信息,而该过程正在运行以显示到目前为止收集的用户url统计信息,因为扫描大型网站需要花费大量时间。因此,每隔5秒,我就会从服务器检索统计信息。现在的问题是我需要在扫描处理完成时(而不是更新期间)最后发送所有List变量数据。现在发生了什么事,List<Stats>变量数据也在更新期间发送,这是一大块数据,我只想发送int显示过程更新所需的类型变量。
List<Stats>
int
通过在互联网上搜索,我找不到解决我的问题的有用信息,我发现Json.NET是一个非常好的库,但是我真的不知道如何正确使用它来获取我想要的东西。
基本上,我正在寻找在运行时根据属性的数据类型对属性进行序列化的方法。
有两种不同的方法可以解决您的问题。
如果您要更频繁地更改类,则应该选择第一个,因为第一种方法可以避免忘记序列化新添加的属性。此外,如果您要添加其他要以相同方式序列化的类,则可以重用得多。
如果只有这两个类,并且很可能它们不会更改,则可以选择第二种方法来简化解决方案。
第一种方法是使用JsonConverter仅通过包含具有type的属性来序列化类或结构的自定义int。代码可能看起来像这样:
JsonConverter
class IntPropertyConverter : JsonConverter { public override bool CanConvert(Type objectType) { // this converter can be applied to any type return true; } public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { // we currently support only writing of JSON throw new NotImplementedException(); } public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { if (value == null) { serializer.Serialize(writer, null); return; } // find all properties with type 'int' var properties = value.GetType().GetProperties().Where(p => p.PropertyType == typeof(int)); writer.WriteStartObject(); foreach (var property in properties) { // write property name writer.WritePropertyName(property.Name); // let the serializer serialize the value itself // (so this converter will work with any other type, not just int) serializer.Serialize(writer, property.GetValue(value, null)); } writer.WriteEndObject(); } }
然后,您必须使用来装饰类JsonConverterAttribute:
JsonConverterAttribute
[JsonConverter(typeof(IntPropertyConverter))] public class UrlStats { // ... }
免责声明: 此代码仅经过非常粗略的测试。
第二种解决方案看起来更简单:您可以使用JsonIgnoreAttribute来装饰要为序列化排除的属性。另外,您可以通过显式包括要序列化的属性,从“黑名单”切换为“白名单”。这是一些示例代码:
JsonIgnoreAttribute
黑名单:( 为了更好的概述,我对属性进行了重新排序)
[JsonObject(MemberSerialization.OptOut)] // this is default and can be omitted public class UrlStats { [JsonIgnore] public string URL { get; set; } [JsonIgnore] public List<Stats> TotalPages { get; set; } [JsonIgnore] public List<Stats> TotalTitles { get; set; } [JsonIgnore] public List<Stats> DuplicateTitles { get; set; } [JsonIgnore] public List<Stats> OverlengthTitles { get; set; } public int TotalPagesFound { get; set; } public int TotalTitleTags { get; set; } public int NoDuplicateTitleTags { get; set; } public int NoOverlengthTitleTags { get; set; } }
白名单:( 也已重新排序)
[JsonObject(MemberSerialization.OptIn)] // this is important! public class UrlStats { public string URL { get; set; } public List<Stats> TotalPages { get; set; } public List<Stats> TotalTitles { get; set; } public List<Stats> DuplicateTitles { get; set; } public List<Stats> OverlengthTitles { get; set; } [JsonProperty] public int TotalPagesFound { get; set; } [JsonProperty] public int TotalTitleTags { get; set; } [JsonProperty] public int NoDuplicateTitleTags { get; set; } [JsonProperty] public int NoOverlengthTitleTags { get; set; } }