MVC Razor Entrada oculta y valores de paso

Estoy bastante seguro de que estoy haciendo algo mal aquí. Durante los últimos 2 meses hemos estado desarrollando una aplicación web usando MVC y Razor y nunca pensamos en usar el elemento de formulario. Ya se ha hecho tanto con las páginas maestras y las subpáginas que significa reestructurar la mayor parte de nuestro código para usar el elemento de formulario y daría como resultado múltiples elementos de formulario en una página.

Aparte de eso, en Asp.Net si quisiera acceder a cualquier control en el código C# detrás, podría simplemente darle un ID="SomeID" y un RUNAT="SERVER". Luego, en mi código detrás, podría establecer su valor y propiedades.

Cuando hago esto en Razor, usamos líneas como:

 <input id="hiddenPostBack" runat="server" type="hidden" />

¿Por qué no puedo acceder a esto en el controlador? Quiero detectar una devolución de datos y establecer el valor en falso si es la primera vez que se carga la página, y si no, establecer el valor en verdadero. Luego, en base a esto, lo leeré del lado del servidor o del lado del cliente y haré algo.

Mi verdadera pregunta es, ¿cómo "hago algo" tanto del lado del servidor como del lado del cliente dado que no tengo un elemento de formulario? Tenía la impresión de que si quería pasar valores del cliente al servidor y viceversa, la forma más fácil de hacerlo es con una entrada oculta. Pero simplemente no entiendo cómo lograr esto con MVC3 y razor.

Gracias de antemano por su ayuda.

preguntado el 04 de julio de 12 a las 09:07

No hay una "Devolución de datos" administrada en MVC. Debe usar javascript para administrar acciones en el lado del cliente ... -

5 Respuestas

Un cambio de WebForms a MVC requiere un cambio radical completo en la lógica y los procesos cerebrales. Ya no está interactuando con el 'formulario' tanto del lado del servidor como del lado del cliente (y, de hecho, incluso con WebForms no estaba interactuando con el lado del cliente). Probablemente haya confundido un poco de pensamiento allí, en eso con WebForms y RUNAT="SERVER" simplemente estabas interactuando con el edificio de la página Web.

MVC es algo similar en el sentido de que tiene un código del lado del servidor para construir el modelo (los datos que necesita para construir lo que verá su usuario), pero una vez que haya creado el HTML, debe apreciar que el vínculo entre el servidor y el usuario ya no existe. Tienen una página de HTML, eso es todo.

Así que el HTML que estás construyendo es sólo lectura. Pase el modelo a la página de Razor, que creará HTML apropiado para ese modelo.

Si desea tener un elemento oculto que establezca verdadero o falso dependiendo de si esta es la primera vista o no, necesita un bool en su modelo, y configúrelo en Verdadero en la Acción si es en respuesta a un seguimiento. Esto se puede hacer teniendo diferentes acciones dependiendo de si la solicitud es [HttpGet] o [HttpPost] (si eso es apropiado para la forma en que configura su formulario: una solicitud GET para la primera visita y una solicitud POST si envía un formulario).

Alternativamente, el modelo podría establecerse en True cuando se crea (que será la primera vez que visite la página), pero después de compruebas el valor como Verdadero o Falso (ya que un valor predeterminado es Falso cuando se crea una instancia). Luego usando:

@Html.HiddenFor(x => x.HiddenPostBack)

en su formulario, que pondrá un True oculto. Cuando el formulario se publique de nuevo en su servidor, el modelo ahora tendrá ese valor establecido en True.

Es difícil dar muchos más consejos que eso, ya que su pregunta no es específica en cuanto a el porqué quieres hacer esto. Quizás sea vital que lea un buen libro sobre cómo pasar a MVC desde WebForms, como Pro ASP.NET MVC de Steve Sanderson.

Respondido 01 ago 13, 10:08

