Mostrando entradas con la etiqueta MVC. Mostrar todas las entradas
Mostrando entradas con la etiqueta MVC. Mostrar todas las entradas

Invalidar ModelState manualmente

El primer campo es el key, es el nombre del atributo para el cual se desplegara el mensaje

ModelState.AddModelError("Usuario", "mensaje");



Acceder a otros campos dentro de un CustomAttribute

Ej, para acceder al valor del atributo FechaHasta:

protected override ValidationResult IsValid(object value, ValidationContext validationContext)
        var otherValue = validationContext.ObjectType.GetProperty("FechaHasta").GetValue(validationContext.ObjectInstance, null);

Modelo llega en null

Si se está recibiendo el modelo en una variable cuyo nombre es igual que el de alguno de los atributos, el ModelBinder falla, porque trata de asignar un tipo de datos simple a uno complejo

Ejemplo:

    public class ImpresorasViewModel
    {
        public List<ImpresoraViewModel> ListaImpresoras {get; set; }
        public ImpresoraViewModel Impresora { get; set; }

        public ImpresorasViewModel()
        {
            this.ListaImpresoras = new List<ImpresoraViewModel>();
            this.Impresora = new ImpresoraViewModel();
        }
    }

Si el ActionResult esta definido así:

[HttpPost]
public ActionResult AgregarImpresora(ImpresorasViewModel impresora)

Esto falla, porque esta intentando recibir un parametro llamado impresora, mientras que en el modelo ya hay un parametro que se llama impresora.

Cambiandolo asi, queda funcionando:

[HttpPost]
public ActionResult AgregarImpresora(ImpresorasViewModel modelo)


Your model has a property named Asmenys_info and the parameter in your POST method is also named asmenys_info. Internally the DefaultModelBinder reads the values of the form data which includes a value for Asmenys_info and attempts to set property Asmenys_info to that value but it fails because there is no conversion from a string to a complex object.
Change the name of the parameter to anything other than a name of a property in your model and it will bind fine, for example
[HttpPost]
public ActionResult Index(AsmenysInfoViewModel2 model)

Enviar model y parametros adicionales en llamado ajax

Javascript

            var datos = $('form').serializeArray();
            var usuarioSup = {
                name: "usuarioSupervisor",
                value: "abc"
            };
            var passwordSup = {
                name: "passwordSupervisor",
                value: "xxx"
            };
            datos.push(usuarioSup);
            datos.push(passwordSup);

            jqxhr2 = $.ajax({
                type: "POST",
                data: datos,
                dataType: "json",
                url: "@Url.Action(@Model.Accion, @Model.Controlador)",
                beforeSend: function () {
                }
            }).fail(function (jqXHR, textStatus) {
                $.unblockUI();
                $("#mensaje").html("Error: " + "Status: " + jqXHR.status + " detalle: " + textStatus + " detalle: " + jqXHR.responseText);
            }).success(function (data) {
                $.unblockUI();
                $("#mensaje").html(data.Mensaje);

                if (data.Codigo != "err_sup") {
                    $("#div_supervision").hide();
                    $("#@ViewBag.boton").removeProp("disabled");
                }
            });


MVC

[HttpPost]
public ActionResult Ejecutar(ConsultaViewModel modelo, string usuarioSupervisor, string passwordSupervisor)
        {
            return null;
        }

Enviar datos desde javascript hacia un controller con AJAX en MVC

Método #1: Enviar form como JSON y otros parametros

