Telerik MVC Grid with Ajax Binding using EntityObjects gets Circular References exception

前端 未结 4 768
说谎
说谎 2021-02-06 15:48

I have been using Telerik MVC Grid for quite a while now and It is a great control, however, one annoying thing keeps showing up related to using the grid with Ajax Binding to o

4条回答
  •  旧时难觅i
    2021-02-06 16:20

    The first solution works with the grid editing mode, but we have the same problem with the load of the grid that already has rows of objects with circular reference, and to resolve this we need to create a new IClientSideObjectWriterFactory and a new IClientSideObjectWriter. This is what I do:

    1- Create a new IClientSideObjectWriterFactory:

    public class JsonClientSideObjectWriterFactory : IClientSideObjectWriterFactory
    {
        public IClientSideObjectWriter Create(string id, string type, TextWriter textWriter)
        {
            return new JsonClientSideObjectWriter(id, type, textWriter);
        }
    }
    

    2- Create a new IClientSideObjectWriter, this time I do not implement the interface, I've inherited the ClientSideObjectWriter and overrided the AppendObject and AppendCollection methods:

    public class JsonClientSideObjectWriter : ClientSideObjectWriter
    {
        public JsonClientSideObjectWriter(string id, string type, TextWriter textWriter)
            : base(id, type, textWriter)
        {
        }
    
        public override IClientSideObjectWriter AppendObject(string name, object value)
        {
            Guard.IsNotNullOrEmpty(name, "name");
    
            var data = JsonConvert.SerializeObject(value,
                Formatting.None,
                new JsonSerializerSettings
                    {
                        NullValueHandling = NullValueHandling.Ignore,
                        ContractResolver = new PropertyNameIgnoreContractResolver()
                    });
    
            return Append("{0}:{1}".FormatWith(name, data));
        }
    
        public override IClientSideObjectWriter AppendCollection(string name, System.Collections.IEnumerable value)
        {
        public override IClientSideObjectWriter AppendCollection(string name, System.Collections.IEnumerable value)
        {
            Guard.IsNotNullOrEmpty(name, "name");
    
            var data = JsonConvert.SerializeObject(value,
                Formatting.Indented,
                new JsonSerializerSettings
                    {
                        NullValueHandling = NullValueHandling.Ignore,
                        ContractResolver = new PropertyNameIgnoreContractResolver()
                    });
    
            data = data.Replace("<", @"\u003c").Replace(">", @"\u003e");
    
            return Append("{0}:{1}".FormatWith((object)name, (object)data));
        }
    }
    

    NOTE: The replace its because the grid renders html tags for the client template in edit mode and if we don't encode then the browser will render the tags. I didn't find a workarround yet if not using a Replace from string object.

    3- On my Application_Start on Global.asax.cs I registered my new factory like this:

    DI.Current.Register(() => new JsonClientSideObjectWriterFactory());
    

    And it worked for all components that Telerik has. The only thing that I do not changed was the PropertyNameIgnoreContractResolver that was the same for the EntityFramework classes.

提交回复
热议问题