代码之家  ›  专栏  ›  技术社区  ›  JMP

如何防止ASP.NET MVC中的JSON序列化?

  •  17
  • JMP  · 技术社区  · 17 年前

    在开发一个ASP.NET MVC应用程序时,我在几个地方发现了JSonResult操作引发的异常“在序列化对象时检测到循环引用”。

    目前,我正在删除相关的引用,但理想情况下,我希望简单地标记该属性,以便JSON序列化程序忽略它。

    有人能建议我怎么做吗?

    5 回复  |  直到 13 年前
        1
  •  28
  •   Matthieu kelly    13 年前

    [ScriptIgnore] 应该 为你工作。

        2
  •  13
  •   Tom Mayfield    15 年前

    我通常发现,对于复杂对象,最好只通过创建临时的“中间”对象来序列化:

    例如,对于证词,我执行以下操作。我在我的ASPX模型页面的代码隐藏中做了这个。

    这将创建一个很好的JSON对象。你会注意到我甚至可以重构我的模型,页面仍然可以工作。它只是数据模型和页面之间的另一个抽象层。我不认为我的控制器应该尽可能多地了解JSON,但是ASPX的“代码隐藏”当然可以。

    /// <summary>
    /// Get JSON for testimonials
    /// </summary>
    public string TestimonialsJSON
    {
        get
        {
            return Model.Testimonials.Select(
                x => new
                {
                    testimonial = x.TestimonialText,
                    name = x.name
                }
                ).ToJSON();
        }
    }
    

    在我的ASPX中,我只是在一个块中执行此操作:

    var testimonials = <%= TestimonialsJSON %>;
    
    // oh and ToJSON() is an extension method
    public static class ObjectExtensions
    {
        public static string ToJSON(this Object obj)
        {
            return new JavaScriptSerializer().Serialize(obj);
        }
    }
    

    我准备好面对反对这个建议的强烈反对…带上它…

    我没有访问数据,只是重新格式化视图的模型。这是“视图模型”逻辑,而不是“控制器模型”逻辑。

        3
  •  2
  •   Dmytrii Nagirniak    17 年前

    我建议使用 JSON.NET . 它允许序列化循环引用并提供更多的序列化选项。

        4
  •  2
  •   Wyatt Barnett    17 年前

    西蒙说的。加一点 AutoMapper 控制代码权重的操作。

        5
  •  1
  •   ShadowChaser    14 年前

    我找到的最干净的方法是对类使用[datacontract]和对要序列化的属性使用[datamember]的组合。datacontract属性告诉各个序列化程序忽略没有datamember属性的任何属性。

    与使用scriptIgnoreAttribute相比,有两个主要好处。首先,它不依赖System.Web.Extensions程序集。其次,它与其他类型的序列化一起工作,而不仅仅是JSON。例如,如果您在MVC4中使用新的Web API,那么DataContract/DataMember方法也将与XML序列化程序一起工作。

    考虑这样一个场景:您的实体存储在一个共享库中,并在不同的项目中重用——您不希望依赖于System.Web.Extensions,您希望松散地描述序列化规则——而不是特定于JSON、XML等的硬编码行为。