Search code examples
asp.net-mvc-3requiredfieldvalidatormodelstatehtml.hiddenfor

Using @Html.HiddenFor in MVC3


I'm having lots of troubles. I think that MVC just hates me.

1st. I'm using Linq and the model is automagically generated. I just completed the properties I need with the [Required] tag/directives.

2nd. I have a "Big Model" that joins two of the models. Like is explained here -> Multiple models in a view


When I try to postback a view with a model that has those properties like nulls, is has the ModelState.isvalid == false. I think that is obvious because I set the [Required] to some of the properties that the model needs. And here comes the thing that brought me here.

3rd. When I'm trying to use @Html.HiddenFor(...) my page won't postback. If I use, let's say, 3 HiddenFor, the page does PostBack, but if I use 10 HiddenFor, the page just stand still. It does not go anywhere.

I've tried to do everything that is within my range of knowledge (very limited, I'm really new at MVC).

  • I've tried to bring to the view those properties and showing them up as if it were a "Detail View". Didn't succeed.
  • I've tried to set the @HiddenFor(model => model.Client). In the Action is passed as null.
  • I've tried to use these tons of HiddenFor.
  • I've tried to pass just an ID in the hidden (ClientID) and retrieve the object from the database, but the ModelState will not "update" its status once inside the action.

Why am I doing this? I'm doing this because I need the pages to display the "Required Field Message" when a box isn't filled, hence, forbiding the page to postback without the data. My database is fine, and those fields are "Not null", so, I can just remove the [Required] from the properties, but I would lose the "Required Field Message" (in addition to the PostBack that is the thing that I'm trying to avoid).

If anyone has the answer or an answer or whatever, please, post it... I'm about to shoot my head out xD

Thanks in advance...

PS: Sorry about my english... I know that it's not good (or even regular).


View

@model PruebaMVC.Models.OperacionModel

<script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>

@using (Html.BeginForm()) {
    @Html.ValidationSummary(true)
    <fieldset>
        <legend>Operación de Venta</legend>

        @Html.HiddenFor(model => model.INMUEBLE)
        @*@Html.HiddenFor(model => model.INMUEBLE.Direccion)*@
        @*@Html.HiddenFor(model => model.INMUEBLE.Localidad)*@
        @*@Html.HiddenFor(model => model.INMUEBLE.Ciudad)*@
        @*@Html.HiddenFor(model => model.INMUEBLE.Caracteristicas)*@
        @*@Html.HiddenFor(model => model.INMUEBLE.PrecioVenta)*@
        @*@Html.HiddenFor(model => model.INMUEBLE.CLIENTE.IDCliente)*@

        <div class="editor-label">
            @Html.LabelFor(model => model.OPERACION.CLIENTE1.Nombre, "Nombre del Comprador")
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.OPERACION.CLIENTE1.Nombre)
            @Html.ValidationMessageFor(model => model.OPERACION.CLIENTE1.Nombre)
        </div>

        <div class="editor-label">
            @Html.LabelFor(model => model.OPERACION.CLIENTE1.Apellido, "Apellido del Comprador")
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.OPERACION.CLIENTE1.Apellido)
            @Html.ValidationMessageFor(model => model.OPERACION.CLIENTE1.Apellido)
        </div>

        <div class="editor-label">
            @Html.LabelFor(model => model.OPERACION.CLIENTE1.FechaNacimiento, "Fecha de Nacimiento del Comprador")
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.OPERACION.CLIENTE1.FechaNacimiento)
            @Html.ValidationMessageFor(model => model.OPERACION.CLIENTE1.FechaNacimiento)
        </div>

        <div class="editor-label">
            @Html.LabelFor(model => model.OPERACION.CLIENTE1.DNI, "DNI del Comprador")
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.OPERACION.CLIENTE1.DNI)
            @Html.ValidationMessageFor(model => model.OPERACION.CLIENTE1.DNI)
        </div>

        <div class="editor-label">
            @*@Html.LabelFor(model=>model.OPERACION.IDFormaPago, "Forma de Pago")*@
            <label for="ComboFP">Forma de Pago</label>
        </div>
        <div class="editor-field">

            <select id="ComboFP" name="SelectFP">
                @{
                    foreach (PruebaMVC.Models.DatosLINQ.FORMA_PAGO item in PruebaMVC.Models.DatosLINQ.OperacionDatos.ListarFormaPago())
                    {
                        <option value="@(item.IDFormaDePago)">@(item.TipoPago)</option>
                    }
                 }
            </select>
        </div>

        <div class="editor-label">
            @Html.LabelFor(model => model.OPERACION.Comision, "Comisión de la Venta")
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.OPERACION.Comision)
            @Html.ValidationMessageFor(model => model.OPERACION.Comision)
        </div>

        <div class="editor-label">
            @Html.LabelFor(model => model.OPERACION.Legajo, "Número de Legajo")
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.OPERACION.Legajo)
            @Html.ValidationMessageFor(model => model.OPERACION.Legajo)
        </div>

        <p>
            <input type="submit" class="formbutton" value="Cargar Venta" />
        </p>
    </fieldset>
}

