Diferentes funcionalidades em uma View em ASP.NET MVC

46 views
Skip to first unread message

Rodrigo Macedo

unread,
Sep 3, 2010, 1:16:11 PM9/3/10
to dotn...@googlegroups.com

Boa tarde, Grupo!

Resolvi desenvolver uma aplicação em asp.net mvc pra entender as diferenças reais
de implementação e os ganhos em comparação ao modelo clássico. E como estou iniciando,
tenho algumas dúvidas sobre as responsabilidades e boas práticas.

Nesta aplicação, eu tenho algo parecido com um blog.
Eu tenho um artigo que o usuário pode comentar no final de cada assunto.

Na implementação, o modelo dessa view é a classe chamada Artigo. No que eu entendo do framework, eu não posso enviar um modelo para uma Action diferente do que está na declaração da view. Imagino que eu poderia enviar esse dado como um segundo objeto, agregando este segundo objeto dentro do modelo declarado na view.

Então, o que eu fiz: dentro da view do artigo, eu chamei outra
usando o Html.RenderAction, chamando o action responsável por ler todos os comentários feitos para aquele artigo.

Dentro dessa view parcial, eu também inclui um campo para adicionar novos comentários.  Como o modelo da view, é um vetor de Comentários, eu não poderia enviar um único objeto para Action. Para isso, criei mais uma view parcial dentro da view que lista comentários.

Então, eu tenho três views diferentes compondo um requisição. É essa a conclusão que vocês chegaram implementando em asp.net mvc? Como vocês fazem pra adicionar mais de uma funcionalidade numa página? Qual a abordagem que vocês usam?

Obrigado,
Rodrigo Macedo.

Felipe Oriani

unread,
Sep 3, 2010, 3:39:46 PM9/3/10
to dotn...@googlegroups.com
Olá Rodrigo, não sei se entendi direito mas tentarei ajudar...

Existe um conceito/prática chamado ViewModel, que você pode aplicar em suas views, deixando elas tipadas, um exemplo disso, você poderia criar uma classe (viewmodel), da seguinte forma:

public class ArtigoViewModel {
    public Artigo Artigo { get; set; }
    public IEnumerable<Comentario> Comentarios { get; set; }
}

E tipar sua view com este cara... assim em sua action você receberia uma instância deste viewmodel, e trabalharia com os dados. Claro que apenas estou ilustrando você poderia em seu objeto de domínio ter uma lista de comentários, mas este é o conceito que aplico quando preciso de várias informações em uma mesma página.

Quando você tem um formulário em uma view que dispara um request (get/post) para uma outra action, nada impede você de receber uma instância diferente daquela que a página é tipada. Em último caso, você pode usar o FormCollection...

Espero que tenha ajudado de alguma forma
[]'s




2010/9/3 Rodrigo Macedo <rodri...@gmail.com>
--
==============================
Comunidade de desenvolvedores Dot Net no Brasil
".Net Br" no Google Groups: http://groups.google.com.br/group/dotnet_br/
E-mail do Grupo: dotn...@googlegroups.com
"Your Potential. Our Passion."
 
==============================
Comunidade de desenvolvedores PHP
"LISTA PHP" no Google Groups: http://groups.google.com.br/group/listaphp
E-mail do Grupo: list...@googlegroups.com



--
______________________________________
Felipe B. Oriani
@felipeorianifelipeoriani.com.brfbor...@gmail.com

"...Trabalhe quanto puder, tornando-se útil quanto possível..." , por André Luiz

Felipe Oriani

unread,
Sep 3, 2010, 3:54:55 PM9/3/10
to dotn...@googlegroups.com
Onde eu disse "assim em sua action você receberia uma instância deste viewmodel,"

leia-se: "assim em sua action você retornaria uma instância deste viewmodel e na view você recebe.. pegando assim várias informações"

2010/9/3 Felipe Oriani <fbor...@gmail.com>

Rodrigo Macedo

unread,
Sep 3, 2010, 4:14:38 PM9/3/10
to dotn...@googlegroups.com
Pois é, entendi. E obrigado por responder.
 
Eu estou usando o modelo direto do meu domínio. Acho que o ViewModel pode ser interessante na view parcial, já que eu posso ter no futuro outra funcionalidade que eu habilite os comentários, o que facilitaria o reuso.

Então, pra facilitar, vamos considerar que só exista agora, essa view parcial. E este é o ViewModel.
 
public class ArtigoViewModel {

    public IEnumerable<Comentario> Comentarios { get; set; }
}
 
 
Talvez não esteja enxergando certo... No formulário para adicionar um novo comentário, como faria adicionar um novo comentário a esse vetor de Comentario usando o Html helper? Outra... Neste caso eu teria duas responsabilidades na propriedade Comentario? Agrupar TODOS os comentários do controller para view, e servir de meio campo pra adicionar novos da view para o controller. Ou não?
 
