【问题标题】:Good way of checking for Ajax request and returning Json result in ASP.NET MVC在 ASP.NET MVC 中检查 Ajax 请求并返回 Json 结果的好方法
【发布时间】:2012-03-30 03:03:06
【问题描述】:

我想让控制器中的操作更加灵活。我的意思是 common Action 通常会返回:

...
return View("someView");

或者,例如,如果 Ajax:

...
return Json(new {result="ok"});

我想要的是让我的操作更“多用途”。例如,我基于简单的非 Ajax 请求制作了我的 UI 层,然后我决定让它更加用户友好并添加一些 Ajax。这样我必须纠正一些动作以返回 Json。

避免此类事情的最简单(也可能是最糟糕)的方法是在每个(或几乎每个)Action 中编写以下代码:

if (Request.IsAjaxRequest) {
    return Json(new {result="ok"});
}
else { 
    return View("someView") 
}

当然这样的方法完全违背了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;
  }
}

这样我可以在 Actions 中调用助手:

return CheckForAjax(View(...));

return CheckForAjax(View(...), Json(new {myCustomJson="hi"});

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

感谢您的任何建议

【问题讨论】:

  • 您的原始解决方案更好,因为它是显式

标签: ajax asp.net-mvc


【解决方案1】:

说实话,我认为您的原始解决方案很好,您的第二个比第一个更违反 DRY。您的第二个解决方案非常多余,并提供了两种方法来完成一项容易处理的工作。

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

如果你问我,KISS(保持简单愚蠢)比 DRY(不要重复自己)更重要。如果你的代码很容易理解,那么它就是好代码。

【讨论】:

    【解决方案2】:

    如果你从一个动作中返回相同的模型,那么:

    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;
            }
        }
    

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

    【讨论】:

      猜你喜欢
      • 2015-03-05
      • 2013-05-26
      • 2016-12-04
      • 2018-07-22
      • 2012-02-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-03-16
      相关资源
      最近更新 更多