ASP.NET MVC 4 - 以 HTML、JSON 或 XML 响应的正确方法

Posted

技术标签:

【中文标题】ASP.NET MVC 4 - 以 HTML、JSON 或 XML 响应的正确方法【英文标题】:ASP.NET MVC 4 - Proper way to respond in HTML, JSON, or XML 【发布时间】:2013-06-16 04:07:54 【问题描述】:

让我的 Index() 方法根据传入的接受/内容类型标头返回内容的正确方法是什么。

我目前有一个我正在尝试重构的应用程序,它有一个 Index() 方法和一个 JsonData() 方法。浏览器拉出这个“索引”页面,然后通过 Ajax 请求 /jsondata URL。我想将两者都放在 Index() 下,并根据传入的请求更改响应类型。在 MVC 4 下执行此操作的正确方法是什么?

注意:我们没有使用 Web API。

【问题讨论】:

我不建议这样做 - 您将两个完全不同的概念(返回页面或返回数据)组合到同一个名称中 - 它只会产生混淆。我会按照你的方式保留它 - 让 Index 响应 GET 请求并返回视图,并让 JsonData 响应 POST 请求并返回数据 - 没有理由将它们组合起来。 Rails 一直这样做。就 REST 而言,html 表示与 JSON 或 XML 有何不同。 ***.com/questions/3672111/… 只是我的看法——你说得对,HTML 在技术上只是数据。我只是发现尽可能将 UI 与数据分开对我来说更有意义。 【参考方案1】:

这里有几个选项。

首先 - 通过动词来区分您的请求,并有一个约定,例如所有 GETs 接收 html,而所有 POSTs 接收 json。控制器将如下所示:

[HttpGet]
[ActionName("Index")]
public ActionResult IndexGet()

    return View();



[HttpPost]
[ActionName("Index")]
public ActionResult IndexPost()

    return Json();

当然,使用正确的方法发出请求是客户端的问题。 更新 - 仅动词在这里是不够的 - 要保留一个动作名称,您还应该使用 ActionName 属性。感谢Joe Enos 指出这一点。

第二 - 引入一个参数。假设默认情况下您正在发送 html,但如果 ajax 调用附加一个参数 isJson - 给它 json 响应:

public ActionResult Index(bool? isJson)

    if (isJson.HasValue && isJson.Value)
    
        return Json();
    

    return View();

第三 - 通过它们背后的机制区分请求。在您的情况下,似乎所有 ajax 调用,并且只有它们,都应该由 json 提供。然后可以使用Request.IsAjaxRequest() 方法:

public ActionResult Index()

    if (Request.IsAjaxRequest())
    
        return Json();
    

    return View();

当然也可以将这些方法结合起来——比如仅通过 ajax 向 POST 请求发送 json 响应。

【讨论】:

在你的第一个例子中,你有冲突的方法 - 即使你有不同的动词属性,如果你需要两个方法,你仍然需要用参数区分这两个方法。 @JoeEnos,鲁莽的错误,感谢您的评论。但是,使用 ActionName 属性的方法仍然可行。【参考方案2】:

可以尝试通过请求 AcceptTypes 解决此问题吗?

 public ActionResult Index()
        
            if (Request.AcceptTypes.Contains("application/json"))
            
                //
            
            else 
            

            
            return View();
        

【讨论】:

这是一个好点;但是如果客户端无法发送 Accept 标头,则附加参数将允许覆盖 Accept 标头值或允许提供类型。例如,如果您使用 XDomainRequest 执行 ajax 请求...

以上是关于ASP.NET MVC 4 - 以 HTML、JSON 或 XML 响应的正确方法的主要内容,如果未能解决你的问题,请参考以下文章

ASP.NET MVC 4 模型验证

在ASP.NET MVC中,使用Bundle来打包压缩js和css(转)

asp.net mvc + vue.js + axios.js

ASP.NET MVC 4入门

ASP.NET MVC 4 - ListBoxFor,在 ActionLink 中发送 selectedValue

指向脚本标签的 src 属性以从 asp.net mvc 2 中的操作方法下载 js。