【问题标题】:Better way to retrieve json from an MVC3 Controller Action?从 MVC3 控制器操作中检索 json 的更好方法?
【发布时间】:2011-09-12 08:24:45
【问题描述】:

我对 MVC3 还很陌生,我已经开始着手处理一个新的 jQuery / MVC3 / EF 4.1 代码优先项目,并且已经检查了一些现有代码。当某个下拉列表的值发生变化时(SubtypeID.change 事件),其中一部分代码通过控制器操作从数据库中检索值。这是 jQuery:

    $.getJSON(
    "/StudyDesign/GetSubtypes?typeId=" + typeId,
    function (data) {
        var theDropDown = document.getElementById("SubtypeID");

        if (data.length === 0) {
            theDropDown.disabled = true;
        }

        $.each(data, function () {
            $("#SubtypeID").append($('<option>').attr('value', this.SubtypeID).text(this.Name));
        });
    }
);

这是控制器动作:

    [OutputCache(Duration = int.MaxValue, VaryByParam = "typeId", Location = OutputCacheLocation.Server)]
    public JsonResult GetSubtypes(int typeId)
    {
        var studyType = this._studyDesignRepository.StudyTypes.SingleOrDefault(s => s.StudyTypeID == typeId);
        return studyType == null ? this.Json(new List<Subtype>()) : this.Json(studyType.Subtypes.Select(s => new { s.SubtypeID, s.Name }).ToList(), JsonRequestBehavior.AllowGet);
    }

这很好用,但是在我们的 Controller 构造函数中,我们有很多代码可以从填充其他下拉列表和网格等的 db 中检索不同的值。第一次加载页面后,我们不需要获取这些值再次出现,因为它们已经在页面中,但是每次触发 .change 事件并调用 StudyDesign/GetSubtypes 时,Controller 构造函数都会运行并再次执行所有 db 调用。这似乎没有必要,所以我想知道

  • 有没有更好的方法来做到这一点?
  • 我们可以/应该以不同的方式检索 json 数据吗?
  • 我们是否应该将 json 操作/方法放在单独的控制器中?

提前致谢:)

【问题讨论】:

    标签: json asp.net-mvc-3


    【解决方案1】:

    一般来说,在你的控制器构造函数中做一堆这样的初始化是一个非常糟糕的主意。对于初学者来说,不能保证这些数据在每次调用中都会存在,因为应用程序的无状态特性可能会导致控制器在调用之间被破坏。这意味着要始终预先完成所有昂贵的工作。

    你应该在你的 Action 方法中做那些昂贵的工作,使用你正在使用的缓存,这些方法在缓存超时之前不会被再次调用。

    重新阅读时,听起来您在谈论其他数据,这些数据填充在页面上,但由于您正在执行 Ajax 调用而从未更改。在那种情况下,我的观点仍然成立。在页面的操作方法中执行此操作,而不是在构造函数中。那么它只会在您实际检索页面时加载该数据。

    【讨论】:

    • 嗨@Mystere - 没错,当调用json Action 时,Controller 构造函数仍会再次检索并填充所有页面数据。我只是在寻找更好的设计来尝试和改进。
    • 所以当你说“在你的 Action 方法中做那些昂贵的工作”时,我认为你的意思是将所有昂贵的工作提取到另一个方法中并在需要的地方调用它,而不是总是在构造函数?这听起来很有道理。
    • @Ciaran Bruen - 这是一种方法,另一种方法是将其变成某种类型的服务(如果您在多个控制器中需要该数据,则很有用)。或者,如果代码足够小,并且只在一个地方使用,而不是在您的操作方法本身中使用。
    【解决方案2】:

    检索数据时有几种不同的思维方式。这里有两个(我用的一个):

    一个:让控制器上的每个操作只检索他们需要的数据。他们都可以共享一个模型,并填充他们将在模型中使用的内容。此外,您可以创建私有方法来填充传入模型的特定部分,这样您就不会拥有多行相同的代码。 private void PopulateColors(Model ModelWithColors).

    两个(我使用的):让模型自己填充它们。例如,您可能将颜色列表作为IEnumerable&lt;string&gt; 作为get 属性,但是当模型被传递到视图或由JSON(model.Colors) 序列化时,才会调用数据库。模型的初始化值(可能包括连接字符串或其他任何需要的内容,也可以在模型的构造函数中或传递给工厂方法)。

    【讨论】:

    • 我认为没有理由在您的 PopulateColors 方法中使用 out 参数。您的方法可以返回 Model 的实例,或填充已传递的现有实例(这不需要 out)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-05
    相关资源
    最近更新 更多