none
Pasar JSON a un controlador RRS feed

  • Pregunta

  • Buenas , tengo este modelo donde tengo definido un modelo Ventas que tiene una relación de 1 a N con el modelo VentasLinias

        public partial class Ventas
        {
            public Ventas()
            {
                this.Caja = new HashSet<Caja>();
                this.Montajes = new HashSet<Montajes>();
                this.VentasLinias = new HashSet<VentasLinias>();
            }
        
            public int idCliente { get; set; }
            public byte tiendaCliente { get; set; }
            public int id { get; set; }
            public byte tiendaVenta { get; set; }
            public string observaciones { get; set; }
            public decimal total { get; set; }
            public decimal subTotal { get; s
        
            public virtual ICollection<Caja> Caja { get; set; }
            public virtual Clientes Clientes { get; set; }
            public virtual ICollection<Montajes> Montajes { get; set; }
            public virtual Usuarios Usuarios { get; set; }
            public virtual ICollection<VentasLinias> VentasLinias { get; set; }
        }

    Luego tengo un controlador que recibe 2 parámetros un objeto Ventas y luego una Lista de VentasLinias , no se si es correcto esto o es mejor pasar solo un objeto Ventas y  dentro de el la lista de  VentasLinias

            public JsonResult guardarVenta(Ventas venta,List<VentasLinias> linias)
            {
                bool estado = false;
    
                try
                {
                    db.Ventas.Add(venta);
                    db.SaveChanges();
                    estado = true;
                }
                catch (Exception ex)
                {
                    estado = false;
                }
    
                return new JsonResult { Data = new { estado = estado } };
           }


    Y luego tengo el JS que se encarga de enviar el JSOn al controlador

            if (isAllValid) {
                var venta = {
                    OrderDateString: $('#orderDate').val().trim(),
                    Description: $('#description').val().trim(),
                    totalCobrar: $("#totalCobrado").val().trim(),
                    totalVenta: $("#totalVenta").val().trim()
                }
    
                var linias = {
                    OrderDetails: list
                }
    
    
                $(this).val('Please wait...');
    
                $.ajax({
                    type: 'POST',
                    url: '/Ventas/guardarVenta',
                    
                    data: {
                        venta: JSON.stringify(venta),
                        linias: JSON.stringify(linias)
                    },
    
                    contentType: 'application/json',
                    success: function (data) {
                        if (data.estado) {
                            alert('Venta creada correctamente');
                            //here we will clear the form
                            list = [];
                            $('#orderNo,#orderDate,#description').val('');
                            $('#orderdetailsItems').empty();
                        }
                        else {
                            alert('Error');
                        }
                        $('#submit').val('Save');
                    },
                    error: function (error) {
                        console.log(error.responseText);
                        $('#submit').val('Save');
                    }
                });
            

    Y al hacer la petición es decir en este trozo de código último me entra en "error" y me da este error

    <!DOCTYPE html> <html> <head> <title>Primitivo JSON no v&#225;lido: venta.</title> <meta name="viewport" content="width=device-width" />

    Gracias,


    • Editado ilernet viernes, 19 de mayo de 2017 17:22
    viernes, 19 de mayo de 2017 17:21

Todas las respuestas

  • hola

    porque no defines

    var venta = {
    	OrderDateString: $('#orderDate').val().trim(),
    	Description: $('#description').val().trim(),
    	totalCobrar: $("#totalCobrado").val().trim(),
    	totalVenta: $("#totalVenta").val().trim()
    }
    
    var linias = {
    	OrderDetails: list
    }
    
    var data = {
    		venta: venta,
    		linias: linias
    	};
    
    $(this).val('Please wait...');
    
    $.ajax({
    	type: 'POST',
    	url: '/Ventas/guardarVenta',
    	
    	data:JSON.stringify(data) ,

    ademas recuerda marcar el action con [HttpPost] asi sabe que tiene que actuar ente el POST del $.ajax

    saludos


    Leandro Tuttini

    Blog
    MVP Profile
    Buenos Aires
    Argentina


    viernes, 19 de mayo de 2017 17:29
  • Muchas gracias , ahora no me da error al enviar la información del JS al controlador .

    En el controlador he hecho estas modificaciones

     [HttpPost]
            public JsonResult guardarVenta(Ventas venta,List<VentasLinias> linias)
            {
    
    ...
    }

      Pero si hago debug en los objetos venta y linias no veo la lista de VentasLinias


    En canvio el objeto Venta que tengo en JS que tiene los campos totalCobrar y totalVenta , cuando hago debug en el constructor el parámetro Ventas venta tiene estas propiedades con sus valores correspondientes.

    Gracias



    • Editado ilernet viernes, 19 de mayo de 2017 18:26
    viernes, 19 de mayo de 2017 17:40
  • que pasa si usas

    public class Venta{

    public Ventas venta{get;set;}

    public List<VentasLinias> linias {get;set;}

    }

    [HttpPost] public JsonResult guardarVenta(Venta venta) { ... }

    unes los dos parametros en una unica clase

    saludos


    Leandro Tuttini

    Blog
    MVP Profile
    Buenos Aires
    Argentina

    viernes, 19 de mayo de 2017 18:20
  • Actualmente tengo la clase de esta manera  , el código lo genere mediante EF con la opción de Database first , en el diagrama de la base de datos tengo la relación de 1 Venta --> N VentasLinias   , supongo que por eso en el constructor de Ventas tengo un HashHet

        public partial class Ventas
        {
            public Ventas()
            {
                this.Caja = new HashSet<Caja>();
                this.Montajes = new HashSet<Montajes>();
                this.VentasLinias = new HashSet<VentasLinias>();
            }
        
             
            public decimal total { get; set; }
            public decimal subTotal { get; set; }
             
        
            public virtual ICollection<Caja> Caja { get; set; }
            public virtual Clientes Clientes { get; set; }
            public virtual ICollection<Montajes> Montajes { get; set; }
            public virtual Usuarios Usuarios { get; set; }
            public virtual ICollection<VentasLinias> VentasLinias { get; set; }
        }


    • Editado ilernet viernes, 19 de mayo de 2017 18:27
    viernes, 19 de mayo de 2017 18:24
  • hola

    >>el código lo genere mediante EF con la opción de Database first , en el diagrama de la base de datos tengo la relación

    No uses las clases de EF como parte del model que devuelves o mapeas como parametro en los action, es para problemas

    define clases nuevas para esto, puedes ayudarte con automapper para convertir de uno a otro

    solo estaria correcto exponer las clases de EF si usas OData, entonces si podrias aplica queries directas a EF, pero este no es el caso

    saludos


    Leandro Tuttini

    Blog
    MVP Profile
    Buenos Aires
    Argentina

    viernes, 19 de mayo de 2017 18:44
  • Gracias es mi primer proyecto en asp net mvc y soy novato en esto gracias por vuestra paciencia.

    Acabo de leer sobre automapper , en mi caso estoy usando EF6 + mvc5 y entiendo que automapper permite "duplicar" un objeto es decir si lo he entendido bien en mi caso deberia cojer la clase que me ha generado EF que en mi caso es por ejemplo esta y con automapper generar una que me quedaria algo como esto

    Esto debo generarlo yo de forma manual verdad? Vamos ...copy-paste y eliminar los métodos sobrantes verdad?

     
        public class ArticulosDAO
        {
           
            public string weblogin { get; set; }
            public byte tienda { get; set; }
            public int id { get; set; }
            public short proveedor { get; set; }
            public string codigoArticulo { get; set; }
            public string descripcion { get; set; }
            public bool activo { get; set; }
     
        }


    Esta es la clase que me ha generado automáticamente EF (entiendo que las ICollections y demás que genera al final del archivo es debido a las relaciones entre tablas verdad?)

     
        public partial class Articulos
        {
            public Articulos()
            {
                this.AlbaranesLinias = new HashSet<AlbaranesLinias>();
                this.ArticulosHistoricoPrecios = new HashSet<ArticulosHistoricoPrecios>();
                this.Stock = new HashSet<Stock>();
                this.VentasLinias = new HashSet<VentasLinias>();
            }
        
            public string weblogin { get; set; }
            public byte tienda { get; set; }
            public int id { get; set; }
            public short proveedor { get; set; }
            public string codigoArticulo { get; set; }
            public string descripcion { get; set; }
            public bool activo { get; set; }
     
        
            public virtual ICollection<AlbaranesLinias> AlbaranesLinias { get; set; }
            public virtual Proveedores Proveedores { get; set; }
            public virtual ICollection<ArticulosHistoricoPrecios> ArticulosHistoricoPrecios { get; set; }
            public virtual ICollection<Stock> Stock { get; set; }
            public virtual ICollection<VentasLinias> VentasLinias { get; set; }
            public virtual TipoProductos TipoProductos { get; set; }
        }


    Ahora mi pregunta es , una vez generado esta clase me faltaria cambiar en el controlador que hace las funciones de guardar  , modificar y editar para que apunten al objeto de esta clase nueva  , es esto el concepto lo he entendido bien?

    Gracias,

    • Editado ilernet viernes, 19 de mayo de 2017 21:29
    viernes, 19 de mayo de 2017 21:24
  • >>una vez generado esta clase me faltaria cambiar en el controlador que hace las funciones de guardar  , modificar y editar para que apunten al objeto de esta clase nueva

    exacto, pero no le pongas DAO a esa clase, porque no va mapear contra la db, usa en reemplazo Model o DTO

    saludos


    Leandro Tuttini

    Blog
    MVP Profile
    Buenos Aires
    Argentina

    sábado, 20 de mayo de 2017 5:30