【问题标题】:How do I prevent JSON serialization in ASP.NET MVC?如何防止 ASP.NET MVC 中的 JSON 序列化?
【发布时间】:2010-11-19 03:20:48
【问题描述】:

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

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

谁能建议我如何做到这一点?

【问题讨论】:

  • 你用的是什么序列化器?
  • JsonResult 是我的返回类型,所以我假设 ASP.NET MVC 1.0 的控制器类中默认的序列化程序。
  • 哪个是JavaScriptSerializer。
  • 我遇到了完全相同的问题,除了在 MVC2 中,错误似乎是“超出了 RecursionLimit!”。感谢 Marc,[ScriptIgnore] 完美地解决了它。

标签: asp.net-mvc json


【解决方案1】:

[ScriptIgnore] 应该为你工作。

【讨论】:

  • 这应该可以工作,因为 JsonResult 在内部使用了 JavaScriptSerializer。
  • 其他人请注意:您可能必须添加对 System.Web.Extensions 程序集的引用才能使其可用,至少在 .NET 4 中是这样。
  • System.Web.Script.Serialization.ScriptIgnore
【解决方案2】:

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

例如,对于推荐,我会执行以下操作。我实际上是在我的 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);
    }
}

我已经准备好接受对这个建议的强烈反对......提出来......

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

【讨论】:

  • +1。起初我想提供一些强烈反对“我不想创建多个模型”,但你提到“视图模型”这对我来说开始有些意义:你为业务逻辑制作模型,为什么不为视图制作模型逻辑?杰出的!不是我具体情况的答案,但值得一票。
  • 我也不想创建多个模型!这是最简单的方法,无需创建另一个类(这里没有必要)。模型应该是数据,并且只是数据,而不是数据的显示方式,虽然并不总是实用的,但您应该始终最小化视图和模型之间的耦合,以防视图更改为不同的技术,或者您需要提供多个不同的视图(ajax /flash/纯 html)
  • 我喜欢这种方法,因为您可能需要对同一底层模型进行几个不同的 JSON 序列化。
【解决方案3】:

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

【讨论】:

    【解决方案4】:

    西蒙说了什么。添加一点AutoMapper 操作以控制代码权重。

    【讨论】:

      【解决方案5】:

      我发现的最简洁的方法是在类上使用 [DataContract] 和在要序列化的属性上使用 [DataMember] 的组合。 DataContract 属性告诉各种序列化程序忽略任何没有 DataMember 属性的属性。

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-02-13
        • 1970-01-01
        • 2015-08-29
        相关资源
        最近更新 更多