ASP.NET MVC:API控制器操作同时返回视图和/或JSON是否是良好的实践?

4

我正在编写一个API,将被Web应用程序和移动应用程序使用,并在我的技术栈中使用ASP.NET MVC 2。

目前,我有一个类似于Rest的API服务,返回JSON格式的数据。这对于移动应用程序很有效,但我也希望它能够为Web应用程序工作。

在控制器操作中返回HTML视图或JsonResult是否是一个好方法?Web应用程序和移动应用程序的唯一区别在于视图层;应用程序逻辑相同。

我想我可以创建一个专门用于Web应用程序的控制器,但我认为会从API控制器中复制很多逻辑。

编辑

我有另一个处理所有应用程序逻辑的层,但API控制器仍然具有验证参数和返回JSON响应时的错误处理等一些逻辑。到目前为止,重复的逻辑部分是验证部分。

以下是一些代码片段:

public JsonResult GetList(string accessToken, string listId)
 {
    if (string.IsNullOrEmpty(accessToken))
        return Json(new { success = false, exceptionMessage = "Facebook access token is required." });
    if (string.IsNullOrEmpty(listId))
        return Json(new { success = false, exceptionMessage = "The list id is required." });

    string facebookId = null;
    var facebookIdParseSuccess = GetFacebookId(accessToken, out facebookId);

    if (!facebookIdParseSuccess)
        return Json(new { success = false, exceptionMessage = "There was a problem accessing your Facebook profile information." });

    try
    {
        _groceryListManager.FacebookId = facebookId;
        var groceryList = _groceryListManager.GetList(listId);
        GroceryListViewModel mappedList = new GroceryListViewModel();
        Mapper.Map(groceryList, mappedList);
        return Json(new { success = true, results = mappedList });

    }
    catch (Exception ex)
    {
        return Json(new { success = false, exceptionMessage = "..."});
    }
}
4个回答

2

如果你的视图模型也适合作为JSON返回,那么在同一个操作中执行两个任务是可行的。可以尝试以下代码:

public ActionResult Foo()
{
  FooModel model = new FooModel();

  // Code here to build the model

  if (Request.IsAjaxRequest())
    return Json(model);
  else
    return View(model);
}

这也有助于引导您进入渐进增强的成功之坑。如果HTML和JSON的URL相同,那么在标记中使用可访问/搜索引擎友好的URL,然后通过向JavaScript启用的浏览器添加不显眼的事件处理程序来逐步增强,就更容易将其替换为对JSON的请求。


听起来这是一个不错的方法!IsAjaxRequest的值是否由其中一个post变量决定? - Abe
通过测试半标准设置 X-Requested-With HTTP 头并将值设为 XMLHttpRequest 来确定,这是一些 AJAX 库在其异步请求上自动设置的。这些库包括 MicrosoftAjax.js 和 jQuery,因此大多数使用 ASP.NET MVC 的人都可以使用。如果您使用其他内容或手动滚动请求,则仍然可以手动设置该 HTTP 标头,并且 Request.IsAjaxRequest() 将正确反映它。 - Dave Ward
我需要对此进行功课,但当移动应用程序调用API时,Request.IsAjaxRequest()也必须为true。无论如何,我相信我可以编写程序,使移动应用程序将X-Requested-With设置为XMLHttpRequest。 - Abe

1

我曾经看到过一个操作方法同时返回两个值,但是在我看来,最好还是有两个单独的操作方法。你可以让它们都调用另一个带有共享代码的方法,但由于它们用于两个非常不同的事情,如果你有两个方法,你可能会发现更容易维护(未来的需求可能会导致其中一个以一种使其难以支持单个方法的方式进行更改)。

无论它们是否在同一个控制器中,这实际上更取决于应用程序的性质、大小和复杂性。我已经将API作为完全不同的项目与HTML分开。我共享了用于访问数据和其他常见功能的dll,但MVC项目是不同的。


感谢您的阅读!在审查 API 调用列表后,只有少数需要 Html 视图,我认为为应用程序的网站部分单独创建一个控制器会更简单。我仍然可以通过 AJAX 调用 API 操作,并且 API 控制器还被移动端和可能的 Flash 客户端使用。 - Abe

1

0
但是我认为很多逻辑会从API控制器中复制。 我认为你自己已经回答了这个问题。我会将它们保留在同一个控制器中 :)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接