Estoy de acuerdo, necesito un buen libro. Sin embargo, estamos en el primer lanzamiento y solo queremos publicar algo lo antes posible, por lo que, como se explicó, reescribir las páginas para usar los formularios correctamente no es práctico en este momento, pero más adelante será definitivo. Lo que ha sugerido es mejor que lo que he visto hasta cierto punto, pero aún adopta el enfoque de un modelo y controlador/resultado de acción para cada control en una página de visualización. Estoy publicando de nuevo usando cuadros combinados desplegables y eventos de clic de casillas de verificación o radios, y el botón ocasional. Pero javascript maneja la redirección. Gracias por tus sugerencias. - francisco rodgers

Sé que esta es una respuesta muy antigua, pero todavía obtengo puntos por ella, por lo que claramente sigue siendo interesante. Solo quería agregar que debe asegurarse de que el configurador para su valor "HiddenPostBack" esté configurado como público; de lo contrario, no lo configurará el enlazador de modelos. Esto me atrapó ayer. Por ejemplo, public bool HiddenPostBack { get; colocar; } - steve owen

Si está utilizando Razor, no puede acceder al campo directamente, pero puede administrar su valor.

La idea es que el primer enfoque de Microsoft aleje a los desarrolladores del desarrollo web y facilite a los programadores de escritorio (por ejemplo) crear aplicaciones web.

Mientras tanto, los desarrolladores web no entendieron esta forma extraña y engañosa de ASP.NET.

En realidad, esta entrada oculta se representa en el lado del cliente y el ASP no tiene acceso a ella (nunca lo tuvo). Sin embargo, con el tiempo verá que es una forma pirata y puede confiar en ella, cuando se acostumbre a ella. El desarrollo web se diferencia del Desktop o Mobile.

El modelo es su unidad lógica y el campo oculto (y toda la página de vista) es solo una vista representativa de los datos. Por lo tanto, puede dedicar su trabajo a la aplicación o la lógica del dominio y la vista simplemente se la ofrece al consumidor, lo que significa que no necesita acceso detallado ni funcionalidad de "lluvia de ideas" en la vista.

El controlador realmente hace el trabajo que necesita para administrar la configuración oculta o general. El modelo sirve propiedades y funcionalidades de unidades lógicas específicas y la vista simplemente se lo presenta al usuario final, simplemente dicho. Leer más sobre MVC.

Modelo

public class MyClassModel
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string MyPropertyForHidden { get; set; }
}

Esta es la acción del controlador.

public ActionResult MyPageView()
{
    MyClassModel model = new MyClassModel(); // Single entity, strongly-typed
    // IList model = new List<MyClassModel>(); // or List, strongly-typed
    // ViewBag.MyHiddenInputValue = "Something to pass"; // ...or using ViewBag

    return View(model);
}

La vista está abajo

//This will make a Model property of the View to be of MyClassModel
@model MyNamespace.Models.MyClassModel // strongly-typed view
// @model IList<MyNamespace.Models.MyClassModel> // list, strongly-typed view

// ... Some Other Code ...

@using(Html.BeginForm()) // Creates <form>
{
    // Renders hidden field for your model property (strongly-typed)
    // The field rendered to server your model property (Address, Phone, etc.)
    Html.HiddenFor(model => Model.MyPropertyForHidden); 

    // For list you may use foreach on Model
    // foreach(var item in Model) or foreach(MyClassModel item in Model)
}

// ... Some Other Code ...

La vista con ViewBag:

// ... Some Other Code ...

@using(Html.BeginForm()) // Creates <form>
{
    Html.Hidden(
        "HiddenName",
        ViewBag.MyHiddenInputValue,
        new { @class = "hiddencss", maxlength = 255 /*, etc... */ }
    );
}

// ... Some Other Code ...

Estamos utilizando Html Helper para representar el campo Oculto o podemos escribirlo a mano: <input name=".." id=".." value="ViewBag.MyHiddenInputValue"> también.

El ViewBag es una especie de soporte de datos para la vista. No te restringe con el modelo, puedes colocar lo que quieras.

Respondido 05 Jul 12, 21:07

Por eso me refiero a los ejemplos de Razor. - Rolice

@Francis no conoce la diferencia entre MVC y Webforms. El motor de vista Razor o ASPX no importa porque podría usar el motor de vista ASPX en MVC y aún enfrentar exactamente el mismo problema. - Fabio Milheiro

