vista una pasar mvc llenar formulario enviar entre dropdownlist desde datos controladores controlador c# asp.net-mvc asp.net-mvc-4

c# - una - MVC 4 ViewModel no se envía de vuelta al controlador



post mvc (9)

Parece que no puedo entender cómo enviar todo el modelo de vista al controlador a la función ''Validar y guardar''.

Aquí está mi controlador:

[HttpPost] public ActionResult Send(BitcoinTransactionViewModel transaction) { }

Aquí está el formulario en la vista:

<li class="check"> <h3>Transaction Id</h3> <p>@Html.DisplayFor(m => m.Transaction.TransactionId)</p> </li> <li class="money"> <h3>Deposited Amount</h3> <p>@Model.Transaction.Amount.ToString() BTC</p> </li> <li class="time"> <h3>Time</h3> <p>@Model.Transaction.Time.ToString()</p> </li> @using (Html.BeginForm("Send", "DepositDetails", FormMethod.Post, new { transaction = Model })) { @Html.HiddenFor(m => m.Token); @Html.HiddenFor(m => m.Transaction.TransactionId); @Html.TextBoxFor(m => m.WalletAddress, new { placeholder = "Wallet Address", maxlength = "34" }) <input type="submit" value="Send" /> @Html.ValidationMessage("walletAddress", new { @class = "validation" }) }

Cuando hago clic en enviar, el controlador contiene el valor correcto del campo walletAddress pero transaction.Transaction.Time , transaction.Transaction.Location , transaction.Transaction.TransactionId está vacío.

¿Hay alguna forma de que pueda pasar todo el Modelo de vuelta al controlador?

Editar:

Cuando ni siquiera recibo walletAddress en el controlador. ¡Todo se anula! Cuando @Html.HiddenFor(m => m.Transaction.TransactionId); esta línea solo: @Html.HiddenFor(m => m.Transaction.TransactionId); funciona y obtengo la propiedad Token en el controlador, pero cuando la vuelvo a agregar, todas las propiedades del objeto de transaction en el controlador son NULL.

Aquí está el BitcoinTransactionViewModel:

public class BitcoinTransactionViewModel { public string Token { get; set; } public string WalletAddress { get; set; } public BitcoinTransaction Transaction { get; set; } } public class BitcoinTransaction { public int Id { get; set; } public BitcoinTransactionStatusTypes Status { get; set; } public int TransactionId { get; set; } public decimal Amount { get; set; } public DateTime Time { get; set; } public string Location { get; set; } }

¿Algunas ideas?

EDITAR: Lo descubrí, está en la respuesta marcada a continuación ...


¿Puedes combinar esos 2 modelos que tienes? Así es como lo hago con un modelo por vista ... 1. Utilizo las plantillas de visualización de la vista para verlas, así puedo pasar todo el modelo y dejar los datos cifrados. 2. Configure su vista principal de esta manera ...

@model IEnumerable<LecExamRes.Models.SelectionModel.GroupModel> <div id="container"> <div class="selectLabel">Select a Location:</div><br /> @foreach (var item in Model) { @Html.DisplayFor(model=>item) } </div>

3. Cree una carpeta DisplayTemplates en shared. Cree una vista, nómbrela como su modelo que desea pasar, porque un DisplayFor busca la plantilla de visualización nombrada después del modelo que usa, yo llamo a mi GroupModel. Piense en una plantilla de visualización como una instancia de objeto de su enumeración. Groupmodel Se ve así, simplemente estoy asignando un grupo a un botón.

@model LecExamRes.Models.SelectionModel.GroupModel @using LecExamRes.Helpers @using (Html.BeginForm("Index", "Home", null, FormMethod.Post)) { <div class="mlink"> @Html.AntiForgeryToken() @Html.EncryptedHiddenFor(model => model.GroupKey) @Html.EncryptedHiddenFor(model => model.GroupName) <p> <input type="submit" name="gbtn" class="groovybutton" value=" @Model.GroupKey "> </p> </div> }

4. Aquí está el controlador. * GET & POST *

