Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to create an ActionController to work both at run time and with ajax

I have an AddressBook controller that will return a list of "folders" (basically groups / locations). This may be called via an AJAX request or within a MVC page itself at render time.

How can I create a function that will work well for both scenarios? Here is my current Controller action which I seem to struggle with using within my MVC page

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

Within page (not working 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
    }
}
like image 665
Chris Avatar asked May 23 '13 14:05

Chris


3 Answers

Just have a function that returns the List, then call it in both your page load and AJAX request Action methods.

Something like:

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

Then on page load, you can stick that in your model:

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
}

Then in your view you can do:

@model YourViewModel

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

Then, assuming your ajax request was something like:

$.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]
        }
    }
});

Your GetFolders action method would look like:

public ActionResult GetFolders()
{
    return Json(GetFolderList());
}
like image 156
mattytommo Avatar answered Sep 20 '22 06:09

mattytommo


This will work:

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

}
like image 45
Maris Avatar answered Sep 22 '22 06:09

Maris


First of all, you should never do something like this in your view:

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

This creates tight coupling between your view and the controller, which pretty much violates the principles of MVC. Now, to answer your questions.

As mattytomo alluded to, you will want to use a strongly typed view and get your list from the views model. Something like the below would work for the simple case. If this view gets more complex then you will need an actual view model object:

@model List<string>

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

Now, you can use one controller method for AJAX or a normal request along with using Request.IsAjaxRequest as Maris pointed out. Assuming your view is named "FolderList", the controller action would look like this:

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

Now when you call this method via AJAX it will return the JSON representation of the folderList, other wise it will return your FolderList view.

like image 29
portlandrock Avatar answered Sep 21 '22 06:09

portlandrock