views:

687

answers:

4

In ASP.net MVC:

How should/Can I pass Form data (From the View) to the Controller?

This is the way I am heading :

  • The Controller Index function is passing a ViewModel object to the View.
  • The ViewModel object contains a paginated list as well as some SelectLists. _ The ViewModel object also contains a custom class I named theFilter. This class' purpose is to hold the Filter information Posted from the View via a Form.
  • I want the Index [AcceptVerbs(HttpVerbs.Post)] function to receive theFilter object populated with the form data, as well as the page number (as is it right now)

Here are snippets of my code:

The Controller/Index postback function:

    [AcceptVerbs(HttpVerbs.Post)]
    public ActionResult Index(int? page, CaseFilter caseFilter)
    {
        const int pageSize = 10;
        var cases = caseRepo.FindAllCases();
        var paginatedCases = new PaginatedList<Case>(cases, page ?? 0, pageSize);
        return View(new CaseIndexViewModel(paginatedCases, caseFilter));
    }

The Filter Class:

public class CaseFilter
{
    int iVolume_id = 0,
        iSubject_id = 0;

    public CaseFilter() {

    }

    public int Volume_id { get { return iVolume_id; } set { iVolume_id = value; } }
    public int Subject_id { get { return iSubject_id; } set { iSubject_id = value; } }

}

And the ViewModel class:

    public class CaseIndexViewModel
    {
    public PaginatedList<Case> PaginatedCases { get; private set; }
    public CaseFilter CaseFilter { get; private set; }

    public CaseIndexViewModel(PaginatedList<Case> paginatedCases, CaseFilter caseFilter)
    {

       PaginatedCases = paginatedCases;
       CaseFilter = caseFilter;
    }
}

Basically I am trying to avoid using Request.Form to populate the Filter class, at least not to use it within the Controller.

Any help, suggestions or disses are welcome!

+1  A: 
[AcceptVerbs(HttpVerbs.Post)]
    public ActionResult Index(FormCollection collection)
    {
         string valueFromNameTextBox = collection["name"];
    }

You can index into this collection with the names of all the inputs on the form.

BFree
A: 

Rather than complicate my method signatures, I've taken to using the ValueProvider property and Try/UpdateModel in the Controller to retrieve form/route values unless the values are simple properties. On the other hand, I would probably also not make the filter part of the model for the View -- I tend to have a narrower conception of the model for the page, wanting it rather to be the business model rather that a model of all the data on the page -- and would simply pass the filter values via ViewData.

tvanfosson
A: 

To expand BFree's answer, you can go through all the elements in the form by doing something like this:

foreach (string key in collection.keys) {
   if (key.contains("blah"))
      text1 = collection[key];
}

If it has too many elements for the key.contains if, it can get a bit ugly though, so beware ;).

Morph
A: 

Finally, I do not need to even use the Request Collection. The CaseFilter object is filled automatically as I set it as a parameter in

public ActionResult Index(int? page, CaseFilter caseFilter)

The code above works as it is.