ASP.NET MVC:AJAX调用的控制器是应该返回JSON还是渲染html?

And*_*NET 22 asp.net-mvc json

我无法确定AJAX调用的控制器操作是应该返回部分视图还是"原始"JSON.

返回部分视图,使用呈现的HTML使javascript更容易使用返回的HTML更新当前DOM.但是,它确实限制了使用Web服务的javascript客户端可以对返回的HTML执行的操作.

另一方面,让控制器操作返回JSON将需要javascript调用"手动"基于返回的JSON创建标记.

像往常一样,每种方法都有它的好处和缺点.每种方法都有其他优点/缺点吗?

Pra*_*yan 18

在我看来,返回JSON然后让客户端视图排序可能会因为以下限制而变得混乱:

  1. 没有JavaScript的标准模板语言.在最糟糕的情况下,您会想要连接字符串以形成您需要的HTML.
  2. 没有简单的方法来对您的连接代码生成的HTML进行单元测试.
  3. 您的JavaScript缺乏智能感知意味着您也容易犯更多错误.

我处理这个的方法是返回渲染的HTML,但是使用局部视图返回这个呈现的HTML.这为您提供了两全其美的体验.您已获得服务器端模板以及IntelliSense支持.

这是一个例子:

这是我的Ajax调用,因为你可以看到它所做的就是替换我的无序列表的html:

FilterRequests: function() {
    $.post("/Request.aspx/GetFilteredRequests", { }, function(data) {
        $('ul.requests').html(data);
    });
},
Run Code Online (Sandbox Code Playgroud)

这是我在我的控制器上的动作:

public ActionResult GetFilteredRequests(string filterJson)
{
    var requests = _requestDao.LoadAll();

    return PartialView("FilteredRequests", requests);
}
Run Code Online (Sandbox Code Playgroud)

最后,这是我的部分视图(没有必要理解这一点,我只是向您展示一些渲染在真实世界的应用程序中会有多复杂.我很害怕在JavaScript中执行此操作.您还会注意到我的局部视图反过来调用其他部分视图.):

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<IEnumerable<Request>>" %>
<%@ Import Namespace="Diangy.HelpDesk.Models.Lookups"%>
<%@ Import Namespace="Diangy.HelpDesk.Models.Requests"%>
<%@ Import Namespace="System.Web.Mvc.Html"%>

<% foreach (var request in ViewData.Model) %>
<%{%>
    <li class="request">
        <h2>#<%= request.Id %>: <%= request.InitialInteraction().Description %></h2>
        <p>from <%= request.Customer.FullName %> (<%= request.Customer.EmailAddress %>), <%= request.InitialInteraction().UsableTimeStamp %></p>

        <h3>Custom Fields & Lookups</h3>
        <div class="tabs">
            <ul>
            <li><a href="#customfields<%= request.Id %>">Custom Fields</a></li>
            <% foreach (var lookupDefinition in (List<LookupDefinition>)ViewData["LookupDefinitions"]) %>
            <%{%>
            <li><a href="#<%= lookupDefinition.Name.ToLowerInvariant().Replace(" ", "") + request.Id %>"><%= lookupDefinition.Name %></a></li>
            <%}%>
        </ul>
        <% Html.RenderPartial("CustomFields", request); %>
    </div>

    <% Html.RenderPartial("Discussion", request); %>
    <% Html.RenderPartial("Attachment", request); %>
    </li>
<%}%>
Run Code Online (Sandbox Code Playgroud)

  • @hrvoje通过该逻辑,我们应该让所有控制器操作只返回视图的数据.查看引擎在那个世界中毫无用处.我认为Praveen说当你更新超过1个DOM元素时,返回由视图引擎呈现的html是理想的.这种方法与在您的操作中调用"View(...)"完全相同 - "ParitialView()"呈现html片段,"View()"呈现html文档.除非你想放弃视图引擎的概念,否则我不确定你如何强烈反对. (7认同)

Den*_*ler 16

如果您正在使用MVC范例,控制器应该返回数据(JSON)并让视图为自己排序,就像它的工作是查找/调整模型中的数据并将其传递给服务器上的视图侧.

你得到了褐色点

  • 保持逻辑和UI之间的关注点分离

  • 使你的ajax动作可测试(祝你好运测试从该动作返回的HTML ......)

它可能有点复杂,但它很合适.

您可以使用客户端模板系统(例如MS Ajax Toolkit中现有的系统)来帮助承担一些负载并在客户端保留逻辑/呈现分离.

所以我肯定会说JSON.但是,嘿,YMMV像往常一样......