How to pass a Controller object or object list to View?

Asked

Viewed 2,341 times

-2

Controller:

 [HttpPost]
        public ActionResult Create(Pedido pedido)
        {

            List<Produto> lista = new List<Produto>();

            if (ModelState.IsValid)
            {
                Cliente cliente = unitOfWork.ClienteRepository.Busca(pedido.ClienteId);
                Produto produto = unitOfWork.ProdutoRepository.Busca(pedido.ProdutoId);
                lista.Add(produto);
                pedido.produtos = lista;
                pedido.cliente = cliente;
                unitOfWork.PedidoRepository.Adiciona(pedido);
                unitOfWork.Salva();
                return RedirectToAction("Index");
            }

            ViewBag.ProdutoId = new SelectList(context.Produtos, "ID", "Nome", pedido.ProdutoId);
            ViewBag.ClienteId = new SelectList(context.Clientes, "ID", "NomeCliente", pedido.ClienteId);
            return View(pedido);

        }

By then OK...I can save my order with an instantiated customer and a list of products...but when this controller passes this order to my View INDEX...the customer object and the list of products arrives empty.

VIEW

@model IEnumerable<ProjetoZeus.Models.Pedido>

@{
    ViewBag.Title = "Index";
}

<h2>Lista de Pedidos</h2>

<p>
    @Html.ActionLink("Adicionar Novo", "Create")
</p>

<fieldset>
    <legend>Pedidos</legend>

    <table>
        <tr>
            <th>@Html.DisplayNameFor(model => model.ID)</th>
            <th>Produto</th>
            <th>Preço</th>
            <th>@Html.DisplayNameFor(model => model.cliente)</th>
        </tr>
        @foreach (var item in Model)
        {
           <tr>
               <td>
                   @Html.DisplayFor(model => item.ID)
               </td>
               <td>
                   @Html.DisplayFor(model => item.produtos[0].Nome)
               </td>
               <td>
                   @Html.DisplayFor(model => item.produtos[0].Preco)
               </td>
               <td>
                   @Html.DisplayFor(model => item.cliente.NomeCliente)
               </td>
           </tr>

        }
    </table>

</fieldset>

Action of the Index

public ActionResult Index()
        {
            return View(unitOfWork.PedidoRepository.Pedidos);
        }

unitofwork class

public PedidoRepository PedidoRepository
        {
            get
            {
                if (pedidoRepository == null)
                {
                    pedidoRepository = new PedidoRepository(context);
                }

                return pedidoRepository;
            }
        }

Pedidorepository.Cs

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

namespace ProjetoZeus.Models
{
    public class PedidoRepository
    {
        private bool disposed = false;
        private Contexto context;

        public PedidoRepository(Contexto context)
        {
            this.context = context;
        }

        public void Salva()
        {
            context.SaveChanges();
        }

        public void Adiciona(Pedido pedido)
        {
            context.Pedidos.Add(pedido);
        }

        public Pedido Busca(int id)
        {
            return context.Pedidos.Find(id);
        }

        public void Remove(int id)
        {
            Pedido pedido = Busca(id);
            context.Pedidos.Remove(pedido);
        }

        public List<Pedido> Pedidos
        {
            get
            {
                return context.Pedidos.ToList();
            }

        }

        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

        protected virtual void Dispose(bool disposing)
        {
            if (!this.disposed)
            {
                if (disposing)
                {
                    context.Dispose();
                }
            }

            this.disposed = true;
        }
    }
}
  • Post your "Index" action code. Your "Index" action has to fetch your requests to be viewed in the view.

  • posted...the only things that are lost when you arrive in the view is the Customer object and the Product Type List

  • Customer and Products are loaded in your order query ? If you are using Entity, you have Lazy load enabled ?

  • Yes they are loaded and I am using Entity...what is Lazy load ?

  • http://answall.com/questions/20646/como-funciona-o-lazy-load-entity-framework

  • If it arrives empty, the repository is not doing what it should. How is the repository code?

  • In the Controller Create action I changed to : Return View("Index",unitOfWork.PedidoRepository.Orders); instead of Return Redirecttoaction("Index"); and it worked...but I did not understand why...the new requests I add it brings now the old ones remain null

  • looking well only the last request I add brings the right data

  • There’s something very wrong with the repository, and this return View() is terrible. You are using what for the bank layer?

  • I’m using that Entity Dbcontext

Show 5 more comments

1 answer

5

This is yet another question that shows the nonsense (and futility) of implementing repository with Entity Framework (which is already a repository). I explain everything here, but as you’re starting, I’ll explain step by step why.

This is your main code:

        List<Produto> lista = new List<Produto>();

        if (ModelState.IsValid)
        {
            Cliente cliente = unitOfWork.ClienteRepository.Busca(pedido.ClienteId);
            Produto produto = unitOfWork.ProdutoRepository.Busca(pedido.ProdutoId);
            lista.Add(produto);
            pedido.produtos = lista;
            pedido.cliente = cliente;
            unitOfWork.PedidoRepository.Adiciona(pedido);
            unitOfWork.Salva();
            return RedirectToAction("Index");
        }

First, the way you have formatted your domain only allows a product to have an order. The correct thing would be to define an associative entity between products and orders, such as:

public class ProdutoPedido
{
    [Key]
    public int ProdutoPedidoId { get; set; }
    public int ProdutoId { get; set; }
    public int PedidoId { get; set; }

    public virtual Produto Produto { get; set; }
    public virtual Pedido Pedido { get; set; }
}

Secondly, these methods are absolutely useless:

    public void Salva()
    {
        context.SaveChanges();
    }

    public void Adiciona(Pedido pedido)
    {
        context.Pedidos.Add(pedido);
    }

    public Pedido Busca(int id)
    {
        return context.Pedidos.Find(id);
    }

    public List<Pedido> Pedidos
    {
        get
        {
            return context.Pedidos.ToList();
        }

    }

You occupy the call stack to perform operations that the context already performs. And now comes the main reason you throw this repository away (beyond the transactional context that is impossible to happen with this structure, but this is another matter). Here:

    public PedidoRepository(Contexto context)
    {
        this.context = context;
    }

There is no guarantee that when selecting products and customers, you are using the same context, which causes various problems while persisting data.

A working solution, therefore, would be something like this:

    [HttpPost]
    public ActionResult Create(Pedido pedido)
    {
        if (ModelState.IsValid)
        {
            var cliente = contexto.Clientes.FirstOrDefault(c => c.ClienteId = pedido.ClienteId);
            var produto = contexto.Produtos.FirstOrDefault(c => c.ProdutoId = pedido.ProdutoId);
            var lista = new List<ProdutoPedido> {
                new ProdutoPedido { Produto = produto }
            };

            pedido.produtoPedidos = lista;
            pedido.cliente = cliente;

            contexto.Pedidos.Add(pedido);
            contexto.SaveChanges();
            return RedirectToAction("Index");
        }

        ViewBag.ProdutoId = new SelectList(context.Produtos, "ID", "Nome", pedido.ProdutoId);
        ViewBag.ClienteId = new SelectList(context.Clientes, "ID", "NomeCliente", pedido.ClienteId);
        return View(pedido);
    }
  • I thought it was simpler to use the direct Dbcontext class...but I was told that it was better to use these Pository...I will change the structure the way you show here...valeu Cigano !

  • 2

    Who said? Eduardo Pires?

  • 2

    hahahaha was actually a colleague of mine

Browser other questions tagged

You are not signed in. Login or sign up in order to post.