Llamado Ajax

            var f = $("#form_refin").serializeFormJSON();
            var send = { param1: "111", param2: "222", datos: JSON.stringify(f) };
            
            jqxhr2 = $.ajax({
                type: "POST",                
                data: send,
                dataType: "json",
                url: "@Url.Action("Supervision2", "RefinanciacionArrendamiento")",
                beforeSend: function () {
                    //l.start();
                }
            }).fail(function (jqXHR, textStatus) {
                //l.stop();
                alert("Error: " + "Status: " + jqXHR.status + " detalle: " + textStatus + " detalle: " + jqXHR.responseText);
            }).success(function (data) {
                $("#HashSup").val(data);
            });


    (function ($) {
        $.fn.serializeFormJSON = function () {

            var o = {};
            var a = this.serializeArray();
            $.each(a, function () {
                if (o[this.name]) {
                    if (!o[this.name].push) {
                        o[this.name] = [o[this.name]];
                    }
                    o[this.name].push(this.value || '');
                } else {
                    o[this.name] = this.value || '';
                }
            });
            return o;
        };
    })(jQuery);




Controller

using Newtonsoft.Json;
...
...
...

[HttpPost]
public ActionResult Supervision2(string param1, string param2, string datos)
{            

 var refin = JsonConvert.DeserializeObject<RefinanciacionArrendamientoVM>(datos);
}


Método #2: Definir el objeto que se va a enviar manualmente

Llamado Ajax

$("#Modificar").click(function() {
var user = {
Documento: $("#txtDocumento").val(),
Email: $("#txtCorreo").val(),
Nombre: $("#txtNombre").val(),
TipoDoc: $("#drpTipoDoc option:selected").val()
}

jqxhr2 = $.ajax({

type: "POST",
async: false,
data: user,
dataType: "json",
url: "@Url.Action("ModificarUsuarioCreado", "Usuario")",
beforeSend: function () {}
})
.fail(function (jqXHR, textStatus) {})
.success(function (data) {}
);
});


Controller

[HttpPost]
public ActionResult ModificarUsuarioCreado(Usuario user) { ... }


public class Usuario

{
    public string Documento { get; set; }
    public string Email { get; set; }
    public string Nombre { get; set; }
    public string TipoDoc { get; set; }
}


Método #3: Enviar el Modelo completo

De esta forma se puede enviar el modelo desde la vista hacia un controller, cualquiera sea su estructura y complejidad.
Funciona con POST y GET, en este ejemplo se utiliza POST.
*** Tener en cuenta que utilizando este método NO se envían los datos modificados manualmente en el formulario o los datos cargados mediante javascript. Para poder hacer esto, utilizar el método 3 ***

Código en la View

Formulario:

@using Creditos.ViewModels.Liquidaciones
@model RefinanciacionArrendamientoVM
...
...
...    

Llamado Ajax

var model = JSON.parse('@Html.Raw(Json.Encode(Model))');

jqxhr2 = $.ajax({
                type: "POST",
                data: model,
                dataType: "json",
                url: "@Url.Action("Contabilizar", "RefinanciacionArrendamiento")" 
            }).fail(function (jqXHR, textStatus) {
                $("#arrendContent").html(jqXHR.responseText);
            }).success(function (data) {
                $("#div_mensaje").html(data.MsgError);
            });



Controller

[HttpPost]
public ActionResult Contabilizar(RefinanciacionArrendamientoVM refin) 
...
...
...


