Подтвердить что ты не робот

JSON.Net Игнорировать свойство во время десериализации

У меня есть класс, настроенный следующим образом:

public class Foo
{
    public string string1 { get; set; }
    public string string2 { get; set; }
    public string string3 { get; set; }
}

Я использую Json.Net для десериализации следующего Json Response:

string json = "[{\"number1\": 1, \"number2\": 12345678901234567890, \"number3\": 3},      
{\"number1\": 9, \"number2\": 12345678901234567890, \"number3\": 8}]";

Код десериализации:

List<Foo> foos = JsonConvert.DeserializeObject<List<Foo>>(json);

Второе число превышает int-64, но мне не важно получить это значение. Есть ли способ передать свойство "number2" в строку или полностью игнорировать его во время десериализации?

Я попытался добавить атрибут '[JsonConverter (typeof (string))]' к свойству string2, но получить ошибку: "Ошибка при создании System.String". Я также попытался установить typeof (десятичный).

Я также пытался использовать [JsonIgnore], но это не работает.

4b9b3361

Ответ 1

Вы можете использовать свойство MissingMemberHandling объекта JsonSerializerSettings.

Пример использования:

var jsonSerializerSettings = new JsonSerializerSettings();
jsonSerializerSettings.MissingMemberHandling = MissingMemberHandling.Ignore;

JsonConvert.DeserializeObject<YourClass>(jsonResponse, jsonSerializerSettings);

Подробнее здесь.

Ответ 2

Это обходное решение, но вы можете создать метод для ручной загрузки json. Если это слишком много данных для загрузки без автоматического десериализатора, просто удалите узлы, которые вы не хотите. Это намного медленнее, хотя.

public static List<Foo> FromJson(string input) {
    var json = JToken.Parse(input);
    json["key"].Remove();
    var foo = JsonConvert.DeserializeObject<List<Foo>>(json.ToString());

}

Это интересная проблема, я задаюсь вопросом, есть ли у кого-то лучшее решение для нее.

Ответ 3

Здесь Newtonsoft Json предпочитает игнорировать свойство без необходимости изменять класс на основе http://james.newtonking.com/json/help/index.html?topic=html/ReducingSerializedJSONSize.htm

Этот используется для игнорирования ленивых ссылочных свойств EF или Linq2Sql

public class DynamicContractResolver : DefaultContractResolver
{
    protected override IList<JsonProperty> CreateProperties(Type type, 
        MemberSerialization memberSerialization)
    {
        Func<Type,bool> includeProperty = t => t.IsValueType || t.Namespace.StartsWith("System") && t.Namespace.StartsWith("System.Data")==false; 
        IList<JsonProperty> properties = base.CreateProperties(type, memberSerialization);
        var allProperties = properties.Select (p => new{p.PropertyName,Including=includeProperty(p.PropertyType), p.PropertyType});//.Dump("props");
        var warnProperties=allProperties.Where (a =>a.Including && a.PropertyType.IsValueType==false && a.PropertyType.Name.IsIgnoreCaseMatch("String")==false) ;

        //linq pad debugging helper
        //var propertyTypesSerializing= allProperties.Where (p => p.Including).Select (p => p.PropertyType).Distinct().OrderBy (p => p.Name).Dump();

        if(warnProperties.Any())
        {
            //LinqPad helper
            //Util.Highlight(warnProperties.ToArray()).Dump("warning flag raised, aborting");
            throw new ArgumentOutOfRangeException();
        }

        properties = properties.Where(p =>includeProperty(p.PropertyType)).ToList();
        return properties;
    }
}

Все вызовы .Dump() - это просто помощники отладки linqpad, а не вызовы методов.

Использование образца:

var inactives = from am in Aspnet_Memberships
        join mm in Member_members on am.UserId equals mm.Member_guid
        where mm.Is_active==false && mm.Org_id==1
        select new{am,mm};
        //inactives.Take(4).ToArray().Dump();
        var serialized = JsonConvert.SerializeObject(
            inactives.Skip(1).Select(i => i.mm).First(), 
            new  JsonSerializerSettings()
            {
                ContractResolver = new DynamicContractResolver(), 
                PreserveReferencesHandling = PreserveReferencesHandling.None,
                ReferenceLoopHandling= ReferenceLoopHandling.Ignore
            }); 
            //.Dump();

Ответ 4

Подобно @Maslow-решению, вы можете использовать другой общий "ignorer" общего назначения,:

var jsonResolver = new IgnorableSerializerContractResolver();
// ignore your specific property
jsonResolver.Ignore(typeof(Foo), "string2");
// ignore single datatype
jsonResolver.Ignore(typeof(System.Data.Objects.DataClasses.EntityObject));
var jsonSettings = new JsonSerializerSettings() { ReferenceLoopHandling = ReferenceLoopHandling.Ignore, ContractResolver = jsonResolver };