如何创建一个ActionController以在运行时和使用ajax工作

时间:2013-05-23 14:50:02

标签: c# asp.net-mvc json asp.net-mvc-4 razor

我有一个AddressBook控制器,它将返回“文件夹”列表(基本上是组/位置)。这可以通过AJAX请求调用,也可以在渲染时通过MVC页面调用。

如何创建一个适用于这两种情况的功能?这是我当前的Controller动作,我似乎很难在我的MVC页面中使用

public ActionResult GetFolderList(int? parent)
{
    List<String> folderList = new List<String>();
    folderList.Add("East Midlands");
    folderList.Add("West Midlands");
    folderList.Add("South West");
    folderList.Add("North East");
    folderList.Add("North West");

    return Json(folderList);
}

在页面内(不在atm工作)

@{
    var controller = new My.Controllers.AddressBookController();
    var what = controller.GetFolderList(0);

    foreach(var p in what){
        //i want to get the list items here
    }
}

4 个答案:

答案 0 :(得分:9)

只需要一个返回List的函数,然后在页面加载和AJAX请求操作方法中调用它。

类似的东西:

public List<string> GetFolderList()
{
    List<String> folderList = new List<String>();
    folderList.Add("East Midlands");
    folderList.Add("West Midlands");
    folderList.Add("South West");
    folderList.Add("North East");
    folderList.Add("North West");

    return folderList;
}

然后在页面加载时,您可以将其粘贴在您的模型中:

public ActionResult Index()
{
    var model = new YourViewModel(); //whatever type the model is

    model.FolderList = GetFolderList(); //have a List<string> called FolderList on your model

    return View(model); //send model to your view
}

然后在您看来,您可以这样做:

@model YourViewModel

@{
    foreach(var item in Model.FolderList){
        //do whatever you want
    }
}

然后,假设您的ajax请求类似于:

$.ajax({
    url: '@Url.Action("GetFolders", "ControllerName")',
    type: 'POST',
    datatype: 'json',
    success: function (result) {
        for (var i = 0; i < result.length; i++)
        {
            //do whatever with result[i]
        }
    }
});

您的GetFolders操作方法如下:

public ActionResult GetFolders()
{
    return Json(GetFolderList());
}

答案 1 :(得分:5)

这将有效:

public ActionResult GetFolderList(int? parent)
{
    List<String> folderList = new List<String>();
    folderList.Add("East Midlands");
    folderList.Add("West Midlands");
    folderList.Add("South West");
    folderList.Add("North East");
    folderList.Add("North West");

    if(Request.IsAjaxRequest())
    {
        return Json(folderList);
    }

    return View("someView", folderList );

}

答案 2 :(得分:2)

首先,你不应该在你的观点中做这样的事情:

var controller = new My.Controllers.AddressBookController();
var what = controller.GetFolderList(0);

这会在您的视图和控制器之间产生紧密耦合,这几乎违反了MVC的原则。现在,回答你的问题。

正如mattytomo所提到的,您将需要使用强类型视图并从视图模型中获取列表。像下面这样的东西适用于简单的情况。如果此视图变得更复杂,则需要实际的视图模型对象:

@model List<string>

@{
  foreach (var p in Model)
  {
      p;
  }
}

现在,你可以使用一个控制器方法用于AJAX或普通请求,以及使用Request.IsAjaxRequest,正如Maris指出的那样。假设您的视图名为“FolderList”,控制器操作将如下所示:

    public ActionResult GetFolderList(int? parent)
    {
        List<String> folderList = new List<String>();
        folderList.Add("East Midlands");
        folderList.Add("West Midlands");
        folderList.Add("South West");
        folderList.Add("North East");
        folderList.Add("North West");

        if (Request.IsAjaxRequest())
        {
            return Json(folderList);
        }

        return View("FolderList", folderList);
    }

现在,当您通过AJAX调用此方法时,它将返回folderList的JSON表示,否则它将返回您的FolderList视图。

答案 3 :(得分:0)

我曾经写过ActionFilter就是这样做的,一旦ActionResult http标头包含JsonResult,它会覆盖Accept json(并且可以通过onAjaxOnly传递true来限制自己仅限于Ajax请求:

public class ReturnJsonIfAcceptedAttribute : ActionFilterAttribute
{
    private bool _onAjaxOnly;
    private bool _allowJsonOnGet;

    public ReturnJsonIfAcceptedAttribute(bool onAjaxOnly = true, bool allowJsonOnGet = false)
    {
        _onAjaxOnly = onAjaxOnly;
        _allowJsonOnGet = allowJsonOnGet;
    }

    public override void OnResultExecuting(ResultExecutingContext filterContext)
    {
        var request = filterContext.HttpContext.Request;

        if (!_allowJsonOnGet && request.HttpMethod.ToUpper() == "GET")
            return;

        var isAjax = !_onAjaxOnly || request.IsAjaxRequest();

        if (isAjax && request.AcceptTypes.Contains("json", StringComparer.OrdinalIgnoreCase))
        {
            var viewResult = filterContext.Result as ViewResult;

            if (viewResult == null)
                return;

            var jsonResult = new JsonResult();
            jsonResult.Data = viewResult.Model;

            filterContext.Result = jsonResult;
        }
    }

然后你保持Action的方式,你只需追加新的ReturnJsonIfAccepted Attribute

[ReturnJsonIfAccepted]
public ActionResult Index()
{
    var model = new Model(); // whatever
    return View(model);
}