我应该如何设计MVC以有条件地返回JSON或漂亮的HTML?

时间:2013-11-26 17:04:36

标签: asp.net-mvc json rest asp.net-mvc-4

我的数据将由人工或网络服务使用。 REST网址是:

 http://host.com/movies/detail/1
 http://host.com/movies/detail/The Shawshank Redemption (1994)

我应遵循哪些约定来有条件地返回JSON或HTML?我应该添加一个参数,如“?json”,还是应该查看客户端标题,两者的一些变化?

如果我对两者进行了修改,是否发现了先例冲突?

3 个答案:

答案 0 :(得分:3)

检查请求是否为Ajax。您可以使用Request.IsAjaxRequest()方法返回true / false

public ActionResult details(string id)
{
  var movieViewModel=movieService.GetMovieDetails(id);
  If(Request.IsAjaxRequest())
  {
    // return Json now
    return Json(movieViewModel,JsonRequestBehavior.AllowGet);
  }
  // Not an ajax request, Let's return Normal View (HTML)
  return View(movieViewModel);
}

UNIT TESTING ASPECT Request.IsAjaxRequest()不是单元测试友好的!因此,如果您担心单元测试,可以编写IsAjaxRequest属性并放入basecontroller类并使用它。

public class BaseController : Controller
{
    protected bool IsAjaxRequest()
    {
        //Using this method instead of Request.IsAjaxRequest() because
       //IsAjaxRequest is static and not mockable ! (not unit test friendly)

        var isAjax = Request.Headers["X-Requested-With"];
        if (isAjax != null && isAjax.ToUpper() == "XMLHTTPREQUEST")
            return true;
        return false;
    }
}

现在从此BaseController继承您的控制器。

public class HomeController : BaseController
{
    public ActionResult details(string id)
    {
      var movieViewModel=movieService.GetMovieDetails(id);
      If(IsAjaxRequest)
      {
        // return Json now
        return Json(movieViewModel,JsonRequestBehavior.AllowGet);
      }
      // Not an ajax request, Let's return Normal View (HTML)
      return View(movieViewModel);
    }

}

答案 1 :(得分:0)

我更喜欢在URL中使用显式参数,因为构建REST请求的方式对于开发人员来说很容易,自我解释并且没有任何意外(您是否必须猜测默认格式?或者看到“难以”看到HTTP标头)。你决定:

  • 如果您有多种格式选项,可以使用format = json
  • 你可以使用json参数,但它不漂亮,因为你必须将它与值json = true,json = 1配对。此外,你可以设置json = 1& xml = 1& html = 1,更难处理。
  • twitter方式是模拟一个扩展名,例如call.json或call.xml(例如https://dev.twitter.com/docs/api/1.1/get/statuses/user_timeline

我建议不要将一种请愿和格式捆绑在一起。让你的API客户决定,ajax-json是常用的,但不是所有的develepers都这样使用它。也许我正在编写一个没有ajax的终端应用程序,也许我想为你的API做一个wget并仍然得到json。

答案 2 :(得分:0)

你也可以使用:

[HttpGet]
public ActionResult() {
    // Return HTML
}


[HttpPost]
public ActionResult() {
  // Assuming Ajax is of the type post
}

如果您的所有Ajax都使用post,那么只是另一种解决方案。