sexta-feira, 25 de novembro de 2011

Google Maps v3: Problema ao renderizar mapa oculto

Recentemente tive que implementar uma página com vários mapas do google, cada um dentro do seu separador (Tab).
O problema surgiu quando clico num separador, o mapa não renderiza como devia e não fica centrado na posição indicada.

A solução encontrada foi a seguinte:

Quando ocorre o clique no separador efectuar o seguinte:
  1. Guardar a posição.
  2. Disparar o evento resize para que o mapa redesenhe como devia.
  3. Centrar o mapa na posição que estava.

Aqui fica o código javascript com a solução.
function fixMap(map) {
    var center = map.getCenter();
    google.maps.event.trigger(map, "resize");
    map.setCenter(center);
}

quinta-feira, 24 de novembro de 2011

SharePoint 2010: Operador In, Caml

O SharePoint 2010 apresenta um novo operador nas Caml queries.
O operador em questão é o operador In que evita que tenhamos de escrever múltiplos Or.

Por exemplo, se tivermos o campo chamado Browser do tipo Text e quisermos procurar  os registos que têm  a palavra Firefox ou a palavra Chrome escrevemos a seguinte Caml query.

<Where>
  <In>
    <FieldRef Name='Browser' />
    <Values>
      <Value Type='Text'>Firefox</Value>
      <Value Type='Text'>Chrome</Value>
    </Values>
  </In>
</Where>

Como nem sempre as nossas queries são estáticas apresento uma forma de gerar o operador In dinamicamente através de uma coleção.

public static string InCaml(IEnumerable<string> items, string type, string name)
{
    string inFormat = "<Value Type='{0}'>{1}</Value>";

    var values = new StringBuilder();
    values.Append("<Values>");
    foreach (string item in items)
    {
        values.AppendFormat(inFormat, type, item);
    }
    values.Append("</Values>");

    var fieldRef = string.Format("<FieldRef Name='{0}' />", name);

    return string.Format("<In>{0}{1}</In>", fieldRef, values.ToString());
}


Exemplo de como chamar o método InCaml.

InCaml(new string[] { "Firefox""Chrome" }, "Text""Browser");

quinta-feira, 17 de novembro de 2011

Papercut - Servidor de SMTP

O Papercut é um servidor de SMTP que permite apenas receber e visualizar as mensagens.
É incrivelmente simples e prático, sendo bastante util para desenvolvimento de aplicações e não necessita de configurações.

quarta-feira, 16 de novembro de 2011

Deep compare de dois objectos em C#

Estava a implementar um teste e gostaria de comparar duas propriedades que eram classes complexas, no entanto é bastante complicado comparar todos os tipos de classes, sobretudo se forem colecções (IList, array, etc.). Após alguma pesquisa encontrei este projecto no codeplex que suporta a maioria dos tipos que uso no projecto:

http://comparenetobjects.codeplex.com/releases/view/47978

Este utilitário está todo implementado numa classe e usa reflection para correr as propriedades todas e é bastante fácil de usar com as opções default:

CompareObjects comparer = new CompareObjects();
return comparer.Compare(obj1, obj2);

domingo, 13 de novembro de 2011

Javascript: Converter uma string num array de caracteres

Em javascript para converter uma string num array de caracteres usamos o método split em que passamos por parametro uma string vazia.

Exemplo: 
"123456789".split("")

Resultado:
["1", "2", "3", "4", "5", "6", "7", "8", "9"]


quinta-feira, 10 de novembro de 2011

Parse do request no evento IDispatchMessageInspector.AfterReceiveRequest

Uma das melhores funcionalidades dos WCF WebServices é sua flexibilidade e capacidade de adicionar código nosso em quase qualquer parte do ciclo de vida do Request. Uma das hipoteses é usar um "inspector" de mensagens para, por exemplo, validar segurança ou alterar conteúdos de um Request.

Quando o pedido é recebido ainda não está deserializado para a respectiva classe .Net, achei problemático fazer esta deserialização. Após alguma investigação uma das formas que encontrei foi usar a classe TypedMessageConverter.

Nota: atenção que ao deserializar a mensagem é preciso criar uma cópia da Message usando este código:
MessageBuffer msgBuffer = message.CreateBufferedCopy(MaxMessageSize);
mais detalhes: http://social.msdn.microsoft.com/Forums/en/wcf/thread/cfef6695-8f6d-468f-9db5-8a27ee5a4b8f

Depois é possível deserializar o body da message com um método genérico:

public static T ParseBody(Message message)
{            TypedMessageConverter converter =
                  TypedMessageConverter.Create(typeof(T), message.Headers.Action);
            T body = (T)converter.FromMessage(message);
            return body;
}
mais detalhes: http://social.msdn.microsoft.com/Forums/en/wcf/thread/fd7f8df9-4a83-4285-be91-b9adb0c1888a