2013-05-23 1 views
8

"폴더"(기본적으로 그룹/위치) 목록을 반환하는 AddressBook 컨트롤러가 있습니다. 이것은 AJAX 요청을 통해 또는 렌더링시 MVC 페이지 자체 내에서 호출 될 수 있습니다.런타임과 아약스 모두에서 작동하도록 ActionController를 만드는 방법

두 시나리오에서 모두 잘 작동하는 함수를 만들려면 어떻게해야합니까? 그냥

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

} 

답변

9

: 여기에 내 현재 컨트롤러 I 페이지 내에서 내 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); 
} 

내 (작동하지 기압)

@{ 
    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

클라이언트에서 POST 호출을 할 때'[HttpPost]'속성을 사용하여 액션 메소드를 꾸미는 것을 잊지 마십시오. – Shyju

+0

@Shyju 모든 동사를 받아 들일 수있는 방법으로 꾸미지 마십시오. :) – mattytommo

+1

분명히 GET해야하는 메소드를 얻으려면 POST해야하는 이유는 무엇입니까? (심지어 이름이 나옵니다!) – Joshua

5

사용하여 투쟁하는 것 행동이 작동이다 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({ 
    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()); 
} 
2

첫째, 당신은보기에이 같은 일을해서는 안 :이보기 사이 꽉 커플 링을 만들어

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

컨트롤러, MVC의 원칙을 거의 위반합니다. 이제 귀하의 질문에 답변 해주십시오.

mattytomo가 암시했듯이 강력한 형식의보기를 사용하고보기 모델에서 목록을 가져와야합니다. 아래의 내용은 간단한 경우에 적용됩니다. 당신은 하나의 컨트롤러 AJAX에 대한 방법 또는 마리스는 지적 Request.IsAjaxRequest를 사용하여 함께 정상적인 요청을 사용할 수 있습니다, 지금

@model List<string> 

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

:이보기가 더 복잡를 얻을 경우, 당신은 실제 뷰 모델 객체가 필요합니다.

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

을 이제 당신이 당신의 FolderList보기를 반환 현명한 기타는 folderList의 JSON 표현을 반환합니다 AJAX를 통해이 메소드를 호출 할 때 : 가정보기는 컨트롤러 액션이 같을 것이다 "FolderList"라는 .

내가 한 번 단지를 않는 ActionFilter를 작성했습니다
0

, 그것은 (trueonAjaxOnly를 전달하여, 단지 Ajax 요청에 자신을 제한 할 수 있습니다)에 Accept HTTP 헤더가 json를 포함하면 JsonResultActionResult 오버라이드 (override) :

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

그런 다음 당신은 단지 새로운 ReturnJsonIfAcceptedAttribute 추가, 당신의 Action 그것이 방식을 유지 :

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