Método #4: Enviar el form serializado
De esta forma se pasan todos los datos del formulario (no del modelo, aunque si no se modifican los campos del form, son los mismos)
Este método permite pasar los cambios que se hagan en el formulario (cosa que el método #2 no puede hacer)

Llamado Ajax


jqxhr2 = $.ajax({
        }).fail(function (jqXHR, textStatus) {
            if (data.MsgError == "Refinanciación contabilizada correctamente.") {

    type: "GET",
    data: $('form').serialize(),
    dataType: "json",
    url: "@Url.Action("Contabilizar", "RefinanciacionArrendamiento")", 
    beforeSend: function () {                    
                  $.blockUI({
                      message: 'Espere por favor...',
                      css: {
                          border: 'none',
                          padding: '15px',
                          backgroundColor: '#000',
                          '-webkit-border-radius': '10px',
                          '-moz-border-radius': '10px',
                          opacity: 0.5,
                          color: '#fff'
                      }
                  });
               }

            $.unblockUI();

            $("#arrendContent").html(jqXHR.responseText);
        }).success(function (data) {
            $.unblockUI();
            $("#div_mensaje").html(data.MsgError);

                $("#btn_contabilizar").attr("disabled", "disabled");

                $("#btn_calcular").attr("disabled", "disabled");
            }                
        });







Cuando se actualizan los datos del modelo en el controller los cambios no se reflejan en la vista

Problema:
Cuando en un action de un controller se modifican datos del modelo y se hace el return View, en la vista no aparecen actualizados dichos datos.

Solución: 
Es necesario hacer ModelState.Remove("nombre-del-atributo")

Por ejemplo:

public ActionResult Prueba(ElModelo m)
{
     m.Nombre = "el nuevo nombre";
     ModelState.Remove("Nombre");
}


Listas no pasan en postback en MVC

Si se carga desde una lista otra con javascript, aunque ambas listas estén en el Modelo, la segunda lista no llega al controller cuando se hace submit.

Causa: Si bien la 2da lista se cargó con javascript, en el submit sólo se envían los datos que estén seleccionados (javascript carga la lista, pero no quedan seleccionados los elementos).
Por lo tanto, antes de hacer submit, la solucion es marcar todos los elementos de la segunda lista.

Error Entity framework "the entity framework provider type..."

Si hay una solucion que tiene dos proyectos, por ej, una dll que usa entity framework y un tester, el tester también tiene que tener las librerias de entity framework. Se deben instalar desde nuGet.

Si no se hace, aparece el siguiente error:

An unhandled exception of type 'System.InvalidOperationException' occurred in mscorlib.dll

Additional information: The Entity Framework provider type 'System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer' registered in the application config file for the ADO.NET provider with invariant name 'System.Data.SqlClient' could not be loaded. Make sure that the assembly-qualified name is used and that the assembly is available to the running application. See http://go.microsoft.com/fwlink/?LinkId=260882 for more information.



Code First con MVC Data Entity Framework

Web.config

  <connectionStrings>
    <add name="entity1" connectionString="Data Source=Xdesa;Initial Catalog=cv;Integrated Security=True" providerName="System.Data.SqlClient" />
  </connectionStrings>


HomeController.cs

        public ActionResult Index()
        {
            Book libro;

            Author a = new Author();
            a.AuthorID = 1;
            a.FirstName = "nombre2";
            a.LastName = "apellido1";
            
            var book = new Book { BookID=1, Author=a, Title="titulo1" };
            using (var context = new MyContext())
            {
                context.Books.Add(book);
                context.SaveChanges();

                //List<Book> l = context.Books.Where(m => m.BookID > 1).ToList();
                libro = context.Books.Where(m => m.BookID > 1).FirstOrDefault();

            }
           
            return View(libro);
        }


MyContext.cs

    public class Book
    {
        [Key] 
        public int BookID { get; set; }
        public string Title { get; set; }

        public Author Author { get; set; }
    }

    public class Author
    {
        [Key] 
        public int AuthorID { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }

        public ICollection<Book> Books { get; set; }
    }

    public class MyContext : DbContext
    {
        public DbSet<Book> Books { get; set; }
        public DbSet<Author> Authors { get; set; }

        public MyContext()
            : base("name=entity1")
        {
        }
    }

Index.cshtml

<!DOCTYPE html>
@using Curriculums.Models
@model Book

@{
    ViewBag.Title = "Index";
}

@Model.BookID - @Model.Title

<h2>Index</h2>



Cargar dropdownlist combo en MVC con una lista desde LINQ


@Html.DropDownListFor(m => m.Cheque.Bancos, new SelectList(Model.Cheque.Bancos, "Value", "Text"))


Cheque chq = new Cheque();

chq.Bancos = CargarBancos();

private IEnumerable<SelectListItem> CargarBancos()
{
IEnumerable<SelectListItem> ll;

using (var db = new X_XEntities())
{
var b = from t in db.BCT_DES
where t.TIPDESTAB == 5
select new { t.CODDESTAB, t.DESCORTAB };


ll = b.Select(aa => new SelectListItem
{
Text = aa.DESCORTAB,
Value = aa.CODDESTAB.ToString()
}).ToList();

}

return ll;
}

Ejemplo MVC

Controllers / ClienteController.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using MvcApplication1.Models;
using LibX.X;
using LibX.X.X.cifIO;

namespace MvcApplication1.Controllers
{
    public class ClientesController : Controller
    {
        //
        // GET: /FormularioClientes/

        public ActionResult Formulario()
        {
            Parametros p = new Parametros();
            ViewBag.doccli = p.comboBCT("TIPDOC");
            ViewBag.paises = p.comboBCT("PAIS");
         
            return View();
        }

        public ActionResult Listado(FormCollection form)
        {
            SqlDb odb = new SqlDb();

            odb.AbrirDB();
            odb.BeginTran();

            ViewBag.doccli = form["doccli"];

            cli.doccli = int.Parse(form["doccli"].ToString());
            cli.numcli = long.Parse(form["numcli"].ToString());
            cli.digcli = form["digcli"].ToString();

            Cliente c = new Cliente();

            try
            {
                cli.LeerCliente(odb);
             
                c.doccli = cli.doccli;
                c.numcli = cli.numcli;
                c.nomabr = cli.nomabr;

                odb.CommitTran();
                odb.CerrarDB();
            }
            catch (Exception e)
            {
                c.nomabr = "NO HAY DATOS...";
            }

            return View(c);
        }

    }
}

Models / Cliente.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.ComponentModel.DataAnnotations;

namespace MvcApplication1.Models
{
    public class Cliente
    {
        public int doccli {get; set;}

        [StringLength(7)]
        public long numcli {get; set;}

        public int digcli {get; set;}

        public String nomabr { get; set; }
    }


}


Models / Parametros.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.UI.WebControls;
using LibX.X;
using LibX.X.Y.bctIO;

namespace MvcApplication1.Models
{
    public class Parametros
    {
        public int ItemBCT { get; set; }
        public List<System.Web.Mvc.SelectListItem> ItemBCTList { get; set; }

        public List<System.Web.Mvc.SelectListItem> comboBCT(String tabla)
        {
            SqlDb odb = new SqlDb();

            odb.AbrirDB();
            odb.BeginTran();

            des.LeerBCTPorTabla(odb, tabla);

            List<System.Web.Mvc.SelectListItem> lista = new List<System.Web.Mvc.SelectListItem>();

            for (int i = 0; i < odb.dt.Rows.Count; i++)
            {
                SelectListItem item = new SelectListItem { Value = odb.dt.Rows[i]["coddestab"].ToString(), Text = odb.dt.Rows[i]["coddestab"].ToString() + " - " + odb.dt.Rows[i]["descortab"].ToString() };

                lista.Add(item);
                /*
                ItemBCTList = new List<System.Web.Mvc.SelectListItem>() {
                        new SelectListItem { Value = "1", Text = "Renault" },
                        new SelectListItem { Value = "2", Text = "Peugeot" } };
                 * */
            }

            odb.CommitTran();
            odb.CerrarDB();

            return lista;
           // return ItemBCTList;
        }
    }
}


Views / Clientes / Formulario.cshtml

<!DOCTYPE html>
@using MvcApplication1.Models
@model Cliente

@{
    ViewBag.Title = "Formulario";
}
<link href="../../Content/themes/base/jquery-ui.css" rel="stylesheet" type="text/css" />
<script src="../../Scripts/jquery-1.10.2.js" type="text/javascript"></script>
<script src="../../Scripts/jquery-ui-1.10.3.js" type="text/javascript"></script>


@using (Html.BeginForm("Listado", "Clientes", FormMethod.Post))
{    
    @Html.DropDownList("doccli")    
    @Html.Label("Numcli")
    @Html.TextBoxFor(m => m.numcli)

    @Html.TextBoxFor(m => m.digcli)
    
    <input id="Submit1" type="submit" value="submit" />    
}