0

这种情况的环境:

  • asp.net mvc 3
  • C#
  • 实体框架 4.3.1
  • JavaScriptSerializer

    我遇到过一种情况,最好包含一个标记为[ScriptIgnore]. 如果没有该属性,该字段将构成循环引用并导致引发异常。原因与此类似:

    public class Foo
    {
     public int FooId { get; set; }
    
     [ScriptIgnore]
     public virtual Collection<Bar> Bars { get; set; }
    }
    
    public class Bar
    {
     public int BarId { get; set; }
     public int FooId { get; set; }
     public virtual Foo Foo { get; set; }
    }
    

    所以你可以在这里看到,一个Foo可以有很多关联的Bars. 并且 aBar有一个关联的Foo.

    回到情况。我正在使用包含语句在控制器中加载此关联:

    .Include( foo => foo.Bars );
    

    没有抛出错误,因为 include 不受[ScriptIgnore]注释的影响。调试时,检查时正确构建关联。有一个 的列表foos,每个foo都有一个 的关联列表Bars

    现在我想序列化这个构造的列表。我有一个充满数据的视图模型,它看起来像这样:

    public class FooView
    {
     public List<Foo> Foos { get; set; }
    
     public string AsJson()
     {
      var serializer = new JavaScriptSerializer();
      return serializer.Serialize(this);
     }
    }
    

    所以我将此视图模型传递给视图并序列化它:

    @model FooView
    <script type="text/javascript">
     var fooViewModel = @( Html.Raw( Model.AsJson() ) );
    </script>
    

    不会引发异常,但是,序列化会正确跳过Bars标有 的字段 ( ) [ScriptIgnore]。经过consol.log(fooViewModel)检查,很明显有一个 的数组Foo,但是,Bar在任何Foos.

    有没有一种方法可以让我一次跳过这个[ScriptIgnore]标签?我意识到,如果它每次都跳过,那么序列化程序会序列化 Foo,查看并查看 Bar 类型的集合,序列化每个 Bar,注意 Bar 有一个关联的 Foo,序列化 Foo,注意 Foo 有一个 Bar 类型的集合。 。ETC。我只想抢Bar第一次的收藏。有没有办法做到这一点?我意识到它将尝试Foo从 Bar 序列化,但它将是空的。这一切都是通过预先加载完成的,并且整个对象图都已经构建好了。

  • 4

    1 回答 1

    2

    当我遇到这个问题时,我最终做的是用具有设置的 Json.NET 序列化程序替换序列化程序,特别是

    _jsonSerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
    

    Json.NET 将忽略引用循环中的对象并且不序列化它们。第一次遇到对象时,它将像往常一样被序列化,但如果遇到对象作为其自身的子对象,则序列化程序将跳过对其进行序列化。

    设置信息是http://james.newtonking.com/projects/json/help/index.html?topic=html/SerializingJSON.htm 我使用了http://blogs.msdn.com/b/henrikn/ archive/2012/02/18/using-json-net-with-asp-net-web-api.aspx 替换序列化程序,然后我将其默认添加到 global.asax.cs。

    configuration.Formatters.Insert(0, new JsonNetFormatter(serializerSettings));
    

    我意识到这是一种解决方法(实际上并不处理 scriptignore),但是,我从提供的数据库中获得了如此多的循环引用,这似乎是当时最好的解决方案。

    于 2012-10-08T20:01:15.007 回答