2011-02-23 22 views
99

tengo un controlador MVC que tiene esta Acción Método:¿Cómo recuperar valores de formulario de HTTPPOST, diccionario o?

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

la forma es una forma no trivial con un simple cuadro de texto.

Pregunta

¿Cómo puedo acceder a los valores de los parámetros?

No estoy escribiendo desde una vista, el puesto está llegando externamente. Supongo que hay una colección de pares clave/valor a los que tengo acceso.

me trataron Request.Params.Get("simpleTextBox"); pero devuelve el error "Se ha producido un error al procesar su solicitud.".

Respuesta

125

Usted podría tener su acción del controlador tomar un objeto que refleje los nombres de entrada de formulario y el ligante modelo por defecto se creará automáticamente este objeto para usted:

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

    ... return something ... 
} 

Otra forma (obviamente más feo) es:

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

    ... return something ... 
} 
+4

me gustaría señalar que se pierde la copia de seguridad del compilador en opción 2. Si el modelo cambia, el compilador no detectará el cambio en los controladores relacionados. Hay buenos casos para la opción 2 pero no recomendaría un uso amplio. –

+0

A veces se necesitan cosas feas, es bueno tener una opción cuando usted ya sabe lo que son las mejores prácticas –

+0

Como alguien todavía está aprendiendo punto net, ¿por qué es la segunda forma más feo? – Goose

94

Simplemente, se puede utilizar como FormCollection:

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

También puede utilizar una clase, que se correlaciona con los valores de la forma, y ​​el motor de asp.net mvc automágicamente lo llena:

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

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

Me gustó la solución de clase es fácil y simple –

29

Las respuestas son muy buenos, pero hay otra manera en la última versión de MVC y. NET que realmente me gusta usar, en lugar de las claves FormCollection y Request de "old school".


Considere un fragmento de HTML contenido en una etiqueta de formulario que hace AJAX o FORMATO.

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

Su controlador realidad analizará los datos del formulario y tratar de entregar a usted como parámetros del tipo definido. Incluí la casilla de verificación porque es complicada. Devuelve el texto "on" si está marcado y nulo si no está marcado. El requisito es que aunque existe especifican estas variables definidas (a no ser anulable (recuerda sin embargo que string es anulable)) de lo contrario el AJAX o POST volver fallarán.

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

También puede enviar de vuelta un modelo sin el uso de ayudantes de afeitar. Me he encontrado con que esto es necesario algunas veces.

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

El marcado HTML será simplemente ...

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

y su controlador (Razor Motor) interceptará la variable de formulario "MyHome" y tratar de construir hacia arriba y echarlo a MyModel.

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

Cuando un controlador está esperando un modelo que no tiene que definir todos los campos como el analizador dejarlos en el defecto, por lo general NULL. Lo bueno es que puede mezclar y combinar varios modelos en el marcado y el análisis posterior de la publicación poblará tanto como sea posible. No necesita definir un modelo en la página o usar ayudantes.

TIP: El nombre del parámetro en el controlador es el nombre definido en el marcado HTML "name =" no es el nombre del modelo!


Usando List<> es poco más complejo en su margen de beneficio.

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

Índice de la Lista <> deberá ser siempre cero en base y secuencial. 0,1,2,3.

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

Usando IEnumerable<> para que no sea cero y los índices basados ​​no secuenciales segundo palo. Necesitamos agregar una entrada oculta adicional para ayudar a la carpeta.

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

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

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

Y el código sólo tiene que utilizar IEnumerable y llame ToList()

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

Se recomienda utilizar un único modelo o un modelo de vista (Modelo contianing otros modelos para crear un complejo 'Vista 'Modelo) por página. Mezclar y combinar según lo propuesto podría considerarse una mala práctica, pero mientras funcione y sea legible no es MALO. Sin embargo, demuestra la potencia y la flexibilidad del motor Razor.

Así que si necesita colocar algo arbitrario o anular otro valor de un Razor helper, o simplemente no tiene ganas de hacer sus propios ayudantes, para un formulario único que utiliza una combinación inusual de datos, puede usar estos rápidamente métodos para aceptar datos adicionales.

+2

fin alguien lo explicó claramente –

+0

utilizando la opción de índice es oscura. ¿Quién en la tierra verde de Dios hubiera sabido usar eso o que incluso existiera? Pero, me alegro de haber encontrado esta publicación. Va a ahorrar una gran cantidad de tráfico de red. –

+1

Esto funcionó para mí, pero solo después de que cambié a @ Html.Hidden ("myId") – radkan

8

Si desea obtener los datos del formulario directamente de petición HTTP, sin ningún tipo de ataduras modelo o FormCollection puede utilizar esto:

[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]); 
} 
+1

Tenga en cuenta que esto puede ser de mala calidad (sin juego de palabras) pero a veces solo quiere los valores de forma y no puede cambiar limpiamente la firma de la función. Esta es la única solución que se adapta a mi situación particular. – Ryan

+0

¿Cómo probar este método con las referencias estáticas? FormCollection sería mucho más deseable cuando se trata de pruebas. –

+0

@KeesdeWit si lee el comentario anterior esta no es la mejor manera, pero a veces se usa como una solución alternativa. Para la prueba unitaria, probablemente pueda burlarse de la 'Solicitud' e inyectarla al método. –

Cuestiones relacionadas