ASP.NET MVC – Acessando o conteúdo de um ViewBag de dentro da tag script

Olá, tudo bom?

Pode parecer simples, na verdade é muito simples mesmo, mas me perguntaram como fazer isso e resolvi escrever. Estou falando do assunto do título desse post, como usar um ViewBag de dentro de uma tag <script>, afinal, para acessar um ViewBag a partir de uma View usamos Razor. É possível utilizar o Razor em conjunto com o javascript desde que você esteja dentro de uma View (arquivo com extensão .cshtml, .vbhtml) e não de um arquivo .js (isso é bem óbvio, certo?). O razor trabalha no servidor e, nesse caso, o javascript no client, ou seja, quando o javascript “for trabalhar” o ViewBag já vai ter sido “transformado” em texto pelo razor. Vamos ver alguns exemplos para entender isso.

asp

Acessando um ViewBag de dentro de uma tag script

Para os exemplos eu utilizei C# em uma aplicação asp.net MVC 5 com o template Internet Application no Visual Studio 2013 e o navegador Chrome.

Veja o exemplo 1:

//Controller Home

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

namespace MvcApplication1.Controllers
{
 public class HomeController : Controller
 {
  public ActionResult Index()
  {
   ViewBag.Message = "Modify this template to jump-start your ASP.NET MVC application.";

   return View();
  }

  public ActionResult About()
  {
   ViewBag.Message = "Your app description page.";

   return View();
  }

  public ActionResult Contact()
  {
   ViewBag.Message = "Your contact page.";

   return View();
  }
 }
}

Perceba que eu não fiz nenhuma alteração no controller Home do template. No método Index podemos ver que existe um ViewBag (ViewBag.Message), vamos utilizá-lo para esse exemplo. Agora, abra a view /Home/Index.

View Home/Index

Figura 1 – View Home/Index

Na Figura 1, podemos ver que também não houve alteração no que foi criado automaticamente. Ao final do html da view /Home/Index vamos adicionar uma tag script com o código para acessar o ViewBag.Message e mostrá-lo em um alert.

//Snippet 1

<script>
 var texto = @ViewBag.Message
 alert(texto);
</script>

Se executarmos nossa aplicação agora e abrirmos o Chrome DevTools (tecle F12 no navegador), veremos que houve um erro de sintaxe no javaScript conforme mostra a Figura 2:

Erro de sintaxe no JavaScript

Figura 2 -Erro de sintaxe no JavaScript

Por que o erro? Ainda com o Chrome DevTools aberto, no canto direito da linha onde está sendo descrito o erro é possível clicar no link para verificarmos o local exato onde ocorreu, conforme indicado na Figura 2. Ao clicar seremos redirecionados para a aba source no local onde o erro aconteceu, conforme mostra a Figura 3.

Local onde aconteceu o erro de sintaxe.

Figura 3 – Local onde aconteceu o erro de sintaxe.

Ao analisar a Figura 3, fica fácil entender o porque do erro de sintaxe. O ViewBag.Message está armazenando uma string, entretanto, não estamos colocando-o entre aspas. Para corrigir este erro, basta colocarmos o @ViewBag.Message entre aspas, veja isso no Snippet 2.

//Snippet 2

<script>
 var texto = "@ViewBag.Message";
 alert(texto);
</script>

Na figura 3, podemos analisar também  que não temos mais o “ViewBag.Message”, mas somente o seu conteúdo, isso porque antes da view ser enviada para o browser o razor faz sua renderização (transforma tudo em html/texto). Nesse momento, ao executarmos a aplicação teremos o retorno esperado, um alerta com o conteúdo do ViewBag.Message. Veja isso na Figura 4:

Retorno esperado do exemplo 1.

Figura 4 – Retorno esperado do exemplo 1.

Se o ViewBag.Message estivesse guardando um valor numérico ou um valor booleano não seria necessário as aspas.

Vamos ver agora um segundo exemplo, como exibir um ViewBag que está armazenando um objeto json, dentro da tag script.

Acessar um objeto json armazenado dentro de um ViewBag no javaScript

Utilizando a mesma aplicação do exemplo 1. Nesse exemplo vamos instalar um pacote para nos auxiliar com a serialização de objetos para json. Vamos instalar esse pacote utilizando o nuget. No Visual Studio navegue até View >> Other Windows e clique em Package Manager Console.

Abrindo o package manager console

Figura 5 – Abrindo o package manager console

No console que se abrirá, digite o seguinte comando e espere a mensagem de que a instalação foi concluída.

PM> Install-Package Newtonsoft.Json

Vamos alterar o método Index do controller Home. Substitua o ViewBag.Message pelo ViewBag.obj e atribua a ele um tipo anônimo com as propriedades id, nome e sobrenome conforme mostra o snippet 3. Em seguida, utilizando a biblioteca que acabamos de instalar, vamos serializar o objeto anônimo antes de atribui-lo ao ViewBag.obj, veja como fazer isso no Snippet 4.