Outra dúvida: você disse é que eu posso enviar outro objeto mesmo que não seja o que eu declarei.
Como faço para passar um objeto complexo diferente do declarado?
 
Obrigado, Felipe.
Abraços,
Rodrigo Macedo.

Felipe Oriani

unread,
Sep 3, 2010, 5:58:54 PM9/3/10
to dotn...@googlegroups.com
Oi Rodrigo, 

Para adicionar um novo comentário, usando HtmlHelper não vejo uma forma de ser feita! Você teria que enviar (submit) as informações de seu formulário para uma action (seja por uma outra ViewModel de formulário, FormCollection, etc...) que deve persistir este comentário em algum lugar (banco de dados) e redirecionaria o usuário novamente ao artigo. Depois disso quando seu usuário solicitar novamente à página, e como você está preenchendo sua IEnumerable<Comentario> de um lugar já persistido, é conseqüente ter este comentário na lista (isso caso você não programe alguma regra , ex: para ser aprovado).

Você não teria responsabilidades na propriedade do ViewModel, vejo este ViewModel apenas como transferência de informações. Prencher comentários aprovados ou não, vejo como uma responsabilidade de um Repositório, lá você poderia ter um método "ObterComentariosAprovados(int idArtigo)". Uma coisa é você ter uma View tipada específica (sem renderizar partial views), outra é você ter uma View que necessita de diversos objetos (seja para renderizar em Partialview, ou não) que ai sim vejo necessidade de um ViewModel com vários propriedades (que são preenchidas no controller ou uma camada de serviços).

Pesquise também sobre ModelBinder, ainda estou estudando isso... mas acredito que resolva seu problema para receber objetos complexos em uma Action.

Rodrigo Macedo

unread,
Sep 6, 2010, 9:05:25 AM9/6/10
to dotn...@googlegroups.com
Obrigado pela resposta, Felipe.
Com certeza vou estudar ModelBinder.

Ricardo Rocha

unread,
Sep 6, 2010, 9:18:51 AM9/6/10
to DotNet Brasil
Ficou um pouco confuso este post, mas vejamos se consigo esclarecer um
pouco as coisas em relação ao MVC.
ViewModel serve para vc receber os dados na página ... ela, por si só,
não faz nada ... é um objeto burro .. uma DTO (Data Transfer Object).

Como EU gosto de trabalhar.
Quando a action é para carregar uma página inteira, crio uma Página
aspx. E nela uso "partial controls" (ascx), tantos quantos necessários
para cada um ter UMA única finalidade.

Vc teria a opção de ter a seguinte estrutura:
- Artigo.aspx (ViewModelArtigo)
- Comentarios.ascx (List<ViewModelComentario>)
- Comentario.ascx (ViewModelComentario)

Desta forma:
ViewModelArtigo - Codigo
- Titulo
- Corpo
- List<ViewModelComentario>

ViewModelComentario - Codigo
- Data
- Descricao


Tua "partial view" Comentarios.ascx teria apenas um loop para carregar
a "partial view" Comentario.ascx, passando um item do "List<>".
Desta forma vc poderia fazer a inclusão do comentário via ajax e
colocar este comentário no fim dos comentários usando o "append" do
jquery ... teu método de post de comentário poderia retornar a partial
view Comentario.ascx com os dados do comentário postado, assim vc
mantém a mesma estrutura e pode reaproveitá-la.

Mas veja bem, esta é apenas uma forma. Vc poderia fazer isso de várias
formas

Se quer usar um HtmlHelper vc até pode, mas não acho legal. Bastaria
vc criar um método de extensão para a VierUserControl que recebe as
informações do comentário e monta um html padrão. (ou então criar um
método de extensão para tua modelview)

Em relação ao HtmlHelper, gostaria de deixar minha opinião. Use-o para
coisas genéricas, como montar uma listagem de dados em formato padrão,
inserir um componente comum em várias páginas. Coisas específicas,
como inserir um comentário, por exemplo, deixe em usercontrol, que
serve justamente para isso.


Bem, qualquer dúvida mais pode escrever para meu e-mail ... como estou
na corrida, as vezes demoro a acessar a lista.

[]'s

Ricardo Rocha
Porto Alegre - RS