<div>
    @Html.ActionLink("Volver al listado de Inmuebles", "Index")
</div>

Controller

//
        // GET: /Inmueble/Sale/5

        public ActionResult VentaP(int id)
        {
            OperacionModel unModeloOperacionCompuesto = new OperacionModel();
            unModeloOperacionCompuesto.INMUEBLE = InmuebleDatos.DetallesInmueble(id);
            return View(unModeloOperacionCompuesto);
        }

        //
        // POST: /Inmueble/Sale/5

        [HttpPost]
        public ActionResult VentaP(OperacionModel model, FormCollection collection)
        {
            try
            {
                // TODO: Add insert logic here

                model.INMUEBLE = InmuebleDatos.DetallesInmueble(model.INMUEBLE.IDInmueble);

                CLIENTE clienteComprador = new CLIENTE();
                clienteComprador.Nombre = model.OPERACION.CLIENTE1.Nombre;
                clienteComprador.Apellido = model.OPERACION.CLIENTE1.Apellido;
                clienteComprador.DNI = model.OPERACION.CLIENTE1.DNI;
                clienteComprador.FechaNacimiento = model.OPERACION.CLIENTE1.FechaNacimiento;

                OPERACION nuevaOperacion = new OPERACION();

                int unIDUsuario = UsuarioDatos.IDUsuario(User.Identity.Name);
                int unIDFormaPago = Convert.ToInt32(collection["SelectFP"]);
                decimal unaComision = model.OPERACION.Comision;
                int unLegajo = model.OPERACION.Legajo;

                if (ModelState.IsValid)
                {
                    nuevaOperacion.INMUEBLE = model.INMUEBLE;
                    nuevaOperacion.FechaOperacion = DateTime.Now;
                    nuevaOperacion.IDUsuario = unIDUsuario;
                    nuevaOperacion.IDFormaPago = unIDFormaPago;
                    nuevaOperacion.INMUEBLE.IDEstado = 2;
                    nuevaOperacion.Monto = model.INMUEBLE.PrecioVenta;
                    nuevaOperacion.Comision = unaComision;
                    nuevaOperacion.Legajo = unLegajo;
                    nuevaOperacion.CLIENTE1 = clienteComprador;
                    nuevaOperacion.CLIENTE = model.INMUEBLE.CLIENTE;

                    OperacionDatos.CrearVenta(nuevaOperacion);

                    return RedirectToAction("Index");
                }
                else
                {
                    //return View(nuevaOperacion);
                    return View(model);
                }
            }
            catch
            {
                return View(model);
            }
        }

Edit 2:

I'm still touching the code, and when I comment the line of

@Html.HiddenFor(model => model.INMUEBLE.PrecioVenta)

Where "PrecioVenta" is a decimal(18,2), the page does post back... it is obviously still getting a ModelState.isValid == false because I'm having left that value.

What can I do?

Which are the primitive types for the "HiddenFor" will work? Or is some stuff of the .Net Framework that can't "map" that datatype properly?


Solution

  • I think that the problem is the client side validations and decimals. When you have a decimal value, it render it as "35,0" in your culture... but the javascript validator doesn't recognice the "," as a decimal coma.

    This is a problem I'm having but I've found a post here in stackoverflow about modifying the javascript validator.

    Here you can learn how to fix the javascript validator for decimals