public ActionResult Index() { // Create a new Patron object upon user''s first visit to the page. _patron = new Patron((WindowsIdentity)User.Identity); Session["patron"] = _patron; var lstGroups = new List<SelectionModel.GroupModel>(); var rMgr = new DataStoreManager.ResourceManager(); // GetResourceGroups will return an empty list if no resource groups where found. var resGroups = rMgr.GetResourceGroups(); // Add the available resource groups to list. foreach (var resource in resGroups) { var group = new SelectionModel.GroupModel(); rMgr.GetResourcesByGroup(resource.Key); group.GroupName = resource.Value; group.GroupKey = resource.Key; lstGroups.Add(group); } return View(lstGroups); } [ValidateAntiForgeryToken] [HttpPost] public ActionResult Index(SelectionModel.GroupModel item) { if (!ModelState.IsValid) return View(); if (item.GroupKey != null && item.GroupName != null) { var rModel = new SelectionModel.ReserveModel { LocationKey = item.GroupKey, Location = item.GroupName }; Session["rModel"] = rModel; } //So now my date model will have Group info in session ready to use return RedirectToAction("Date", "Home"); }

5. Ahora si tengo muchas Vistas con diferentes modelos, generalmente utilizo un modelo relacionado con la vista y luego un obj de sesión que toma datos de cada modelo, así que al final tengo que enviar los datos.


De acuerdo, he estado trabajando en otra cosa y volví a pensar en el mismo tema una vez más. ¡Solo que esta vez descubrí cómo hacerlo funcionar!

Aquí está la respuesta para cualquiera que pueda estar interesado:

Aparentemente, hay una convención de nombres. Presta atención:

Esto no funciona:

// Controller [HttpPost] public ActionResult Send(BitcoinTransactionViewModel transaction) { } // View @using (Html.BeginForm("Send", "DepositDetails", FormMethod.Post, new { transaction = Model })) { @Html.HiddenFor(m => m.Token); @Html.HiddenFor(m => m.Transaction.TransactionId); . .

Esto funciona:

// Controller [HttpPost] public ActionResult Send(BitcoinTransactionViewModel **RedeemTransaction**) { } // View @using (Html.BeginForm("Send", "DepositDetails", FormMethod.Post, new { **RedeemTransaction** = Model })) { @Html.HiddenFor(m => m.Token); @Html.HiddenFor(m => m.Transaction.TransactionId); . .

En otras palabras, ¡un error de convención de nomenclatura! Hubo una ambigüedad de nombre entre la propiedad Model.Transaction y el campo de formulario de transaction + parámetro de controlador. Indestructible

Si tiene los mismos problemas, asegúrese de que el nombre de su parámetro de controlador sea único; intente cambiar el nombre a MyTestParameter o algo así ...

Además, si desea enviar valores de formulario al controlador, deberá incluirlos como campos ocultos y estará listo.


El enlace de modelo hidrata su modelo de vista en su acción de controlador a través de los valores de formulario publicados. No veo ningún control de formulario para las variables antes mencionadas, por lo que no se publicará nada. ¿Puedes ver si tienes algo de alegría con esto?

@using (Html.BeginForm("Send", "DepositDetails", FormMethod.Post, new { transaction = Model })) { @Html.TextBoxFor(m => m.WalletAddress, new { placeholder = "Wallet Address", maxlength = "34" }) @Html.Hidden("Time", Model.Transaction.Time) @Html.Hidden("Location", Model.Transaction.Location) @Html.Hidden("TransactionId", Model.Transaction.TransactionId) <input type="submit" value="Send" /> @Html.ValidationMessage("walletAddress", new { @class = "validation" }) }


El nombre de acción al que se publicarán los datos debe ser el mismo que el nombre de la acción desde la que se publican los datos. La única diferencia debe ser que la segunda acción en la que se publican los datos debe tener [HttpPost] y el método de Publicación solo debe servir para obtener solicitudes.


Esto no es MVC específico. El formulario HTML solo publicará los valores contenidos dentro de los elementos del formulario dentro del formulario. Su ejemplo no está dentro del formulario o en un elemento de formulario (como entradas ocultas). Tienes que hacer esto ya que MVC no depende de View State. Pon campos ocultos dentro del formulario:

@Html.HiddenFor(x => x.Transaction.Time) // etc...

Pregúntese sin embargo ... si el usuario no está actualizando estos valores ... ¿los requiere su método de acción?


Intente seguir con la siguiente afirmación no con FOREACH

<table> @for (var i = 0; i < Model.itemlist.Count; i++) { <tr> <td> @Html.HiddenFor(x => x.itemlist[i].Id) @Html.HiddenFor(x => x.itemlist[i].Name) @Html.DisplayFor(x => x.itemlist[i].Name) </td> </tr> } </table>


La firma del método de envío que el formulario está publicando tiene un parámetro denominado transacción, que parece confundir el archivador de modelo. Cambie el nombre del parámetro para que sea algo que no coincida con el nombre de una propiedad en su modelo:

[HttpPost] public ActionResult Send(BitcoinTransactionViewModel model) { }

Además, elimine el parámetro htmlAttributes de su llamada a BeginForm, ya que no está haciendo nada útil. Se vuelve:

@using (Html.BeginForm("Send", "DepositDetails", FormMethod.Post))

Cualquier información que regrese del cliente podría haber sido alterada, por lo que solo debe publicar la ID única de la transacción y luego recuperar cualquier información adicional sobre ella de su fuente de datos para realizar un procesamiento posterior. También querrá verificar aquí que el usuario que publica los datos tiene acceso a la identificación de la transacción especificada, ya que también podría haber sido manipulada.


Pon todos los campos dentro del formulario

@using (Html.BeginForm("Send", "DepositDetails", FormMethod.Post))

y asegúrese de que el modelo

BitcoinTransactionViewModel

incluido a la vista o no?


Pruebe las colecciones de formularios y obtenga el valor como. Creo que esto puede funcionar

public ActionResult Send(FormCollection frm) { var time = frm[''Transaction.Time'']; }