Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
704 views
in Technique[技术] by (71.8m points)

vb.net - How can I do JSON serializer ignore navigation properties?

I am exactly in the same case that this question: How do I make JSON.NET ignore object relationships?

I see the proposed solution and I know I must use a Contract Revolver, and I also see the code of the Contract Resolver, but I do not know how to use it.

  • Should I use it in the WebApiConfig.vb?
  • Should I modify my Entity Model anyway?
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

It is a useful question?? and I hope this help:

A)

If you have created your models manually (without Entity Framework), mark the relation properties as virtual first.

If your models were created by EF, It has already done it for you and each Relation Property is marked as virtual, as seen below:

enter image description here

Sample class:

public class PC
{
    public int FileFolderId {get;set;}

    public virtual ICollection<string> Libs { get; set; }
    public virtual ICollection<string> Books { get; set; }
    public virtual ICollection<string> Files { get; set; }
}

B)

Those relation properties can now be ignored by the JSON serializer by using the following ContractResolver for JSON.NET:

CustomResolver:

class CustomResolver : DefaultContractResolver
{
    private readonly List<string> _namesOfVirtualPropsToKeep=new List<string>(new String[]{});

    public CustomResolver(){}

    public CustomResolver(IEnumerable<string> namesOfVirtualPropsToKeep)
    {
        this._namesOfVirtualPropsToKeep = namesOfVirtualPropsToKeep.Select(x=>x.ToLower()).ToList();
    }

    protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
    {
        JsonProperty prop = base.CreateProperty(member, memberSerialization);
        var propInfo = member as PropertyInfo;
        if (propInfo != null)
        {
            if (propInfo.GetMethod.IsVirtual && !propInfo.GetMethod.IsFinal
                && !_namesOfVirtualPropsToKeep.Contains(propInfo.Name.ToLower()))
            {
                prop.ShouldSerialize = obj => false;
            }
        }
        return prop;
    }
}

C)

Finally, to serialize your model easily use the above ContractResolver. Set it up like this:

// -------------------------------------------------------------------
// Serializer settings
JsonSerializerSettings settings = new JsonSerializerSettings
{
    // ContractResolver = new CustomResolver();
    // OR:
    ContractResolver = new CustomResolver(new []
    {
        nameof(PC.Libs), // keep Libs property among virtual properties
        nameof(PC.Files) // keep Files property among virtual properties
    }),
    PreserveReferencesHandling = PreserveReferencesHandling.None,
    ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
    Formatting = Formatting.Indented
};

// -------------------------------------------------------------------
// Do the serialization and output to the console
var json = JsonConvert.SerializeObject(new PC(), settings);
Console.WriteLine(json);

// -------------------------------------------------------------------
// We can see that "Books" filed is ignored in the output:
// {
//  "FileFolderId": 0,
//  "Libs": null,
//  "Files": null
// }

Now, all the navigation (relation) properties [virtual properties] will be ignored automatically except you keep some of them by determine them in your code.??

Live DEMO


Thanks from @BrianRogers for his answer here.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...