Neste tutorial, você vai aprender a desenvolver um widget Twitter para ASP.NET sob a forma de um controle de servidor reutilizáveis, como transformar automaticamente URLs em links, e cache para acelerar o carregamento da página.
Passo 1 Introdução
Para seguir este tutorial, tudo que você precisa é o Visual Studio (Você pode usar MonoDevelop , projeto Mono, se você não estiver no Windows, embora não haja garantias e nem suporte pela Microsoft, mas você pode tentar.) ou ainda utilizar a versão Web Developer Express Edition.
Você também vai precisar de conhecimento de C# 3.0, como este tutorial faz uso de algumas das novas funcionalidades da linguagem, como a utilização da palavra reservada var.
Passo 2 Criando o ControleO ASP.NET inclui um recurso útil conhecido como Server Controls. Estas são marcas personalizadas que visam ajudar os desenvolvedores com a estrutura de seu código. Quando uma página usando um controle de servidor é solicitado, o ASP.NET runtime executa o método Render (), e inclui a saída na página final.
Clique na imagem para ampliar
Depois de criar uma nova Web Application no Visual Studio, clique com o botão direito no Solution Explorer e adicione um novo item para a aplicação. Selecione ASP.NET Server Control, e dê um nome. Aqui, eu chamei de Twidget.cs, mas fique à vontade para chamá-lo com quiser. Cole o seguinte código, e não se preocupe se tudo parece um pouco estranho.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.Script.Serialization;
using System.Net;
namespace WebApplication1
{
public class Twidget : Control
{
public string Account { get; set; }
public int Tweets { get; set; }
protected override void Render(HtmlTextWriter writer)
{
writer.Write("<ul>");
foreach (var t in GetTweets().Take(Tweets))
writer.Write("<li>{0}</li>", HttpUtility.HtmlEncode(t));
writer.Write("</ul>");
}
public List<string> GetTweets()
{
var ls = new List<string>();
var jss = new JavaScriptSerializer();
var d = jss.Deserialize<List<Dictionary<string, object>>>(
new WebClient()
.DownloadString("http://api.twitter.com/1/statuses/user_timeline.json?screen_name=" + Account)
);
foreach (var x in d)
ls.Add((string)x["text"]);
return ls;
}
}
}
Passo 3 usando o controle
Agora temos o código para o nosso widget Twitter. Abra a página Default.aspx e coloque o seguinte código após o :
<%@ Register TagPrefix="widgets" Namespace="WebApplication1" Assembly="WebApplication1" %>
Sinta-se livre para mudar o TagPrefix para o que quiser, mas certifique-se que o atributo namespace esta definido corretamente para qualquer espaço que você colocou o código dentro do widget , e veja também se o atributoAssembly está definido para o nome do seu aplicativo web (no nosso caso , WebApplication1).
Uma vez que você registrou o prefixo, você pode começar a usá-lo. Cole o seguinte código em algum lugar na sua página, e mais uma vez, sinta-se livre para alterar os atributos que desejar.
<widgets:Twidget runat="server" Account="Sua-conta-no-Twitter" Tweets="10" />Se você tiver feito tudo corretamente, você deve ver uma página semelhante a esta quando você executar o aplicativo Web:
Clique na imagem para ampliar
Etapa 4 Melhorando Algumas Coisas …
O controle que nós temos no momento é bastante rudimentar. Para dar uma melhorada vamos tornar os links clicáveis.
Encontre o loop foreach no método Render () e desfazer-se completamente. Substitua-a por isso:
// Você precisa importar o uso de expressões regulares, cole isso junto com os outro using
using System.Text.RegularExpressions;
//Substitua esse foreach pelo que já havia no código anterior
foreach (var t in GetTweets().Take(Tweets))
{
string s = Regex.Replace(
HttpUtility.HtmlEncode(t),
@"[a-z]+://[^\s]+",
x => "<a href="" + x.Value.Replace("">" + x.Value + "</a>",
RegexOptions.Compiled | RegexOptions.IgnoreCase
);
writer.Write("<li>{0}</li>", s);
}
Vamos entender o Regex.Replace () na linha 6.
O primeiro parâmetro é a entrada do Regex. Neste caso, é apenas o texto do tweet após a passagem através HttpUtility.HtmlEncode (). A entrada é então comparado com o segundo parâmetro que é uma expressão regular concebido para corresponder a uma URL.
Ao final, deve aparece algo parecido com isso:
Clique na imagem para ampliar
Etapa 5 Caching
Há um grande problema com o código acima, e que é que ele não armazena em cache a resposta da API do Twitter. Isto significa que toda vez que alguém carrega sua página, o servidor tem que fazer uma solicitação para a API do Twitter e esperar por uma resposta. Isso pode diminuir seu tempo de carregamento da página e também pode deixar você mais vulnerável a um ataque de negação de serviço. Podemos resolver tudo isso implementando um cache.
Embora a estrutura básica do código do controle permanece após a implementação de cache, há muitas pequenas alterações. Observe:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.Script.Serialization;
using System.Net;
using System.Threading;
using System.Text.RegularExpressions;
namespace WebApplication1
{
public class Twidget : Control
{
public string Account { get; set; }
public int Tweets { get; set; }
public int CacheTTL { get; set; }
static Dictionary<string, CachedData<List<string>>> Cache = new Dictionary<string, CachedData<List<string>>>();
protected override void Render(HtmlTextWriter writer)
{
writer.Write("<ul>");
foreach (var t in GetTweets().Take(Tweets))
{
string s = Regex.Replace(
HttpUtility.HtmlEncode(t),
@"[a-z]+://[^\s]+",
x => "<a href='" + x.Value.Replace("'", """) + "'>" + x.Value + "</a>",
RegexOptions.Compiled | RegexOptions.IgnoreCase
);
writer.Write("<li>{0}</li>", s);
}
writer.Write("</ul>");
}
public List<string> GetTweets()
{
if (!Cache.Keys.Contains(Account)
|| (DateTime.Now - Cache[Account].Time).TotalSeconds > CacheTTL
)
new Thread(Update).Start(Account);
if (!Cache.Keys.Contains(Account))
return new List<string>();
return Cache[Account].Data;
}
public static void Update(object acc)
{
try
{
string Account = (string)acc;
var ls = new List<string>();
var jss = new JavaScriptSerializer();
var d = jss.Deserialize<List<Dictionary<string, object>>>(
new WebClient()
.DownloadString("http://api.twitter.com/1/statuses/user_timeline.json?screen_name=" + Account)
);
foreach (var x in d)
ls.Add((string)x["text"]);
if (!Cache.Keys.Contains(Account))
Cache.Add(Account, new CachedData<List<string>>());
Cache[Account].Data = ls;
}
catch (Exception) { }
}
}
class CachedData<T>
{
public DateTime Time { get; private set; }
T data;
public T Data {
get {
return data;
}
set
{
Time = DateTime.Now;
data = value;
}
}
}
}
O método Render () permanece inalterado, mas há algumas mudanças bastante drásticas em algumas partes. Nós mudamos o GetTweets () método, adicionou uma nova propriedade (CacheTTL), acrescentou um campo particular estático (Cache), e há ainda toda uma nova classe – CachedData.
O método GetTweets() não é mais responsável por falar com a API. Em vez disso, ele só retorna os dados no cache. Se detectar que a conta Twitter solicitado não tenha sido ainda colocado em cachê, ele irá gerar um segmento separado de forma assíncrona para atualizar o cache do tweet. Note que todo o corpo do método Update () é encerrado em um bloco try / catch, pois embora uma exceção no segmento página apenas exibe uma mensagem de erro para o usuário, se ocorrer uma exceção em outro segmento, ele irá desenrolar de todos os caminho de volta até a pilha e eventualmente travar o processo de trabalho responsável por atender toda a sua aplicação web.
O cache tweet é implementado como uma string <Dictionary, CachedData <string>>, onde o nome do usuário da conta do Twitter que está sendo armazenado em cache é a chave, e uma instância da classe CachedData <T> é o valor. A classe CachedData <T> é uma classe genérica e pode ser usado com qualquer tipo. Ela tem duas propriedades públicas, Data , que é alimentado pelo valor da resposta do tweet e Time, que é atualizada sempre que o tempo atual da propiedade Data estiver setado.
Você pode usar o seguinte código na sua página para usar esta versão em cache do widget. Note que o atributo CacheTTL é demostrado em segundos.
<widgets:Twidget runat="server" Account="twitter" Tweets="10" CacheTTL="600" />Então é isso… Espero que tenham gostado!
Vejam o artigo original. Até a próxima!
Artigo postado em:
ASP.NET