跳过[ScriptIgnore]一次

时间:2012-10-08 19:15:17

标签: c# asp.net-mvc-3 entity-framework-4 javascriptserializer scriptignore

这种情况的环境:

  • 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可以有多个关联的BarsBar有一个关联的Foo

    回到这种情况。我使用include语句在控制器中加载此关联:

    .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);
     }
    }
    

    所以我将这个viewmodel传递给视图并序列化它:

    @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的集合.. 。等等。我只是想第一次抓住Bar的集合。有没有办法实现这个目标?我意识到它将尝试从Bar序列化Foo,但它将是空的。这一切都是通过热切加载完成的,整个对象图已经构建完毕。

  • 1 个答案:

    答案 0 :(得分: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),但是,我从提供的数据库中获得了如此多的循环引用,它似乎是当时最好的解决方案。