//Snippet 3

public ActionResult Index()
{
 ViewBag.obj = new { id=1, nome = "Wennder", sobrenome = "Santos" };

 return View();
}

//Snippet 4

public ActionResult Index()
{
  ViewBag.obj = Newtonsoft.Json.JsonConvert.SerializeObject(new { id=1, nome = "Wennder", sobrenome = "Santos"});

 return View();
}

Não podemos esquecer de alterar também o javaScript que está acessando o ViewBag na View /Home/Index. Devemos trocar o “@ViewBag.Message” por “@ViewBag.obj”, veja como ficou após a alteração no Snippet 5.

//Snippet 5


<script>
var texto = "@ViewBag.obj";
alert(texto);
</script>

Lembrando que json é string, por isso continuo usando as aspas. Se executarmos a aplicação nesse momento ela funcionará, porém, não da forma esperada. O objeto anônimo será exibido no alert com o formato html encode, conforme mostra a Figura 6:

Alert com o conteúdo do ViewBag.obj no formato html encode

Figura 6 – Alert com o conteúdo do ViewBag.obj no formato html encode

Isso acontece porque o método Index do controller Home é do tipo ActionResult e usa o método View() para fazer o retorno para quem o “chama”, o método View() renderiza e retorna um html. No caso do ViewBag.obj, para não gerar confusão com tag’s html alguns caracteres são substituídos por pequeno “códigos”. Conseguimos ver isso de outra forma também, através do DevTools. Abra-o teclando F12, navegue até a aba Network e clique na requisição localhost, feito isso clique na aba Response, conforme mostra a Figura 7.

Requisições da página /Home/Index

Figura 7 – Requisições da página /Home/Index

Após entendido o problema, vamos corrigi-lo. Para isso utilizaremos um html helper, o @html.raw. Conforme diz a documentação, o @html.raw recebe como parâmetro uma string e a retorna sem encoding. É exatamente o que precisamos, certo? Pois bem, vamos alterar o javaScript da view /Home/Index e decodificar o conteúdo do ViewBag.obj. Veja o javaScript alterado no snippet 6.

//Snippet 6

<script>
var texto = "@Html.Raw(ViewBag.obj)";
alert(texto);
</script>

Se executarmos a aplicação agora, conseguiremos ver o objeto anônimo criado no controller, entretanto, com um erro sintaxe gerado por conflito de aspas, veja isso na Figura 8:

Erro de sintaxe provado por conflito de aspas

Figura 8 – Erro de sintaxe provado por conflito de aspas

Resolveremos isso de forma simples, basta trocar as aspas duplas, que “envelopam” o ViewBag.obj, por aspas simples. Veja essa alteração no snippet 7:

//Snippet 7

<script>
var texto = '@Html.Raw(ViewBag.obj)';
alert(texto);
</script>

Agora sim temos uma cadeia de caracteres no formato json, se rodarmos a aplicação já teremos um alert mostrando o objeto criado no controller no formato json. Vamos fazer uma ultima alteração para mostrarmos uma propriedade por linha. Para fazer isso, teremos que “falar” para o javaScript que o ViewBag.obj é um objeto, fazemos isso com o JSON.parse. Veja essa alteração no snippet 8.

//Snippet 8

<script>
 var texto = JSON.parse('@Html.Raw(ViewBag.obj)');
 alert("Id:" + texto.id + "\nNome: " + texto.nome + "\nSobrenome: " + texto.sobrenome);
</script>

No alert estou concatenando o nome da propriedade com o seu valor e alguns “\n” para quebra de linha. Veja o resultado na Figura 9:

Exibindo valores do objeto anônimo criado no controller

Figura 9 – Exibindo valores do objeto anônimo criado no controller

Pessoal, uma vez que, a variável texto for declarada em um escopo global ela estará disponível em todos os arquivos .js que estão sendo referenciados pela view.

Espero ter sido claro nos exemplos.

Outro artigo sobre esse assunto é o Convertendo objetos para o padrão json em views do asp.net mvc do mestre Renato Groffe.

Seria legal que qualquer tipo de comentário fosse feito aqui no blog para que todos possam participar.

Até o próximo post.

Anúncios

10 comentários sobre “ASP.NET MVC – Acessando o conteúdo de um ViewBag de dentro da tag script

    • Opa Lysandro, como vai?
      Obrigado pelo feedback. É muito importante saber o que os leitores estão achando para que eu possa sempre melhorar.

      Abraços.

      Wennder Santos

    • E aê Renato, tranquilo?
      Desculpa a demora, final de ano está corrido. Muito obrigado pelo feedback, é muito bom saber como está o conteúdo que estou escrevendo.

      Obrigado.

      Abraços.

      Wennder Santos

Deixe um comentário

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair /  Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair /  Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair /  Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair /  Alterar )

w

Conectando a %s