我有一个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
}
}
答案 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);
}