在ASP.NET MVC中检查Ajax请求并返回Json结果的好方法

在ASP.NET MVC中检查Ajax请求并返回Json结果的好方法,ajax,asp.net-mvc,Ajax,Asp.net Mvc,我想让我在控制器中的操作更灵活。我的意思是,共同行动通常会返回: ... return View("someView"); 或者,例如,如果Ajax: ... return Json(new {result="ok"}); 我想要的是让我的行动更“多用途”。例如,我基于简单的非Ajax请求创建了UI层,然后我决定让它更加用户友好,并添加了一些Ajax。这样,我必须纠正一些操作才能返回Json 避免这种情况的最简单(可能也是最糟糕)的方法是在每个(或几乎每个)操作中编写以下代码: 当然,这种方

我想让我在控制器中的操作更灵活。我的意思是,共同行动通常会返回:

...
return View("someView");
或者,例如,如果Ajax:

...
return Json(new {result="ok"});
我想要的是让我的行动更“多用途”。例如,我基于简单的非Ajax请求创建了UI层,然后我决定让它更加用户友好,并添加了一些Ajax。这样,我必须纠正一些操作才能返回Json

避免这种情况的最简单(可能也是最糟糕)的方法是在每个(或几乎每个)操作中编写以下代码:

当然,这种方法完全违背了DRY的原则

因此,我想找到实现“多重姿态”的良好实践

一种方法是编写如下帮助器方法:

public ActionResult CheckForAjax(ActionResult result)
{
  return ActionResult(result, Json(new {result="ok"}));
}

public ActionResult CheckForAjax(ActionResult result, Json json)
{
  if (Request.IsAjaxRequest) {
     return json;
  }
  else {
     return result;
  }
}
这样,我就可以在行动中呼叫助手:

return CheckForAjax(View(...));

但我不知道这是一个好办法还是只是重新发明一些自行车:) 也许使用动作过滤器更好?但我不知道如何将自定义Json传递给该过滤器


感谢您的建议

老实说,我认为您最初的解决方案很好,您的第二个方案比第一个方案更违反了DRY。您的第二个解决方案是非常冗余的,它提供了两种方法来完成一项由一个用户轻松处理的工作

这不仅是糟糕的风格,也是一个可维护性问题。通过将两个函数用于一个目的,您必须在每次发生更改时更新这两个函数。您为什么这样做也不是非常清楚,这将使其他开发人员很难维护您的代码


如果你问我,吻(保持简单愚蠢)比干(不要重复)更重要。如果您的代码易于理解,那么它就是好代码。

如果您从操作返回相同的模型,例如:

var model = new {result="ok"}
if (Request.IsAjaxRequest) {
    return Json(model);
}
else { 
    return View("someView", model) 
}
您可以很容易地编写一个Actionfilter来实现这一点。示例如下:

protected override void OnActionExecuted(ActionExecutedContext filterContext)
    {
        base.OnActionExecuted(filterContext);

        if (filterContext.RequestContext.HttpContext.Request.IsAjaxRequest())
        {
            var res = filterContext.Result as ViewResultBase;
            if (res == null) { return; }


            var jres = new JsonNetResult();
            jres.SerializerSettings.Converters.Add(new IsoDateTimeConverter());
            jres.Data = res.ViewData.Model;
            filterContext.Result = jres;
        }
    }

请注意,此方法意味着您正在从操作返回相同的模型。您是否选择在“正常”请求中使用视图中的结果对象取决于您

您的原始解决方案更好,因为它是显式的。
var model = new {result="ok"}
if (Request.IsAjaxRequest) {
    return Json(model);
}
else { 
    return View("someView", model) 
}
protected override void OnActionExecuted(ActionExecutedContext filterContext)
    {
        base.OnActionExecuted(filterContext);

        if (filterContext.RequestContext.HttpContext.Request.IsAjaxRequest())
        {
            var res = filterContext.Result as ViewResultBase;
            if (res == null) { return; }


            var jres = new JsonNetResult();
            jres.SerializerSettings.Converters.Add(new IsoDateTimeConverter());
            jres.Data = res.ViewData.Model;
            filterContext.Result = jres;
        }
    }