Me he encontrado mucho con esta idea. Sin embargo, me resulta difícil creer que sea práctico que deba crear un nuevo modelo y/o resultado de acción del controlador para cada control en mi página de vista. Incluso si fuera posible tener múltiples controladores para una página o resultados de acción para un control en una página (que yo sepa, no lo es, pero estoy abierto a equivocarme), ¿cómo hago para llamar a ese resultado de acción en el controlador correspondiente. Estoy confundido con este enfoque, sin embargo, gracias por su respuesta. - francisco rodgers

Como ya se habrá dado cuenta, Asp.Net MVC es un paradigma diferente a Asp.Net (formularios web). El acceso a elementos de formulario entre el servidor y el cliente adopta un enfoque diferente en Asp.Net MVC.

Puede buscar en Google más material de lectura sobre esto en la web. Por ahora, sugeriría usar Ajax para obtener o publicar datos en el servidor. Todavía puedes emplear input type="hidden", pero inicialícelo con un valor de la ViewData o para navaja, ViewBag.

Por ejemplo, su controlador puede verse así:

public ActionResult Index()
{
     ViewBag.MyInitialValue = true;
     return View();
} 

En su opinión, puede tener un elemento de entrada que se inicializa por el valor en su ViewBag:

<input type="hidden" name="myHiddenInput" id="myHiddenInput" value="@ViewBag.MyInitialValue" />

Luego puede pasar datos entre el cliente y el servidor a través de ajax. Por ejemplo, usando jQuery:

$.get('GetMyNewValue?oldValue=' + $('#myHiddenInput').val(), function (e) {
   // blah
});

Alternativamente, puede usar $.ajax, $.getJSON, $.post dependiendo de su requerimiento.

Respondido 04 Jul 12, 10:07

Entiendo que su sugerencia no es la forma estándar de MVC de hacer las cosas. Pero inicialmente estoy buscando un enfoque rápido y sucio y daré su ejemplo más enseñado. Más tarde, cuando el tiempo lo permita, reprogramaré mi solución a un mejor estándar, pero por ahora necesito sacarla por la puerta. Todavía no estoy seguro, pero esta puede haber sido la respuesta que estaba buscando. - francisco rodgers

Pruébalo y verás. He estado haciendo esto por otras cosas, pero para sus propósitos también podría ser factible. No es necesariamente la mejor práctica, pero MVC no prohíbe el uso de Ajax. Simplemente no utilice esta técnica extensivamente. - Alex R.

En primer lugar, ASP.NET MVC no funciona de la misma manera que WebForms. no tienes todo runat="server" cosa. MVC no ofrece la capa de abstracción que ofrece WebForms. Probablemente debería tratar de entender qué son los controladores y las acciones y luego debería mirar el enlace del modelo. Cualquier tutorial de nivel principiante sobre MVC muestra cómo puede pasar datos entre el cliente y el servidor.

Respondido 04 Jul 12, 10:07

Creo que puedes usar formularios ASP en MVC. La elección de View Engine es entre Razor CSHTML o ASP Web Forms. - Rolice

De hecho, puede, pero ¿ha notado que estos formularios ya no tienen un código detrás? :-) (comprensible ya que el controlador es el nuevo código detrás). Gracias por tu respuesta. - francisco rodgers

Lo está haciendo mal ya que intenta mapear WebForms en la aplicación MVC.

No hay controles del lado del servidor en MVC. Solo el Ver y Normativa en el back-end. Envías los datos del servidor al cliente mediante la inicialización de la Vista con tu modelo.

Esto sucede en la solicitud HTTP GET a su recurso.

[HttpGet]
public ActionResult Home() 
{
  var model = new HomeModel { Greeatings = "Hi" };
  return View(model);
}

Envía datos del cliente al servidor mediante la publicación de datos en el servidor. Para que eso suceda, crea un formulario dentro de su vista y [HttpPost] controlador en su controlador.

// View

@using (Html.BeginForm()) {
  @Html.TextBoxFor(m => m.Name)
  @Html.TextBoxFor(m => m.Password)
}

// Controller

[HttpPost]
public ActionResult Home(LoginModel model) 
{
  // do auth.. and stuff
  return Redirect();
}

Respondido el 28 de diciembre de 18 a las 12:12

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.