How to retrieve form values from HTTPPOST, dictionary or?

asp.netasp.net Mvc-3Http Post

asp.net Problem Overview


I have an MVC controller that has this Action Method:

[HttpPost]
public ActionResult SubmitAction()
{
     // Get Post Params Here
 ... return something ...
}

The form is a non-trivial form with a simple textbox.

Question

How I access the parameter values?

I am not posting from a View, the post is coming externally. I'm assuming there is a collection of key/value pairs I have access to.

I tried Request.Params.Get("simpleTextBox"); but it returns error "Sorry, an error occurred while processing your request.".

asp.net Solutions


Solution 1 - asp.net

You could have your controller action take an object which would reflect the form input names and the default model binder will automatically create this object for you:

[HttpPost]
public ActionResult SubmitAction(SomeModel model)
{
    var value1 = model.SimpleProp1;
    var value2 = model.SimpleProp2;
    var value3 = model.ComplexProp1.SimpleProp1;
    ...

    ... return something ...
}

Another (obviously uglier) way is:

[HttpPost]
public ActionResult SubmitAction()
{
    var value1 = Request["SimpleProp1"];
    var value2 = Request["SimpleProp2"];
    var value3 = Request["ComplexProp1.SimpleProp1"];
    ...

    ... return something ...
}

Solution 2 - asp.net

Simply, you can use FormCollection like:

[HttpPost] 
public ActionResult SubmitAction(FormCollection collection)
{
     // Get Post Params Here
 string var1 = collection["var1"];
}

You can also use a class, that is mapped with Form values, and asp.net mvc engine automagically fills it:

//Defined in another file
class MyForm
{
  public string var1 { get; set; }
}

[HttpPost]
public ActionResult SubmitAction(MyForm form)
{      
  string var1 = form1.Var1;
}

Solution 3 - asp.net

The answers are very good but there is another way in the latest release of MVC and .NET that I really like to use, instead of the "old school" FormCollection and Request keys.


Consider a HTML snippet contained within a form tag that either does an AJAX or FORM POST.

<input type="hidden"   name="TrackingID" 
<input type="text"     name="FirstName"  id="firstnametext" />
<input type="checkbox" name="IsLegal"  value="Do you accept terms and conditions?" />

Your controller will actually parse the form data and try to deliver it to you as parameters of the defined type. I included checkbox because it is a tricky one. It returns text "on" if checked and null if not checked. The requirement though is that these defined variables MUST exists (unless nullable(remember though that string is nullable)) otherwise the AJAX or POST back will fail.

[HttpPost]
public ActionResult PostBack(int TrackingID, string FirstName, string IsLegal){
    MyData.SaveRequest(TrackingID,FirstName, IsLegal == null ? false : true);
}

You can also post back a model without using any razor helpers. I have come across that this is needed some times.

public Class HomeModel
{
  public int HouseNumber { get; set; }
  public string StreetAddress { get; set; }
}

The HTML markup will simply be ...

<input type="text" name="variableName.HouseNumber" id="whateverid" >

and your controller(Razor Engine) will intercept the Form Variable "variableName" (name is as you like but keep it consistent) and try to build it up and cast it to MyModel.

[HttpPost]
public ActionResult PostBack(HomeModel variableName){
    postBack.HouseNumber; //The value user entered
    postBack.StreetAddress; //the default value of NULL.
}

When a controller is expecting a Model (in this case HomeModel) you do not have to define ALL the fields as the parser will just leave them at default, usually NULL. The nice thing is you can mix and match various models on the Mark-up and the post back parse will populate as much as possible. You do not need to define a model on the page or use any helpers.

> TIP: The name of the parameter in the controller is the name defined > in the HTML mark-up "name=" not the name of the Model but the name of the expected variable in the !


Using List<> is bit more complex in its mark-up.

<input type="text" name="variableNameHere[0].HouseNumber" id="id"           value="0">
<input type="text" name="variableNameHere[1].HouseNumber" id="whateverid-x" value="1">
<input type="text" name="variableNameHere[2].HouseNumber"                   value="2">
<input type="text" name="variableNameHere[3].HouseNumber" id="whateverid22" value="3">

Index on List<> MUST always be zero based and sequential. 0,1,2,3.

[HttpPost]
public ActionResult PostBack(List<HomeModel> variableNameHere){
     int counter = MyHomes.Count()
     foreach(var home in MyHomes)
     { ... }
}

Using IEnumerable<> for non zero based and non sequential indices post back. We need to add an extra hidden input to help the binder.

<input type="hidden" name="variableNameHere.Index" value="278">
<input type="text" name="variableNameHere[278].HouseNumber" id="id"      value="3">

<input type="hidden" name="variableNameHere.Index" value="99976">
<input type="text" name="variableNameHere[99976].HouseNumber" id="id3"   value="4">

<input type="hidden" name="variableNameHere.Index" value="777">
<input type="text" name="variableNameHere[777].HouseNumber" id="id23"    value="5">

And the code just needs to use IEnumerable and call ToList()

[HttpPost]
public ActionResult PostBack(IEnumerable<MyModel> variableNameHere){
     int counter = variableNameHere.ToList().Count()
     foreach(var home in variableNameHere)
     { ... }
}

It is recommended to use a single Model or a ViewModel (Model contianing other models to create a complex 'View' Model) per page. Mixing and matching as proposed could be considered bad practice, but as long as it works and is readable its not BAD. It does however, demonstrate the power and flexiblity of the Razor engine.

So if you need to drop in something arbitrary or override another value from a Razor helper, or just do not feel like making your own helpers, for a single form that uses some unusual combination of data, you can quickly use these methods to accept extra data.

Solution 4 - asp.net

If you want to get the form data directly from Http request, without any model bindings or FormCollection you can use this:

[HttpPost] 
public ActionResult SubmitAction() {

    // This will return an string array of all keys in the form.
    // NOTE: you specify the keys in form by the name attributes e.g:
    // <input name="this is the key" value="some value" type="test" />
    var keys = Request.Form.AllKeys;

    // This will return the value for the keys.
    var value1 = Request.Form.Get(keys[0]);
    var value2 = Request.Form.Get(keys[1]);
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionRichardView Question on Stackoverflow
Solution 1 - asp.netDarin DimitrovView Answer on Stackoverflow
Solution 2 - asp.netAdeelView Answer on Stackoverflow
Solution 3 - asp.netPiotr KulaView Answer on Stackoverflow
Solution 4 - asp.netA-SharabianiView Answer on Stackoverflow