Meu último Web Cast no MSDN, falando sobre o que são Sandboxed Solutions no SharePoint 2010, suas vantagens e exemplo de implementação, já está na MSDN: https://msevents.microsoft.com/CUI/WebCastEventDetails.aspx?culture=pt-BR&EventID=1032456921&CountryCode=BR. Dê uma olhada e me mande suas dúvidas!
terça-feira, 26 de outubro de 2010
Azure Development Storage não reconhece ponto decimal em valores double
Gravei em uma tabela do Development Storage do Azure uma entidade que tem uma propriedade do tipo double. O valor dessa propriedade era 123,45. Quando recarreguei a entidade do Dev Storage, ao ler o valor da propriedade, obtive 12.345. Aparentemente o Dev Storage estava “ignorando” o ponto decimal que eu tinha colocado ao armazenar o valor. Mas como a gente já tinha visto este comportamento em outras situações, e sempre era relativo ao “Regional Settings” sendo usado, tentei por aí.
DISCLAIMER: Não tente isto em casa. Manipular diretamente o BD do Development Storage é altamente “des-recomendado”.
Bem, abri o BD do Development Storage no SQL Management Studio, e achei uma tabela chamada “TableRow”, que contém as entidades que gravamos no dito cujo. Na coluna Data, estão gravadas as propriedades da entidade, formatadas como um documento XML. E o valor gravado lá era “123.45” – ou seja, o Dev Storage armazenou corretamente o valor; o problema aparentemente era na leitura. Pra confirmar isso, mudei o valor “na mão” (leia DISCLAIMER acima) para “123,45” e a aplicação retornou o valor que eu esperava.
Não consegui um jeito de mudar a cultura usada pelo Development Storage, para ver se com isto ele lia os valores de forma correta; mas um workaround simples é mudar, no Painel de Controle, na parte de configurações regionais, o separador decimal de “vírgula” para “ponto”. Aí você reinicia o Dev Storage e ele passa a ler corretamente os valores double. (No Windows 7 as configurações regionais para o separador decimal ficam em Painel de Controle > Relógio, Idioma e Região > Alterar o formato de data, hora ou número > Configurações adicionais).
Coloquei um bug no Connect sobre isto (o link está aqui mas parece que as entradas do Connect agora só são acessíveis se você se inscrever no programa do respectivo produto). Vamos ver o que o pessoal da MS responde.
sexta-feira, 22 de outubro de 2010
Papai Noel dos Correios 2010
Semana BPOS de WebCasts
Semana que vem a Microsoft irá realizar uma série de eventos sobre BPOS (Bussiness Productivity Online Services), que é um conjunto de serviços para colaboração e messaging rodando na nuvem. De acordo com o site do BPOS, “e-mail, Web conferencing, instant messaging, document collaboration and workflow”, ou seja, Exchange, Live Meeting, Office Communicator e SharePoint. Uma ótima pedida para pequenas e médias empresas que querem a agilidade que estes serviços dão aos negócios, mas que não tem como justificar ou suportar uma equipe de TI para mantê-los.
Os webcasts sobre BPOS serão:
25/10 - 12h00 - Semana na Nuvem com o BPOS - Visão Geral do BPOS
26/10 - 12h00 - Semana na Nuvem com o BPOS - Planejando a Implementação do BPOS em sua organização
27/10 - 12h00 - Semana na Nuvem com o BPOS - Criando sua conta trial no BPOS e Visão Geral da Central de Administração
28/10 - 12h00 - Semana na Nuvem com o BPOS - Instalando e Configurando o Directory Synchronization
29/10 - 12h00 - Semana na Nuvem com o BPOS - Migrando o Exchange Server 2007 para o Exchange Server Online
E pra você que está chegando aqui depois da realização, lembre-se que a gravação deles fica disponível no mesmo link.
Aconselho a fazerem o trial – gratuito - e verem os benefícios que o BPOS pode trazer à sua empresa, ou para seus clientes!
quarta-feira, 20 de outubro de 2010
Standby no Windows 2008
Só que meu boot de testes pro SharePoint é Windows 2008. Por default, o standby vem desabilitado no Windows 2008, pois sendo ele um sistema operacional para servidores, a Microsoft - com razão - achou que as consequências para a sua rede não seriam boas se um servidor entrasse em standby depois de um tempo de inatividade. Mas como esse meu boot é pra testes, eu quero poder botar o bichinho em standby.
Pra isso, basta criar um atalho apontando pra seguinte linha de comando:
%windir%\System32\rundll32.exe powrprof.dll,SetSuspendState Standby
Simples assim. Dá até pra criar links para shutdown, logoff, reboot e hibernate: http://blogs.msdn.com/b/baliles/archive/2010/06/08/tips-amp-tricks-enable-standby-in-windows-2008-r2-server.aspx.
quarta-feira, 13 de outubro de 2010
LinqPad4: Ferramenta free de consultas Linq também funciona no Azure Tables!!!
Então. Estava eu precisando debugar uma consulta Linq que a aplicação estava mandando pro Development Storage do Azure. Coloquei um breakpoint em cima da danada, e na hora que não veio o que eu queria, copiei ela pro clipboard e joguei na Watch1 pra poder alterar seu texto e ver o resultado desta alteração. Mas a janela de Watch não gostou do Linq na expressão: Expression cannot contain query expression.
Na Immediate Window, mesma coisa. Como ganhei um bônus de 2 dias no prazo da próxima entrega do projeto, fui procurar alguma ferramenta que me permitisse escrever e executar uma consulta Linq no Azure Tables. E aí achei o LinqPad4.
O LinqPad4 deixa você escrever um programa em uma linguagem (na versão 4 ele suporta C#, VB.NET, F# e SQL), e executa este programa na conexão de dados que você especificou. Ele contém funcionalidades que permitem ver o resultado de consultas Linq. E permite você declarar variáveis, colocar referência a assemblies, e incluir namespaces. Então ficou fácil fazer com que ele consulte o Azure Tables:
- Se vou fazer uma consulta Linq nas tabelas no Azure Tables, preciso instanciar a classe que serve como contexto de acesso às tabelas. Então na janela das propriedades da consulta (Query > Query Properties), coloco uma referência ao assembly que tem minha classe de contexto de dados (“Projeto1”.AcessoDados.dll, na figura – os personagens usam nomes fictícios pois nosso cliente tem muito carinho pelo nome fantasia que ele bolou para o produto):
- Ainda nessa janela, na tab “Additional Namespace Imports” coloco namespaces que vou usar na consulta – a mesma funcionalidade do using do C#.
E pronto! Agora posso escrever e executar consultas Linq nas tabelas do Development Storage:
Explicando o código:
Linha 1: Preciso dos dados de conexão com o Development Storage. Eles estão em Microsoft.WindowsAzure.CloudStorageAccount.DevelopmentStorageAccount.
Linha 2: Preciso instanciar a classe de contexto da aplicação, informando como ela deve se conectar ao Azure. Para consultar as tabelas no Development Storage, crio uma instância da minha classe de contexto usando a assinatura
ContextoDados(string baseAddress, Microsoft.WindowsAzure.StorageCredentials credentials). Esta assinatura está presente na minha classe de contexto pois é herdada de Microsoft.WindowsAzure.StorageClient.TableServiceContext.
Linhas 3-6: É a consulta Linq.
Linha 7: O LinqPad tem uma funcionalidade de escrever um List<T> como uma tabela no painel “Results”, o que permite você visualizar de forma fácil e rápida o resultado da consulta Linq.
O site do LinqPad é http://www.linqpad.net. Tem versões para o Framework 3.5 e 4.0, e é for free.
sexta-feira, 8 de outubro de 2010
Como passar lista de objetos de classe derivada para método que recebe lista objetos de classe base
Criei o seguinte método:
public static void IncluiEntidades(List<EntidadeAzureTable> entidades) { ... }EntidadeAzureTable é a classe base de várias outras na aplicação. Este método recebe uma lista de entidades e as grava nas respectivas tabelas (no Azure Table Service).
Pois bem, criei uma lista de objetos de uma classe derivada e tentei passá-la para o método acima:
List<DocumentoSaida> documentos; // DocumentoSaida deriva de EntidadeAzureTable documentos = ...; AzureTables.IncluiEntidades(documentos);O compilador do C# não deixou passar, retornando o seguinte erro de compilação:
Argument 1: cannot convert from 'System.Collections.Generic.List<DocumentoSaida>' to 'System.Collections.Generic.List<EntidadeAzureTable>'
Ele “não entendeu” que DocumentoSaida herda de EntidadeAzureTable. Aparentemente, se um método recebe um parâmetro que é uma lista de objetos de uma classe, não posso passar uma lista de objetos de uma classe derivada neste parâmetro.
Para resolver este problema, podemos utilizar generic type constraints: criar um método genérico, e usar a palavra-chave where para colocar uma restrição no parâmetro de tipo do método. Mudei a declaração do método para
public static void IncluiEntidades<T>(List<T> entidades) where T : EntidadeAzureTable { ... }e o compilador entendeu o que eu estava querendo fazer.