On 3 set, 18:58, Felipe Oriani <fbori...@gmail.com> wrote:
> Oi Rodrigo,
>
> Para adicionar um novo comentário, usando HtmlHelper não vejo uma forma de
> ser feita! Você teria que enviar (submit) as informações de seu formulário
> para uma action (seja por uma outra ViewModel de formulário, FormCollection,
> etc...) que deve persistir este comentário em algum lugar (banco de dados) e
> redirecionaria o usuário novamente ao artigo. Depois disso quando seu
> usuário solicitar novamente à página, e como você está preenchendo sua
> IEnumerable<Comentario> de um lugar já persistido, é conseqüente ter este
> comentário na lista (isso caso você não programe alguma regra , ex: para ser
> aprovado).
>
> Você não teria responsabilidades na propriedade do ViewModel, vejo este
> ViewModel apenas como transferência de informações. Prencher comentários
> aprovados ou não, vejo como uma responsabilidade de um Repositório, lá você
> poderia ter um método "ObterComentariosAprovados(int idArtigo)". Uma coisa é
> você ter uma View tipada específica (sem renderizar partial views), outra é
> você ter uma View que necessita de diversos objetos (seja para renderizar em
> Partialview, ou não) que ai sim vejo necessidade de um ViewModel com vários
> propriedades (que são preenchidas no controller ou uma camada de serviços).
>
> Pesquise também sobre ModelBinder, ainda estou estudando isso... mas
> acredito que resolva seu problema para receber objetos complexos em uma
> Action.
>
> []'s
>
> 2010/9/3 Rodrigo Macedo <rodrigo....@gmail.com>
>
>
>
> > Pois é, entendi. E obrigado por responder.
>
> > Eu estou usando o modelo direto do meu domínio. Acho que o ViewModel pode
> > ser interessante na view parcial, já que eu posso ter no futuro outra
> > funcionalidade que eu habilite os comentários, o que facilitaria o reuso.
>
> > Então, pra facilitar, vamos considerar que só exista agora, essa view
> > parcial. E este é o ViewModel.
>
> > public class ArtigoViewModel {
>
> >     public IEnumerable<Comentario> Comentarios { get; set; }
> > }
>
> > Talvez não esteja enxergando certo... No formulário para adicionar um novo
> > comentário, como faria adicionar um novo comentário a esse vetor de
> > Comentario usando o Html helper? Outra... Neste caso eu teria duas
> > responsabilidades na propriedade Comentario? Agrupar TODOS os comentários do
> > controller para view, e servir de meio campo pra adicionar novos da view
> > para o controller. Ou não?
>
> > Outra dúvida: você disse é que eu posso enviar outro objeto mesmo que não
> > seja o que eu declarei.
> > Como faço para passar um objeto complexo diferente do declarado?
>
> > Obrigado, Felipe.
> > Em 3 de setembro de 2010 16:54, Felipe Oriani <fbori...@gmail.com>escreveu:
>
> > Onde eu disse "assim em sua action você receberia uma instância deste
> >> viewmodel,"
>
> >> leia-se: "assim em sua action você retornaria uma instância deste
> >> viewmodel e na view você recebe.. pegando assim várias informações"
>
> >> 2010/9/3 Felipe Oriani <fbori...@gmail.com>
>
> >> Olá Rodrigo, não sei se entendi direito mas tentarei ajudar...
>
> >>> Existe um conceito/prática chamado ViewModel, que você pode aplicar em
> >>> suas views, deixando elas tipadas, um exemplo disso, você poderia criar uma
> >>> classe (viewmodel), da seguinte forma:
>
> >>> public class ArtigoViewModel {
> >>>     public Artigo Artigo { get; set; }
> >>>     public IEnumerable<Comentario> Comentarios { get; set; }
> >>> }
>
> >>> E tipar sua view com este cara... assim em sua action você receberia uma
> >>> instância deste viewmodel, e trabalharia com os dados. Claro que apenas
> >>> estou ilustrando você poderia em seu objeto de domínio ter uma lista de
> >>> comentários, mas este é o conceito que aplico quando preciso de várias
> >>> informações em uma mesma página.
>
> >>> Quando você tem um formulário em uma view que dispara um request
> >>> (get/post) para uma outra action, nada impede você de receber uma instância
> >>> diferente daquela que a página é tipada. Em último caso, você pode usar o
> >>> FormCollection...
>
> >>> Espero que tenha ajudado de alguma forma
> >>> []'s
>
> >>> 2010/9/3 Rodrigo Macedo <rodrigo....@gmail.com>
> >>> @felipeoriani <http://www.twitter.com/felipeoriani> |
> >>> felipeoriani.com.br | fbori...@gmail.com
>
> >>> "...Trabalhe quanto puder, tornando-se útil quanto possível..." , por
> >>> André Luiz
>
> >> --
> >> ______________________________________
> >> Felipe B. Oriani
> >> @felipeoriani <http://www.twitter.com/felipeoriani> | felipeoriani.com.br|
> >> fbori...@gmail.com
> @felipeoriani <http://www.twitter.com/felipeoriani> | felipeoriani.com.br |
> fbori...@gmail.com

Rodrigo Macedo

unread,
Sep 6, 2010, 12:32:50 PM9/6/10
to dotn...@googlegroups.com
Obrigado pela resposta, Ricardo.
Eu estava pensando em algo assim, só que ao invés de controle (e concordo muito com tua visão) eu estava usando partial views.
Também gostei da idéia do append em jquery. Não tinha pensado nessa possibilidade, realmente será útil.
Reply all
Reply to author
Forward
0 new messages