InstaSharp - Biblioteca C# que encapsula a API do Instagram

9/26/2013 11:23:12 PM By Felipe Pessoto

O InstaSharp é uma biblioteca C# que encapsula a API do Instagram, uma API RESTful.

Comecei a usar o InstaSharp para um projeto pessoal, mas percebi que faltava algumas propriedades e resolvi criar um fork do código original. Já existia um branch "re-design"com algumas novidades então trabalhei em cima dele e fiz diversas melhorias, principalmente uma atualização de tecnologia.

O projeto original estava meio parado, então o criador da biblioteca me incluiu como colaborador. Acredito que hoje sou o principal e único desenvolvedor ativo no projeto.

Re-escrevi boa parte do código que agora é todo assíncrono. As principais novidades são:

  • Convertido para Portable Class Library
  • Uso o HttpClient em vez do RestSharp
  • Todas chamadas são async
  • Projeto separado para Testes
  • Suporte para .NET 4, .NET 4.5, Silverlight 5, Windows Phone 8 e Windows Store 8

Você também pode criar um fork e contribuir com pull's requests.

Links:

InstaSharp

InstaSharp no GitHub

Meu Fork do InstaShap

Visual Studio 2013 & TFS 2013 RC disponíveis

9/9/2013 6:08:19 PM By Felipe Pessoto

Ontem instalei o Beta 1 do Visual Studio 2013, cansado de esperar um Release Candidate, e hoje recebo a notícia....hoje saiu o RC1, felizmente pra instalar o RC1 nem precisa desinstalar o Beta 1.

Assim como o Beta, ele vem com licença go-live, o que permite o uso em produção. Esta é uma versão mais próxima à final, com diversas correções, além disso também inclui o TypeScript 0.9.1.1.

O lançamento foi publicado em diversos blogs, onde você pode conferir mais informações e datalhes:

Visual Studio ALM + Team Foundation Server Blog

The Visual Studio Blog

.NET Framework Blog

.NET Web Development and Tools Blog

Brian Harry’s blog

 

Download Visual Studio 2013 RC1 (incluindo a opção por ISO)

TypeScript 0.9.0

6/19/2013 2:08:00 AM By Felipe Pessoto

Após algum tempo em Alpha e Beta, temos a versão 0.9.0. Pra quem ainda não conhece, o TypeScript é um superset do JavaScript desenvolvido pelo Anders Hejlsberg, pai do C#, que adicionar tipos opcionais e orientação a objetos. Assim todo código JavaScript é um código TypeScript válido. O objetivo é ajudar o desenvolvimento de aplicações em grande escala em JavaScript.

Essa nova versão traz diversas melhorias solicitadas pela comunidade, sendo a principal o suporte a Generics. Além disso o compilador foi reestruturado para lidar com aplicações com centenas de milhares de linha de código.

É fácil começar a usar, uma vez que seu código JavaScript é também TypeScript. Por ser Open Source, existem diversos editores, incluindo o plug-in pra Visual Studio, também recomendo usar em conjunto com a extensão Web Essentials, assim sempre que você salvar um arquivo (.ts) ele já chama o compilador e gera o (.js).

Também é possível usar arquivos de cabeçalho, tipando bibliotecas existentes como o jQuery, Knockout, underscore, etc

Download

Web Essentials

Projeto DefinitelyTyped (Arquivos de Cabeçalho)

Links:

Anúncio v0.9.0

Site Oficial

TypeScript no Codeplex

Try It

Blog

Twitter

 

A diferença que o C# 5.0 faz com o async/await

3/11/2013 11:51:00 PM By Felipe Pessoto

A melhor forma de ver a grande diferença que o async faz é usando exemplos. Saindo de um código não só maior, mas muito mais complicado, com callbacks, tratamento de contexto e thread de execução, tratamento de erros aninhados com os callbacks, pra um código simples, como se fosse um código síncrono comum.

Código Antigo:

void ShowStuff ()
{
	var client = new WebClient ();
	var content = JsonValue.Parse (client.DownloadString ("http://api.worldbank.org/countries?format=json&per_page=50"));
	int number_of_countries = content [0] ["total"];
	int done = 0, error = 0;

	InvokeOnMainThread (() => {
		CountriesLabel.Text = string.Format ("Countries: {0} done: 0 error: 0", number_of_countries);
	});

	foreach (JsonObject c in content [1]) {
		string country_url = string.Format ("http://api.worldbank.org/countries/{0}/indicators/NY.GDP.MKTP.CD&format=json", (string)c ["id"]);
		JsonValue json = null;

		try {
			json = JsonValue.Parse (client.DownloadString (country_url));
		} catch (Exception e){
			++error;
			InvokeOnMainThread (()=> status.Text = "Got exception "+ e);
			continue;
		}

		ThreadPool.QueueUserWorkItem (delegate {
			Map map = null;
			try {
				map = LoadCountryLogo (c ["name"]).Result;
			} catch (Exception e){
				++error;
				InvokeOnMainThread (()=> status.Text = "Got exception "+ e);
			}
			if (map != null){
				ThreadPool.QueueUserWorkItem (delegate {
					Position position = null;

					try {
						position = LookupCountryPosition (c ["longitude"], c ["latitude"]).Result;
						if (position != null)
							InvokeOnMainThread (() => {
								AddPin (map, position); 
								++done;
								status.Text = json ["name"];

							});
					} catch (Exception e){
						error++;
						InvokeOnMainThread (()=> status.Text = "Got exception "+ e);
					}

				});
			}
		});
		
		InvokeOnMainThread (() => CountriesLabel.Text = string.Format ("Countries: {0} done: {1} error: {2}", number_of_countries, done, error));
	}
	InvokeOnMainThread (() => {
		CountriesLabel.Text = string.Format ("Countries: {0}", number_of_countries);
	});
}
 

Código usando C# 5.0:

async Task ShowStuffAsync ()
{
	var client = new HttpClient ();

	var content = JsonValue.Parse (await client.GetStringAsync ("http://api.worldbank.org/countries?format=json"));
	int number_of_countries = content [0] ["per_page"];
	int done = 0, error = 0;

	CountriesLabel.Text = string.Format ("Countries: {0} done: 0 error: 0", number_of_countries);

	foreach (JsonObject c in content [1]) {
		try {
			string country_url = string.Format ("http://api.worldbank.org/countries/{0}/indicators/NY.GDP.MKTP.CD&format=json", (string)c ["id"]);
			var json = JsonValue.Parse (await client.GetStringAsync (country_url));
			var map = await LoadCountryLogoAsync (json ["name"]);
			if (map != null){
				var position = await LookupCountryPositionAsync (c ["longitude"], c ["latitude"]);
				if (position != null){
					AddPin (map, position);
					status.Text = json ["name"];
					++done;
				}
			}

		} catch (Exception e) {
			++error;
			status.Text = "Got exception "+ e;
		}
		CountriesLabel.Text = string.Format ("Countries: {0} done: {1} error: {2}", number_of_countries, done, error);
	}
	CountriesLabel.Text = string.Format ("Countries: {0}", number_of_countries);
}
 

Unobtrusive jQuery Validation com forms dinâmicos

3/6/2013 12:53:00 AM By Felipe Pessoto

Recentemente tive um problema ao usar um form dinâmico no ASP.NET MVC. A validação não "intrusiva" é processada assim que a página termina de carregar, e a partir daquele momento não é mais alterada. Porém eu tinha uma página que carregava todo o conteúdo do form via Ajax, e neste caso é ainda pior do que carregar um novo form, pois se o form já existia ele é marcado para não ser processado novamente, então preciso primeiro desmarca-lo e depois ativar a validação novamente. O código é simples, só não é algo suportado ou documentado, e depende de detalhes da implementação atual:

var form = $('#form-adiciona-entrega');

form.removeData('validator').removeData('unobtrusiveValidation');//Este passo só é necessário se o form já existia. Se o form em si é gerado dinamicamente, não precisa desse "reset"

$.validator.unobtrusive.parse(form);

 

Encontrei também este código, que diz fazer isso automaticamente a cada chamada ajax, mas que depende também de detalhes do ASP.NET MVC:

$(document).ajaxSuccess(function (event, xhr, settings) {
   if (settings.mvcTargetElement) {
       $(settings.mvcTargetElement.getAttribute("data-ajax-update")).each(function () {
          $.validator.unobtrusive.parse(this);
     });
  }
});

 

Fontes:

http://btburnett.com/2011/01/mvc-3-unobtrusive-ajax-improvements.html

http://stackoverflow.com/questions/11045256/jquery-client-side-validate-not-working