How to pass an object or list of objects from Controller to View?

-3

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);

        }

Okay ... I can save my order with an instantiated client and a list of products ... but when this controller passes that request to my View INDEX ... the client 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 da Index

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

class UnitOfWork

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

                return pedidoRepository;
            }
        }

RequestRepository.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;
        }
    }
}
    
asked by anonymous 28.10.2015 / 18:04

1 answer

5

This is one more question that shows the nonsense (and uselessness) of implementing repository with Entity Framework (which is already a repository). I explain everything here , but how are you? starting, I'll explain step by step why.

This is your primary 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 that you have formatted your domain only allows a product to have an order. The right thing would be to define an associative entity between products and requests, 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; }
}

Second, 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 off (besides the transactional context that is impossible to happen with this structure, but that's another matter). Here:

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

There is no guarantee that when you select products and customers, you are using the same context, which causes various problems as data persist.

A solution that works, therefore, would look 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);
    }
    
28.10.2015 / 19:43