Mvc 4 JsonResult不返回任何东西



我在Items控制器上设置了这个操作

[HttpGet]
public JsonResult Search(string data, int id)
{
    var date = DateTime.Now;
    if(!string.IsNullOrEmpty(data))
        date = DateTime.Parse(data);
    var result = Repository.FindBy(date, id); // (1)
    return Json(result, JsonRequestBehavior.AllowGet);
}

我用jQuery调用它

function successHandler(success){
    console.log(success); // (2)
    return success;
}
function errorHandler(error){
    console.error(error); // (3)
    return error;
}
$.ajax({
    type: 'GET',
    contentType: 'application/json',
    url: '/Items/Date/2015-01-01/Id/2',
}).then(successHandler, errorHandler);

如果我在(1)中设置一个断点,并启动jQuery ajax调用,调试器就会碰到断点,我可以看到result是一个有效的IEnumerable<Item>,并且Action返回。

如果我在(2)中设置了一个断点,它永远不会被击中,并且在(3)中error的值是

{ readyState: 4,
  responseText: "",
  status: 200,
  statusText: "OK" }

这不是错误。

如果我直接调用URL (http://localhost:26252/Items/Search/2015-01-01/Id/2),我得到一个空页面,并且使用Firebug的控制台,得到相同的响应。

怎么回事?

编辑:

这个动作的自定义路由是

routes.MapRoute(
    name: "Items",
    url: "Items/Date/{date}/Id/{id}",
    defaults: new { controller = "Items", action = "Search" }
);

,默认为

routes.MapRoute(
    name: "Default",
    url: "{controller}/{action}/{id}",
    defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);

只要结果变量值是有效的对象/集合,您的代码就可以正常工作。如果您的ajax调用从服务器接收到null响应,则它将转到错误回调,其中它期望json数据结构作为响应。由于jQuery无法将null值转换为有效的json,因此您会得到此错误。

确保您的操作方法不返回null值。如果它返回一个集合,当没有数据时,您应该返回一个空集合,我个人倾向于将响应包装在另一个包装器响应中来处理这种情况。

var result = Repository.FindBy(date, id);    
return Json(new { status="success", data=result } , JsonRequestBehavior.AllowGet);

返回如下JSON结构

{
  "status":"success",
  "data": null // or a valid object/array here
}

现在在您的成功处理程序中,您可以在null检查之后访问data属性。

successHandler = function (response) {
       if(response.status==="success")
       { 
          if(response.data!=null)
          {
            console.log(success);
            return success;
          }
          else
          {
            console.log('data is null. may be no data for your filter');
          }
       }
};

另外,您可以考虑为您的参数使用DateTime?类型,而不是在string中读取值并再次解析它。

相关内容

最新更新