2013-05-23 9 views
8

"フォルダ"(基本的にグループ/場所)のリストを返すAddressBookコントローラがあります。これは、レンダリング時にAJAXリクエストまたはMVCページ内で呼び出すことができます。実行時とajaxの両方で動作するActionControllerの作成方法

両方のシナリオでうまく機能する関数を作成するにはどうすればよいですか?ここで私は(気圧動作していない)ページ内で私の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 
    } 
} 

答えて

9

だけListを返す関数があり、ページロードとAJAXリクエストの両方のアクションメソッドで呼び出します。その後

@model YourViewModel 

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

ような何か:次に、ページのロード時に、あなたがあなたのモデルであることを固執することができます

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 
} 

次に、あなたが行うことができますあなたのビューであなたの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()); 
} 
+0

クライアントからPOST呼び出しを行うときに '[HttpPost]'属性でアクションメソッドを飾るのを忘れないでください。 – Shyju

+0

@ Shyjuそれはすべての動詞を受け入れることを意味してそれを飾っていない:) – mattytommo

+1

あなたはなぜ明らかにGETする必要があるメソッドを取得するPOSTですか? (それはそれにも名前が入ります!) – Joshua

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

まず、あなたはあなたのビューでこのような何かを行うことはありません:これはあなたのビューとの間で緊密な結合を作成

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

コントローラは、MVCの原則にかなり違反しています。今、あなたの質問に答える。

mattytomoが指摘したように、強く型付けされたビューを使用し、ビューモデルからリストを取得したいと思うでしょう。以下のようなものは、単純なケースではうまくいくでしょう。あなたは1つのコントローラAJAXのための方法またはマリスが指摘したようにRequest.IsAjaxRequestを使用して一緒に通常の要求を使用することができ、今

@model List<string> 

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

:このビューは、より複雑なを取得した場合、あなたは、実際のビューモデルオブジェクトが必要になります。あなたのビューが「のFolderList」と命名されたと仮定すると、コントローラのアクションは、次のようになります。あなたがAJAX経由でこのメソッドを呼び出すとき

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のJSON表現を返します、他の賢明な、それはあなたのFolderListビューを返します。 。

0

私は一度だけそれを行うActionFilterを書かAccept HTTPヘッダがjsonが含まれている(とtrueonAjaxOnlyを渡すことによって、唯一のAjaxリクエストに自分自身を制限する可能性)と、それはJsonResultActionResultを上書きしています

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); 
} 
関連する問題