labnet@isel

Laboratório .NET do Instituto Superior de Engenharia de Lisboa

in

Ricardo Portela

  • AG_E_PARSER_UNKNOWN_TYPE Error due to Resource File Auto generated code-behind

    This is the most annoying error I got while developing in Silverlight 2.0… And I know I’m not alone… There are several causes to this problem.

    Generally speaking, this error indicates that a certain type could not be loaded OR (and this is important) that the type could not be instantiated.

     

    Error message (details removed)

    In our case, the problem was due to the fact that we are using resource files to localize the strings in the Silverlight application.

    To do this, we are using something like this in XAML:

    <Loc:Resource1 x:Name="LocStrings" />

    Then we can use the strings in the resource file like in the following example:

    <Button Content="{Binding Path=RESOURCE_KEY, Source={StaticResource LocStrings}}" />

    This way, the LoadComponent Method of the System.Windows.Application class tries to call a constructor of the Resource1 class.

    This is correct. The problem is that the constructor of this class is auto-generated and its visibility is Internal, being inaccessible to the Application class.

    So, the fix is easy: just switch the constructor’s visibility to public.

     

    The guilty....

     

    Note: You will need to apply this fix every time you add a string to the resource (or whenever the code-behind file gets automatically generated again).

  • (A little bit) smaller is (even) better

    (PT)

    Baseado no post do Delay acerca de como podemos reduzir o tamanho de uma aplicação Silverlight 2.0 (XAP), lembrei-me de uma ferramenta que é muito conhecida nos domínios da programação para Java ME (onde cada byte conta): KZip do Ken Silverman. Para além de conseguir uma taxa de compressão superior em relação a muitos (todos?) os compressores compatíveis com PKZIP, é gratuito tanto para uso privado como comercial.

    Não fiz testes tão exaustivos como o Delay, mas cá vão os resultados que obtive com a aplicação Silverlight de que falei num post anterior:

     

    Tamanho Inicial PKZip (como referido pelo Delay) Ganho com o PKZip KZip Ganho com o KZip
    334.027 bytes 259.355 bytes 22% 244.340 bytes 27%

     

    90KB podem não parecer nada nos dias de hoje, mas visto do ponto de vista do servidor, se tiver milhares de pedidos, esta solução já começa a ter algum interesse. Ainda para mais tendo em conta que uma vez preparado o ambiente, não dá trabalho nenhum… E mesmo o setup inicial não é assim tão complexo.

     

    Para utilizar o KZip, foi necessário efectuar algumas alterações ao ficheiro .cmd proposto pelo Delay. Ora cá vai a minha versão:

    @REM XapShrink - Recompresses XAP files smaller - Based on XapReZip by Delay, but using KZIP to do the dirty work

    @REM Invoke as a VS post-build event like so:

    @REM <WhereEver you created the .cmd file>\XapShrink.cmd $(TargetDir)$(TargetName).xap

     

    @echo off

    setlocal

     

    REM Define paths to zip.exe and unzip.exe

    set ZIPEXE="%~p0kzip.exe"

    set UNZIPEXE="%~p0unzip.exe"

     

    REM Define paths for intermediate files

    set XAP=%1

    set XAPDIR=%~p1

    set XAPBAK=%1.bak

    set XAPZIP=%1.zip

    set TMPDIR=%XAPDIR%tmp\

     

    REM Output a banner message

    echo XapShrink: %XAP%

     

    REM Change to XAP file directory

    pushd %XAPDIR%

     

    REM Create the temporary work folder

    md tmp

     

    REM Unzip the current XAP file

    %UNZIPEXE% -o %XAP% -d %TMPDIR%

     

    REM Change to temp file directory

    cd %TMPDIR%

     

    REM Create the new XAP using KZIP

    %ZIPEXE% /y %XAPZIP% %TMPDIR%*

     

    REM Abort if something went wrong

    if ERRORLEVEL 1 goto :DONE

     

    REM Replace original XAP file with smaller one

    move /y %XAPZIP% %XAP%

    del /Q *.*

    cd..

    rd tmp

     

    REM Output a success message

    echo XapShrink: Success

     

    :DONE

     

    REM Restore previous directory

    popd

     

    endlocal

     

    Para associar este comando ao vosso projecto, basta criar um ficheiro .cmd, colar o conteúdo anterior, e de seguida, no Visual Studio, associar o comando ao evento de Post-Build, como ilustrado de seguida:

     

    image

     

    Quando é feito o build, o output do processo de recompressão é exibido na janela de Output:

    image

     

    Para finalizar, aqui fica o ficheiro XapShrink.cmd, prontinho para ser associado ao projecto.

     

    (EN)

    While reading Delay's post about how can we reduce the size of a Silverlight 2.0 application(XAP), it stroke me about a tool very well known from the Java ME programming domain (where every single byte counts): KZip by Ken Silverman. This tool is not only able to get a compression rate better than most (all?)PKZip compatible compressors, but is also free for private and commercial use.

    I haven’t made tests as exhaustive as Delay’s but here goes the results I got, regarding the application I presented in a previous post:

     

    Initial Size PKZip (as suggested by Delay) Winnings with PKZip KZip Winnings with KZip
    334.027 bytes 259.355 bytes 22% 244.340 bytes 27%

     

    90KB might not look as much nowadays, but from the server’s point of view, if it serves thousands of requests, this solution starts to gather some interest. And we are talking about an optimization that once set up doesn’t need any action from the programmer’s side… And even the set ups is not that complex…

     

    To support KZip, it was necessary to make a few changes to the .cmd file proposed by Delay. Here goes my version:

    @REM XapShrink - Recompresses XAP files smaller - Based on XapReZip by Delay, but using KZIP to do the dirty work

    @REM Invoke as a VS post-build event like so:

    @REM <WhereEver you created the .cmd file>\XapShrink.cmd $(TargetDir)$(TargetName).xap

     

    @echo off

    setlocal

     

    REM Define paths to zip.exe and unzip.exe

    set ZIPEXE="%~p0kzip.exe"

    set UNZIPEXE="%~p0unzip.exe"

     

    REM Define paths for intermediate files

    set XAP=%1

    set XAPDIR=%~p1

    set XAPBAK=%1.bak

    set XAPZIP=%1.zip

    set TMPDIR=%XAPDIR%tmp\

     

    REM Output a banner message

    echo XapShrink: %XAP%

     

    REM Change to XAP file directory

    pushd %XAPDIR%

     

    REM Create the temporary work folder

    md tmp

     

    REM Unzip the current XAP file

    %UNZIPEXE% -o %XAP% -d %TMPDIR%

     

    REM Change to temp file directory

    cd %TMPDIR%

     

    REM Create the new XAP using KZIP

    %ZIPEXE% /y %XAPZIP% %TMPDIR%*

     

    REM Abort if something went wrong

    if ERRORLEVEL 1 goto :DONE

     

    REM Replace original XAP file with smaller one

    move /y %XAPZIP% %XAP%

    del /Q *.*

    cd..

    rd tmp

     

    REM Output a success message

    echo XapShrink: Success

     

    :DONE

     

    REM Restore previous directory

    popd

     

    endlocal

     

    To associate this command to your project, you just need to create a .cmd file and paste the above content (or download the file that I link below). Then, in Visual Studio, you need to associate the command to the Post-Build event, as the following picture shows:

     

    image

     

    When you build your application, the output window shows the recompression process evolution:

    image

     

    To sum things up, here is the XapShrink.cmd file, ready to be associated to your favorite project :).

  • Silverlight 2 Beta 2 is out, so take some time to update your SL Beta 1 Apps (specially if you use SeaDragon…)

    (PT)

    Como alguns de vós sabem, saiu uma nova versão (beta 2) do Silverlight 2.0.

    As aplicações desenvolvidas para a versão anterior (beta 1, como é o caso da aplicação que falei no meu anterior post), devem pois ser migradas para esta nova versão. Existe a necessidade de mudar algumas chamadas, mas nada de muito preocupante no meu caso. Não vou enunciar as alterações para esta nova versão, até porque estão bem documentadas, por exemplo aqui, ou aqui. O pior foi mesmo a alteração do formato dos ficheiros que são utilizados pelo controlo MultiScaleImage. Isto fez com que fosse obrigado a obter a nova versão do DeepZoom Composer. “Até aqui tudo bem”, pensei eu, “é só abrir o projecto anterior, e exportar novamente”. Pois… Não foi bem assim… Ao abrir o projecto anterior, o Deep Zoom Composer ficou durante uns valentes 45 minutos (o tempo de ir almoçar) a “abrir o projecto”…e nada… Acabei por criar um novo projecto, importar as imagens, compor a collection, e exportar…

    Já agora, saiu também uma nova versão do Expression Blend, mas esta não foi necessária para a migração da minha aplicação.

    Moral da história: Ai queres usar plataformas em versão beta, queres??

    Digo isto sem malícia, uma das coisas que nos é mostrada vezes sem conta na documentação que acompanha estas versões beta é precisamente que não devem ser utilizadas em ambiente de produção. É um risco que fica à responsabilidade de cada um.

     

    (EN)

    As some of you might know, there is a new Silverlight 2.0 Version available (beta 2).

    Applications developed for the previous version (beta 1, as is the case of the application I presented in one of my previous posts), must be converted ASAP for this new release. There are code-breaking changes, but nothing to worry about in my case. I will not enumerate the changes, as they are well documented (see this, or this). The sad part of the history came when I realized that the output of the Deep Zoom Composer (and consequently, the input for MultiScaleImageControl) has changed. To try and solve this, I downloaded the new version of DeepZoom Composer. “So far, so good”, I thought, “I’ll just open the previous project, and export it again”. Yeah.. right.. I opened the previous project in this new version of Deep Zoom Composer, noticed that it was taking a bit to load and went lunch. After 45 minutes, it was still “opening the project” I eventually got tired of it, and ended up creating a new project, importing the images, laying out the collection and exporting…

    Even though I haven’t needed it for this migration process, for the sake of completeness, I must also tell that there is a new version of Expression Blend available.

    Moral: So you want to use beta version platforms, huh??

    No harm intended, really. One of the things we are presented while installing and downloading such beta versions is precisely that these versions should not be used in production environment. So it is a risk that one must know how to control.

  • Criar blocos para o popfly

    (PT)

    Já passou muito tempo desde que fui convidado para fazer alguns blocos para o popfly, utilizando serviços do sapo. Os blocos viriam a ser depois utilizados para uma demonstração do popfly no Sapo Code Bits 2007 (eu avisei que já tinha passado muito tempo). Finalmente, "encontrei" algum tempo, e decidi agarrar num dos (vários) workitems que tenho pendentes nesta "categoria" :)

    Para quem não conhece, o Popfly é uma ferramenta online para a criação de mashups. Para quem não sabe o que é um Mashup... bem... resta-me perguntar em que buraco tem andado enfiado nos últimos anos... :)

    Software necessário

    • Web browser :) - Testado por mim no Firefox e no Internet Explorer 7. A aplicação é baseada em Silverlight, por isso, deverá funcionar em qualquer browser que suporte Silverlight.
    • Opcionalmente, pode ser utilizado um editor de texto, para a edição e manutenção de uma cópia local do código antes de submissão na aplicação Silverlight.

    Nota: O código-fonte dos blocos fica visível para outros utilizadores, por isso cuidado com o código que escreverem.

    Software recomendado

     

    Referência

    Para instalar o Popfly Explorer sobre o Visual Web Developer, é necessário efectuar o registo deste último. O registo é gratuito, e fica associado ao Live ID.

    Quando criei os blocos Sapo Pharmacy e Sapo Maps para apresentar no Sapo Code Bits, não existia este plug-in, pelo que já agora, aproveito para o apresentar, uma vez que me parece simplificar muito o processo.

     

    Para começar, vou apresentar os conceitos associados aos blocos, bem como o código / markup criado para a criação dos blocos Sapo Pharmacy e Sapo Maps.

    Mas afinal, o que é um bloco?

    Um bloco representa um serviço, e é composto por várias operações. Em Popfly, um bloco é composto por uma parte em XML, que descreve o bloco, e por uma parte em JavaScript, onde se define o comportamento do bloco.

    Como começar?

    Para começar, vamos ao serviço Web de pesquisa de Farmácias do Sapo, e escolhemos uma operação. Por exemplo, vamos começar com a operação "GetPharmaciesAtServiceByCoordinates". Podemos usar esta página para efectuar alguns testes, e observar o output da chamada da operação do serviço.

     

    image 

    O que colocar nestes campos? Bem, é fácil, podemos utilizar o Sistema de Informação Geográfica do Sapo para, por exemplo obter uma lista de Distritos, ordenada pelo nome.

    Surgirá uma lista de concelhos, onde cada um deles, terá o seguinte aspecto:

    image

    Fica a faltar o campo "radius". Este campo é utilizado para definir o raio da pesquisa (em metros), em torno das coordenadas seleccionadas.

    Assim sendo, escolhemos um concelho, e usamos os valores associados na página anterior. (Escolhi um raio de 10Km).

    Seja quais forem os parâmetros escolhidos, desde que não exista um erro nos argumentos, surgirá uma resposta semelhante a esta:

     

    image

    O que há aqui a reter é a estrutura da resposta, o url que surge no browser após a satisfação do pedido, que neste caso é algo do género:

    http://services.sapo.pt/Pharmacy/GetPharmaciesAtServiceByCoordinates?latitude=38.8031578&longitude=-9.381098&radius=10000

    Este dado também nos vai ser útil.

     

    Criar o bloco

    Esta é a parte fácil: no Popfly, menu "Create Stuff"-> "Block"

     

    image

     

    Estrutura (Markup)

    Assim sendo, já é mais fácil justificar o markup que tem de ser criado para dar suporte a esta operação, no bloco Popfly (recomenda-se uma passagem de olhos rápida pelo documento que consta nas referências):

    <?xml version="1.0" encoding="utf-8"?>
    <!-- O código Javascript do bloco reside na classe SapoPharmacyClass, que tem um método initialize -->
    <block class="SapoPharmacyClass" hasInitialize="true"> <providerName>Sapo</providerName> <operations>
    <!-- A lista de operações disponibilizadas pelo bloco. Para já apenas uma. -->
    <operation name="getPharmaciesAtServiceByCoordinates"> <!-- O nome do método em JavaScript que será chamado (sobre uma instância do tipo previamente identificado) --> <description> Obtém uma lista de farmácias de serviço a partir das coordenadas, e num raio especificado </description> <inputs>
    <!-- A caracterização de cada um dos argumentos da operação -->
    <input name="latitude" required="true" type="latitude"> <description>A latitude do local</description> <defaultValue>38.9982</defaultValue> <constraints/> </input> <input name="longitude" required="true" type="longitude"> <description>A longitude do local</description> <defaultValue>-9.16351</defaultValue> <constraints/> </input> <input name="radius" required="true" type="nonNegativeInteger"> <description>O raio da pesquisa</description> <defaultValue>10000</defaultValue> <constraints/> </input> </inputs> <outputs>
    <!-- A caracterização do resultado da operação --> <
    output isArray="true" type="custom" object="SapoPharmacy"/> </outputs> </operation> </operations> <objects>
    <!-- Definição do tipo custom "SapoPharmacy", referenciado no argumento de saída --> <
    object name="SapoPharmacy"> <field name="LastUpdate" isArray="false" type="date"/> <field type="nonNegativeInteger" isArray="false" name="Code"/> <field type="string" isArray="false" name="Name"/> <field type="phoneNumber" isArray="false" name="Phone" /> <field type="phoneNumber" isArray="false" name="Fax" /> <field type="string" isArray="false" name="Director" /> <field type="string" isArray="false" name="Distance" /> <field type="custom" isArray="true" name="Services" object="ServiceType"/> <field type="boolean" isArray="false" name="IsAtService"/> <field type="boolean" isArray="false" name="IsLateNight"/> <field type="location" isArray="false" name="Street"/> <field type="latitude" isArray="false" name="Latitude"/> <field type="longitude" isArray="false" name="Longitude"/> <field type="zipCode" isArray="false" name="ZipCode"/> <field type="integer" isArray="false" name="DistrictId"/> <field type="location" isArray="false" name="District"/> <field type="integer" isArray="false" name="MunicipalityId"/> <field type="location" isArray="false" name="Municipality"/> <field type="integer" isArray="false" name="ParishId"/> <field type="location" isArray="false" name="Parish"/> </object>
    <!-- Definição do tipo custom "ServiceType", referenciado no tipo custom SapoPharmacy, no campo "Services" --> <
    object name="ServiceType"> <field type="date" isArray="false" name="Date"/> <field type="string" isArray="false" name="Type"/> <field type="date" isArray="false" name="LastUpdate"/> </object> </objects> </block>

    Penso que a descrição é bastante auto-explanatória (hmm isto existe?..), e que não são necessárias mais explicações desta parte.

    Comportamento (JavaScript)

    De seguida, basta definir o código JavaScript para realizar a operação definida no Markup:

    function SapoPharmacyClass()
    {
    }
    //Esta função é chamada antes de ser iniciado o render do bloco.
    SapoPharmacyClass.prototype.initialize = function() {
        if (environment.designTime)
            throw "Isto não é suportado pelo bloco de farmácias do sapo em modo de desenho.";
        environment.output("<LINK REL=StyleSheet HREF=\"http://farmacias.sapo.pt/css/farmacias.css\" TYPE=\"text/css\>");
    }
    //A operação propriamente dita:
    SapoPharmacyClass.prototype.getPharmaciesAtServiceByCoordinates = function (latitude, longitude, radius) { 
    //Lembram-se da query string que surgiu quando foi feito o pedido com os argumentos de teste? url = "http://services.sapo.pt/Pharmacy/GetPharmaciesAtServiceByCoordinates?latitude="+latitude+"&longitude="+longitude+"&radius="+radius; return this.__getResults(url, "GetPharmaciesAtServiceByCoordinatesResult"); }; SapoPharmacyClass.prototype.__getElementValue = function (rootElement, tagName){ return rootElement.getElementsByTagName(tagName)[0]&&rootElement.getElementsByTagName(tagName)[0].firstChild!==null?rootElement.getElementsByTagName(tagName)[0].firstChild.nodeValue : ""; }; SapoPharmacyClass.prototype.__getResults = function (url, firstElemTagName) { var resultsArray = new Array(); var resultXML = environment.getXml(url); //Este método é fornecido pelo popfly. Sem este método, seria impossível realizar este código, porque o browser não permite chamadas em script para outros domínios.
    //boring... interpretação da resposta...... if(resultXML.getElementsByTagName(firstElemTagName).length >= 1) { var total = resultXML.getElementsByTagName("Total")[0]?resultXML.getElementsByTagName("Total")[0].firstChild.nodeValue : ""; var pharmaciesNodes = resultXML.getElementsByTagName("Pharmacy"); var pharmaciesCount = pharmaciesNodes.length; for(var i = 0; i < pharmaciesCount; i++) { //Elementos simples var LastUpdate = this.__getElementValue(pharmaciesNodes[i], "LastUpdate"); var Code = this.__getElementValue(pharmaciesNodes[i], "Code"); var Name = this.__getElementValue(pharmaciesNodes[i], "Name"); var Phone = this.__getElementValue(pharmaciesNodes[i], "Phone"); var Fax = this.__getElementValue(pharmaciesNodes[i], "Fax"); var Director = this.__getElementValue(pharmaciesNodes[i], "Director"); var Distance = this.__getElementValue(pharmaciesNodes[i], "Distance"); var IsAtService = this.__getElementValue(pharmaciesNodes[i], "IsAtService"); var IsLateNight = this.__getElementValue(pharmaciesNodes[i], "IsLateNight"); //tipos complexos //Address var Address = pharmaciesNodes[i].getElementsByTagName("Address")[0]; var Street = this.__getElementValue(Address, "Street"); var ZipCode = this.__getElementValue(Address, "ZipCode"); var DistrictId = this.__getElementValue(Address, "DistrictId"); var District = this.__getElementValue(Address, "District"); var MunicipalityId = this.__getElementValue(Address, "MunicipalityId"); var Municipality = this.__getElementValue(Address, "Municipality"); var ParishId = this.__getElementValue(Address, "ParishId"); var Parish = this.__getElementValue(Address, "Parish"); //Coordinates var Coordinates = Address.getElementsByTagName("Coordinates")[0]; var Latitude = this.__getElementValue(Coordinates, "Latitude"); var Longitude = this.__getElementValue(Coordinates, "Longitude"); //Services var ServicesNodes = pharmaciesNodes[i].getElementsByTagName("Service"); var ServicesCount = ServicesNodes===null?0:ServicesNodes.length; var servicesArray = new Array(); for(var k = 0; k < ServicesCount; k++){ var Date = this.__getElementValue(ServicesNodes[k], "Date"); var Type = this.__getElementValue(ServicesNodes[k], "Type"); var LastUpdate2 = this.__getElementValue(ServicesNodes[k], "LastUpdate"); servicesArray[k] = new SapoPharmacyService(Date, Type, LastUpdate2); } resultsArray[i] = new SapoPharmacy(LastUpdate, Code, Name, Street, Latitude, Longitude, ZipCode, DistrictId, District, MunicipalityId, Municipality, ParishId, Parish, Phone, Fax, Director, Distance, servicesArray, IsAtService, IsLateNight); } } return resultsArray; //array de instâncias do tipo SapoPharmacy, tal como descrito no Markup. }; //usado para encapsular tipo de dados SapoPharmacyService function SapoPharmacyService(date, type, lastUpdate){ this.Date=date; this.Type=type; this.LastUpdate=lastUpdate; } //usado para encapsular tipo de dados SapoPharmacy function SapoPharmacy(lastUpdate, code, name, street, latitude, longitude, zipCode, districtId, district, municipalityId, municipality, parishId, parish, phone, fax, director, distance, services, isAtService, isLateNight) { this.LastUpdate = lastUpdate; this.Code=code; this.Name=name; this.Phone=phone; this.Fax=fax; this.Director=director; this.Distance=distance; this.Services=services; this.IsAtService=isAtService; this.IsLateNight=isLateNight; this.Street = street; this.ZipCode = zipCode; this.DistrictId = districtId; this.District = district; this.MunicipalityId = municipalityId; this.Municipality = municipality; this.ParishId = parishId; this.Parish = parish; this.Latitude = latitude; this.Longitude = longitude; } //Utilizado pelo popfly quando o bloco é o último na cadeia, não entregando os resultados a outro bloco. SapoPharmacy.prototype.toString = function(){ var sb = new Sys.StringBuilder(); sb.append("<div style='height:110px' class='farm-destaque'><h2>"); sb.append(this.Name); sb.append("</h2>"); if (this.Distance>0){ sb.append("Diste2ncia "); var dist = parseFloat(this.Distance); dist=dist/1000; sb.append(dist.toFixed(2)); sb.append(" Km <br />"); } sb.append(this.Street); sb.append("<br/>"); sb.append(this.ZipCode); sb.append(" "); sb.append(this.Parish); sb.append("<br/>Tel. "); sb.append(this.Phone); sb.append("<br/><a href='http://mapas.sapo.pt/#c"); sb.append(this.Latitude); sb.append("_"); sb.append(this.Longitude); sb.append("_17'>Mapa</a></br></div>"); return sb.toString(); //tirar partido dos mapas do sapo para apresentar a localização da farmácia em questão };
     

    Este último método (toString), é chamado pelo Popfly quando o output do nosso mashup não é entregue a mais nenhum bloco, isto é, quando o nosso bloco está no fim da cadeia de invocação:

    image 

    Entretanto reparei que a página dos mapas foi alterada, e os pedidos na forma _-_">http://mapas.sapo.pt/#c<LATITUDE>_-<LONGITUDE>_<NIVEL_ZOOM> que utilizava no toString, deixaram de funcionar desde que fiz o bloco (era apresentado um mapa centrado nas coordenadas especificadas, ao nível de zoom indicado)... Estive a ver assim meio à pressa e não vi como é o novo formato para obter o mesmo efeito. Se alguém souber, apite!

    Pronto agora basta guardar, dar nome, etc etc.

    Bem, agora que temos o nosso bloco criado, toca a fazer Mashups!

    Criar um Mashup

    Aqui vem a parte divertida da coisa!

    Menu "Create Stuff"->"Mashup"

    image 
     

    Do lado esquerdo da aplicação, existe uma lista de blocos já existentes. Mesmo no fim dessa lista, surgem os blocos criados por nós.

    Lá deve residir o nosso Sapo Pharmacy. Cliquem nele (ou arrastem-no para a superfície de edição), e alterem as definições dos dados de entrada:

    image

    Aqui coloquem os valores que pretenderem (ou obtenham-nos através de outro bloco...)

    image

     

    Para um exemplo simples, vamos apenas exibir os resultados da pesquisa num mapa do Virtual Earth:

    image 

     

    Agora basta fazer "Run", e voilá:

    image 
     

    Agora que me preparava para juntar aqui o Bloco do Sapo Mapas que fiz também para o Sapo Code Bits, reparei que a malta do sapo mudou também o controlo dos mapas! Aqueles malandros... Lixaram-me a demo... Pronto, mas já deu para ficar com a ideia de como criar um bloco simples que consome dados de um Serviço. O dos mapas também tinha alguns conceitos engraçados, mas paciência... O código continua disponível no Popfly (tornei o bloco público), mas actualmente não funciona.

     

    Para a próxima vez que não tiver nada para fazer num serão (ou que não me apeteça fazer o que devia :) ), apresento o Popfly Explorer. Uma das coisas interessantes que vi é a geração de blocos de forma automática a partir do contrato WSDL. Isto promete...

  • Simple application for Silverlight's Deep Zoom (MultiScaleImage control)

    (PT)

    À algumas semanas atrás, o meu primo desafiou-me a fazer um pequeno facelift ao site da empresa onde ele trabalha.

    Não sendo propriamente uma pessoa com uma veia artística muito forte (zero...), centrei o facelift na componente tecnológica, e aproveitei para experimentar algumas tecnologias, APIs e bibliotecas que nunca tinha utilizado, tais como flash, script.aculo.us, google maps (2D e 3D) e, claro está, Silverlight 2.0.

    Ora uma das novidades em Silverlight 2.0, é a integração do trabalho realizado pela equipa do SeaDragon, sob a forma do controlo MultiScaleImage.

    Para explorar este controlo, adquiri as imagens com o scanner, a 800dpi, cortei as imagens de forma a ficarem todas da mesma dimensão, adicionei uma marca de água (requisito do "cliente" :)), e importei as imagens para o DeepZoom Composer. Como queria ficar com a hipótese de ordenar as imagens e ter controlo sobre cada uma delas individualmente, criei uma colecção no DeepZoom composer. Desta forma, cada imagem passa a ser representada por uma instância de MultiScaleSubImage, e podem ser manipuladas individualmente.

    Durante o desenvolvimento desta demo, deparei-me com diversas questões e problemas, que eventualmente apresentarei à medida que for tendo disponibilidade.

    Aqui fica um exemplo de como Silverlight abre portas para um conjunto de soluções muito interessantes, com pouco esforço (relativamente ao que seria normal). Para ficarem com uma ideia da simplicidade do desenvolvimento desta demo, demorei mais ou menos o mesmo tempo a preparar a colecção de imagens (aquisição, corte, marcas de água, e finalmente, composição no DeepZoom Composer) que a desenvolver a aplicação em Silverlight...

    A colecção de imagens tem, no total, cerca de 600 MB (a versão após tratamento por parte do DeepZoom composer, com os diversos tiles nos diferentes níveis de zoom).

    Deixo só uma nota final para a possibilidade de efectuar Debug das aplicações Silverlight 2.0, quando a aplicação está a correr no browser, que para mim, é fantástico.

    É até possível fazer debug de aplicações Silverlight quando o browser em utilização é o Firefox, por exemplo. Depois disto, quando fui fazer as partes em Flash, fiquei mesmo com saudades desta capacidade...

    (EN)

    A few weeks ago, my cousin, challenged me to do a small facelift to the site of the company he works on.

    Not being someone into design (no, not really...), I tried to compensate it on the technological side, and so I used this opportunity to try some Web Technologies, APIs and libraries that I have never used before, such as  flash, script.aculo.us, google maps (2D e 3D) and, finally, the motif of this post, Silverlight 2.0.

    One of the new things in Silverlight 2.0, that I explored is the integration of SeaDragon's Team work, that is working under the hood of the new MultiScaleImage control.

    To explore this control, I acquired the images with the scanner, at 800dpi, cut the images such that all ended up the same size, added some watermark (as required by the "customer" :)), and imported the images to DeepZoom Composer. Because I wanted to be able to order and manipulate each of the images individually, I've created a DeepZoom collection. This way, each image gets represented in Silverlight, as an instance of the type MultiScaleSubImage, and we can deal with each one of them individually.

    During the development of this demo, I've encountered several issues and problems, and I will eventually show the solution to some of them, as I get some spare time.

    So here it goes, an example of how you can use Silverlight to a set of very interesting solutions, with relative low effort. To get an idea of the effort involved in the development of this demo, I took more or less the same time to prepare the image collection (including acquisition, cut, watermarking, and composition in DeepZoom Composer) and develop the Silverlight application.

    The image collection has, in it's final state (as processed by DeepZoom Composer, and deployed to the server, including the various tiles at different zoom levels), around some 600 MB.

    Just a final note on Silverlight 2.0 application's Debug support while it is working in the Browser, that just RULES!! :)

    You can actually debug a Silverlight Application even if it is running on Firefox. Man, I missed this a lot when I made the flash controls of the site...

  • ZoomIt - Ferramenta para apresentações

    Todos nós já participámos em várias apresentações em que damos pelo orador (por vezes, nós...) a tentar descobrir como aumentar o tamanho da letra de uma determinada aplicação para que todos os participantes consigam ler o conteúdo que o orador refere.

    Por exemplo, no Visual Studio, o "truque" normalmente utilizado é o aumento do tamanho da letra. No entanto, caso se esteja a demonstrar a User Interface, ou outro item que não permita a alteração da dimensão, o problema persiste. (Como uma nota adicional, achei muito interessante a possibilidade oferecida pelo Expression Blend, em que é possível redimensionar toda a UI).

    Pois bem, durante uma sessão do TechDays 2008 dada pelo Edwin Yuen, encontrei uma solução muito interessante para este problema (sim, a sessão em si também foi muito interessante :) ).

    O apresentador em causa estava a utilizar um pequeno aplicativo (44KB) de seu nome ZoomIt, do nosso amigo Mark Russinovich (SysInternals), que já nos vem habituando a software muito prático, de grande qualidade e de grande utilidade, tal como o Process Explorer, Registry Monitor, etc etc (Aconselho vivamente uma visita ao site da Sysinternals (recentemente adquirida pela Microsoft)). Todas estas ferramentas são de download e utilização gratuita.

    Este software foi criado pelo autor para uso pessoal durante as suas apresentações, e entre outras coisas, permite escolher uma tecla ou combinação de teclas que activa o modo de zoom. Este zoom é feito em torno da região onde se encontra o ponteiro do rato. De seguida, à medida que o ponteiro do rato é movido, é também alterada a região que se encontra ampliada.

    Adicionalmente, é ainda possível desenhar e escrever sobre a área aumentada, ou em qualquer altura (com a dimensão original) para por exemplo, realçar determinados aspectos.

    Outra funcionalidade disponível nesta pequena ferramenta é a apresentação de um timer em full screen, em contagem decrescente. Isto é útil entre outras coisas, para os tempos mortos antes da sessão, dando aos espectadores a noção de quanto tempo falta para que o orador comece a sua apresentação.

  • Microsoft TechDays Academic Day - Entradas gratuitas para estudantes

    A Microsoft Portugal convida todos os alunos do ISEL/DEETC, a participar no evento a realizar no dia 20 de Março, Terça-Feira 14 de Março, Quinta-Feira, em Lisboa: o TechDays Academic Track (ACAD Day). Este evento insere-se no plano global do evento TechDays (www.microsoft.pt/techdays), sendo destinado a alunos de todo o país da área de Informática e com o objectivo de divulgar o potencial das novas tecnologias Microsoft, no desenvolvimento profissional e académico.
    Esta é uma excelente oportunidade de obteres formação GRATUITA em algumas das áreas mais interessantes (e importantes) do mercado actual de TI's, como Web Development ou Computação Gráfica, bem como de aproveitares o evento para conhecer alguns dos mais reputados profissionais dessa área e trocar ideias com eles, tal como o poderás fazer com os alunos das outras instituições que se irão deslocar ao evento.
    A agenda é composta por 3 sessões, a saber:
    14:15 :: DEV002 -The Microsoft Web Story: ASP.NET 2.0, ASP.NET AJAX, and WPF/E (Jeff Prosise)(ACAD Day);
    15:30 :: Break;
    16:00 :: DEV003 -Programação e Simulação de Robots usando Robotics Studio (Martin Calsyn)(ACAD Day);
    17:15 :: Break;
    17:45 :: DEV004 -Desenvolvimento de Jogos com XNA Express (Rob Miles)(ACAD Day);

    Para te inscreveres, basta enviares um e-mail para o endereço rportela em student-partners.com, com o teu primeiro e último nome, e-mail e contacto telefónico.

    O número de inscrições é limitado.

     

    Edit: O número limite de inscrições já foi ultrapassado.

    O follow up do evento será feito pela comunidade, e serão muito provavelmente disponibilizados conteúdos das sessões. Um ponto de encontro onde será com toda a certeza feito o rescaldo do evento é em http://weblogs.pontonetpt.com/.

  • Imagine Cup 2008 - IT Challenge is on the Go!

    Este é o primeiro dos meus posts únicamente em Inglês. Eu sei que a comunidade é PT, mas também sei que todos sabemos pelo menos ler o Inglês razoavelmente.

    A escrita dos posts só em Inglês tem a ver com a minha necessidade pessoal de praticar o Inglês escrito, e com a falta de tempo para escrever os posts em 2 línguas.

    Aceitam-se comentários e/ou sugestões.

    logo_it

    One of the Imagine Cup competitions I'm participating is the IT Challenge.

    This phrase that captures the meaning of this challenge:

    The IT Invitational highlights the art and science of developing, deploying, and maintaining IT systems that are efficient, functional, robust and secure.

    The challenge goes around most of the IT infrastructure design and management, and students aspiring to be in France for the finals must go through a series of tests.

    The first, is the online quiz (also known as round 1). All competitors go online and answer a 30 question quiz. Only the ones with more than 15 correct answers go to round 2.

    The next, more challenging one is the creation of a case study around a proposed business scenario. You can check the last year's business scenario here.

    The challenge, as expected relies on using Microsoft technologies for accomplishing the final design specification for the case study. However, additional networking and other general IT knowledge is essential to get even through the round 1. For example, in both quizzes I've participated, there was at least one question about CIDR addressing.

    Last year, I've also participated, advanced to round 2, but haven't got the time to create the Case Study.

    You can check last year's finalists proposals through Imagine Cup's website or directly through the following links:

    1st place: China - Zhifeng Chen - Hua Zhong University of Science and Technology

    2nd place: France - Jean-Benoit Paux - INSA de Lyon

    3rd place: France - Romain Larmet - INSA de Lyon

    4th place: Poland - Paul Wojcicki Jarocki - School of Banking and Management in Krakow

    5th place: Romania - Andrei Alexandroni - Politehnica University of Timiosara

    6th place: Romania - Ilie Cosmin Viorel - Alexandru Ioan Cuza University of Iai

     

    The final challenge happens where the finals take place. Armed with all the necessary software and equipment, the finalists have a deadline to implement their proposal. So if you are planning on passing to the 3rd (and final) round of the IT Challenge, don't expect to see much of the City of the lights...

     

    The first quiz for the Imagine Cup IT Challenge happened last Thursday, 27th Dec. According to the stats of one of the members of the organizing team, Portugal ranked 10th in a list with 43 countries. The highest score in Portugal was 19 out of 30 correct answers.

    In this first quiz, we had 6 Portuguese participants, and all of them managed to get through!

     

    Rank Country NickName Score
    92 PT chocolate_jesus 19
    130 PT ricardo-portela 17
    137 PT hfcpereira 16
    144 PT Luis Gomes 16
    148 PT Pedro Quinta 16
    152 PT ajnm 15

     

    As you can see, I am one of the competitors that advanced to round 2. I hope I can find the time to create my Case Study this year.

    Just a little sidenote: As you may know, I am a Microsoft Student Partner. One of the many advantages of being a MSP, is access to some information that is not on the public domain, as well as a MSDN subscription, which in this case can enable us to simulate the scenario, as all the software is available (admitting that one also has the very expensive hardware). Also, we get to know some of the people inside MSFT PT who know a lot about these technologies. That may seem unfair to other contestants, and has been addressed by the IC organization:

    (...)If you are a Microsoft campus representative (such as Microsoft Student Partners http://student-partners.com/) and you meet the eligibility criteria set forth above (Note: see the full rules here), you may enter, but you are prohibited from using Microsoft property or resources, including without limitation, Microsoft networks, hardware tools and technology resources and/or the counsel of Microsoft employees, in connection with the creation or execution of your entry.

    These rules are pretty simple to follow, and this is why some of us (MSPs) are participating in this contest. I think some of us might still participate in the quizzes that follow, but in this list we have at least one more MSP (hfcpereira).

     

    If you are a student and have registered in the IT Challenge, stay tuned for the next quizzes. There are still more chances for you to advance to round 2!

    The next quiz takes place January 9th, at 00:00 GMT.

     

    Good Luck!

  • Introdução AJAX e ASP.NET AJAX + Chamadas a Web Services com ASP.NET AJAX

    Este semestre eu e o meu colega Paulo Vieira do ISEL, preparámos uma apresentação acerca deste tema, no contexto da cadeira de Fundamentos de Sistemas Distribuídos.

    Existiam vários temas à escolha, de entre os quais WCF, mas como este último já tinha sido escolhido, e existia a hipótese de propôr um tema que se enquadrasse, a nossa escolha recaiu sobre este tema.

    Deixo aqui os conteúdos que preparámos para a apresentação, caso seja útil para quem se esteja a iniciar nesta tecnologia, ou queira dar uma apresentação sobre o tema.

    O ficheiro .ZIP contém:

    1. Ficheiro PPTX que contém os slides preparados para a apresentação, em PowerPoint, com comentários.
    2. Ficheiro DOCX que contém um resumo mais detalhado da matéria em estudo. Serve de suporte adicional aos slides.
    3. Solution VS2008 (CodeName Orcas) com o código de exemplo que dá suporte às demos da apresentação.

    Caso identifiquem alguma incorrecção ou observação, deixe em comentário, que terei todo o gosto de discutir o tema.

  • Connection Strings (outra vez...)

    Ainda há dias vi este post do Daniel, e lembrei-me de uma outra forma, porventura mais interessante de obter a connection string.

    Para evitar o suspense e para poupar o tempo de quem já conhece o "truque", cá vai: Ficheiros com a extensão UDL (a.k.a. "Microsoft Data Link").

    Esta funcionalidade existe (pelo menos) nos Windows XP e Vista.

     

    Passos:

    1 - Criar um ficheiro de texto

    shot1

    2 - Mudar a extensão do ficheiro para .udl

    shot2

    3 - Clicar com o botão direito sobre o ficheiro, e ver as respectivas propriedades.

    Aqui já começamos a ver coisas que nos são familiares...

    shot3

    4 - Começamos por escolher o "provider"

    shot4

    5 - De seguida, os passos variam consoante o "provider" seleccionado. Aqui vou ilustrar os passos para o SQL Server, via OLE DB.

    shot5 

    É até possível obter a lista dos servidores disponíveis, assim como das bases de dados existentes num servidor específico (desde que sejam inseridas credenciais válidas para esse mesmo servidor).

    É ainda possível configurar os timeouts através da aba "Advanced".

    Todas as propriedades disponíveis para a ligação são configuráveis através da aba "All".

    6 - De seguida, basta clicar em "Apply" para guardar as definições. Caso estejam a usar SQL Authentication e escreveram a palavra passe, vão receber um aviso, a indicar que a palavra passe fica guarada "em claro".

    7 - Agora, basta abrir o ficheiro em questão (.udl) no bloco de notas, e vão encontrar a connection string, pronta a ser usada:

    shot6

    Boas ligações! 

  • Material do Workshop Windows Forms realizado no ISEC no dia 25 de Abril de 2007-05-07

    No passado dia 25 de Abril de 2007, eu, o Nelson Correia, o Ricardo Calejo e o Simão Pereira realizámos em conjunto um Workshop sobre Windows Forms e Web Forms no ISEC. Eu e o Simão ficámos encarregues da parte de desenvolvimento de aplicações Desktop, e o desenvolvimento Web ficou a cargo do Nelson Correia e do Ricardo Calejo.

    Se quiserem saber mais detalhes do evento, podem seguir o link que se segue:

    http://weblogs.pontonetpt.com/calejo/posts/13907.aspx

    O que me leva a escrever este post é a vontade de disponibilizar os conteúdos que foram de alguma maneira da minha responsabilidade.

    O workshop começou com uma breve introdução acerca da plataforma .NET dada por mim, com muito nervosismo à mistura... (Agora é que começo a dar o verdadeiro valor aos professores...).

    Os slides que utilizei para essa sessão estão disponíveis neste endereço:

    http://pwp.net.ipl.pt/alunos.isel/27394/WorkshopISEC/Slides/dotNetPPT.zip [Versão Power Point 97-2003]

    http://pwp.net.ipl.pt/alunos.isel/27394/WorkshopISEC/Slides/dotNetPPTX.zip [Versão Power Point 2007]

    Quem já teve aulas no ISEL, vai reconhecer alguns, senão a maioria dos slides, já que na maior parte dos casos fiz apenas alterações cosméticas, só tendo criado alguns de raíz. Os slides são de cadeiras como AVE, onde usei os acetatos do Eng. Jorge Martins e CP (Luís Falcão).

    De seguida, cada uma das “turmas” foi para um laboratório diferente, e lá a ideia era criar parte de uma aplicação Windows Forms que seria responsável pela gestão de um sistema de vendas, e dos produtos e clientes associados.

    De forma a simplificar a tarefa dos “alunos”, e como a ideia era desenvolver a utilização de Windows Forms, foi criada uma camada de acesso a dados que seria depois utilizada pela camada de apresentação Windows Forms. Essa camada de acesso a dados foi fornecida (incompleta, infelizmente) aos alunos, que assim poderiam utilizar os dados presentes na BD sem terem de se preocupar com os detalhes de ADO.NET.

    Esta camada foi entretanto terminada, e foram criados alguns testes unitários para efectuar algumas validações. Neste campo ainda existe espaço para progredir, mas o foque da sessão não era esse, e como tal não foi dispensado muito tempo para essa componente.

    Apesar de o acesso a dados não ser um dos temas principais, foi abordada a utilização de código parcialmente independente de provider (utilização do namespace System.Data.Common). A string de ligação à base de dados é carregada a partir do ficheiro App.config, onde reside também a informação acerca do provider de acesso a dados utilizado.

    Outro dos temas que vemos muitas vezes esquecidos em aplicações Desktop é a utilização de threads de background para a execução de tarefas (potencialmente) mais prelongadas, em vez da utilização da thread de User Interface. Este tema foi também abordado e foi apresentado o objecto BackgroundWorker como forma de ajudar o programador a resolver parte dos seus problemas neste aspecto. No código existem 2 formas de utilização deste objecto.

    Ao longo do código foram sendo colocados comentários na medida do possível, e quando achei necessário. No entanto, se surgirem dúvidas, entrem em contacto comigo. Se a questão for pertinente, poderei fazer uma adenda a este post.

    Como em qualquer outro programa, as soluções adoptadas podem não ser as melhores. Se achar que é esse o caso, entre em contacto comigo, que terei todo o gosto em discutir melhores soluções. Note, no entanto, que em certos casos compliquei de propósito para ilustrar específicamente algumas características da plataforma.

    Por exemplo, o código do método mostrarUC no ficheiro “UserInterface.cs” tem 2 soluções disponíveis. Uma que usa introspecção, e outra que usa uma abordagem mais “clássica”.

    Outros exemplos incluem a reutilização de objectos do tipo BackgroundWorker por mais de um tipo de funcionalidade, e a reutilização de Forms.

    A solução que vai incluída no ficheiro ZIP possui 4 projectos. São eles:

    1.       GestãoVendas.BusinessLayer – A camada de negócio
    Neste projecto estão reunidas os tipos que efectuam a transformação do modelo relacional para o modelo Object Oriented da estrutura de dados apresentada.

    2.       GestãoVendas.BusinessLayer.Tests – Os testes unitários da camada de negócio
    Conjunto de testes unitários que servem para efectuar algumas validações de forma automática, e verificar, por exemplo, se uma determinada alteração efectuada numa das classes provoca a quebra do funcionamento de outra que dela dependa.

    3.       GestãoVendas.Presentation.Windows – A camada de apresentação Windows Forms
    O projecto de Windows Forms propriamente dito.

    4.       GestãoVendas.Presentation.Windows.Controls – Custom Controls Windows Forms, que são depois utilizados no projecto anterior.
    A plataforma Windows Forms é extensível, e é possível ao programador criar novos controlos visuais e utilizá-los tal e qual como os que vêm com a plataforma. Neste caso, para ilustração, foi criado um controlo que desenha uma linha horizontal na janela. A posição, cor, espessura e dimensão da linha são configuráveis através do editor de propriedades do Visual Studio, em modo de edição, como esperaríamos de um controlo built-in.

     

    Adicionalmente, a solução foi criada na versão CTP do novo Visual Studio codename “Orcas”, pelo que não será possível abri-la com o Visual Studio 2005. No entanto, os projectos individuais são sompatíveis com o Visual Studio 2005, pelo que basta criar uma Solution em branco e adicionar os projectos existentes.

    Outro pormenor que é importante referir é que o projecto dos testes unitários só é suportado na versão Team System / Team Suite do Visual Studio 2005.

    Se não possuir uma destas últimas, lembro que estas estão disponíveis através do programa MSDNAA, em funcionamento em muitos institutos de ensino superios do país. Outra solução é efectuar o download (grátis) da versão Beta do Visual Studio codename “Orcas”.

    Para quem utiliza o Visual C# Express, e como este não suporta a noção de Solutions, a solução é abrir o projecto, compilar, e fazer referência nos outros projectos ao assembly produzido pelo compilador.

    O projecto pode ser obtido no seguinte URL:

    http://pwp.net.ipl.pt/alunos.isel/27394/WorkshopISEC/GestaoVendas_Orcas.zip

    Em relação à base de dados, existem várias hipóteses. No ficheiro:

    http://pwp.net.ipl.pt/alunos.isel/27394/WorkshopISEC/BaseDados.zip

    Existe um backup da minha BD de testes, e o script de criação. Se desejar, pode restaurar a BD a partir do meu backup. Em alternativa, pode correr o script de criação numa BD chamada “DemoISEC”.

    Qualquer dúvida não hesite em contactar, que dentro da minha disponibilidade terei todo o prazer em responder.

    Outro dos recursos que pode utilizar, são os fóruns do Laboratório .NET do ISEL, que apesar de (ainda) ser pouco movimentado, é frequentado por pessoas que provavelmente poderão ajudar quando a tecnologia envolvida é .NET.

    Relembro que este tipo de acções foi levada a cabo nos (poucos) tempos livres de que dispomos e não devem ser vistas como exemplares, mas como soluções possíveis para um problema. Por exemplo, na base de dados existe uma série de alterações possíveis, nomeadamente ao nível dos tipos de dados, e em alguns casos, certas operações poderiam ser logo resolvidas na BD através de Stored Procedures ou Triggers.

    Finalmente, resta dizer que espero que as pessoas presentes no workshop tenham dado o seu feriado como bem empregue J. Feedback é sempre bem-vindo, uma vez que somos “verdinhos” neste tipo de eventos.

     

    [Cross-posted de http://weblogs.pontonetpt.com/rportela]

  • Série de Posts acerca do novo IIS 7.0

    Fiquei curioso sobre este tema, porque durante o último TechDays tive a oportunidade de assistir a uma apresentação acerca das novas novidades no IIS7, dada pelo Nuno Silva, da Microsoft, intitulada IIS 7.0 para Programadores.

    À medida que for tendo disponibilidade, vou introduzir alguns conceitos neste novo servidor da Microsoft, que vem integrado com o Windows Vista, e que virá também com o Windows Codename "Longhorn".

    Este é um tema interessante para quem, como eu desenvolve aplicações Web, porque mais cedo ou mais tarde este vai ser o servidor utilizado para servir os conteúdos das suas aplicações.

    welcome.jpg

  • IIS 7.0 - Arquitectura

    Nas versões anteriores do IIS, era possível adicionar funcionalidades ao servidor através da implementação de extensões ISAPI.
    Estas extensões eram de difícil implementação devido ao modelo de extensibilidade utilizado (e para além disso, para quem, como eu já não sabe viver sem o “conforto” dos ambientes virtuais de execução, é uma API unmanaged...).
    Não vou entrar muito em pormenor acerca do funcionamento do modelo antigo, até porque já é um assunto bem documentado. Ainda assim, para quem quiser ficar com uma ideia, vou incluir em attachment o material de apoio que usei numa apresentação que dei sobre ASP.NET no Evento Ready For TechDays, em Vila Real, onde abordei esta questão, se bem que muito por alto, devido a restrições de agenda.
    No novo modelo, a plataforma ASP.NET é integrada no IIS, e não está dependente de nenhuma extensão ISAPI, como acontecia no modelo anterior. Nesta nova versão, a arquitectura do servidor passou (de grosso modo) por duas fases:

    1. Desenho de um servidor genérico e extensível
    2. Implementação das funcionalidades que todos conhecemos do IIS (e mais algumas...) sobre essa plataforma, utilizando a mesma interface que os programadores vão usar quando realizarem os seus próprios módulos

    Para a plataforma de extensibilidade, foram criadas duas APIs distintas, uma managed e outra unmanaged, que no fundo oferecem as mesmas funcionalidades, para que os programadores possam usar a que mais lhes convém.
    Um exemplo das diferenças provocadas por estas alterações é o caso das configuração de handlers HTTP: No modelo anterior, caso desejássemos configurar um handler ASP.NET para atender um determinado tipo de pedido (baseado na extensão e verbos HTTP) teríamos primeiro de configurar o IIS para encaminhar esse tipo de pedidos para a extensão ISAPI de ASP.NET (aspnet_isapi.dll) e depois era ainda necessário efectuar alterações ao ficheiro web.config da aplicação web (ou o ficheiro web.config geral [existente em %windir%\Microsoft.NET\Framework\v2.0.50727], caso desejássemos que o handler estivesse disponível em todas as aplicações do servidor em questão).
    No novo modelo, basta registar o handler no IIS.
    No handler, pode ser usado o mesmo código que seria utilizado na versão anterior do pipeline, uma vez que a interface que deve ser implementada manteve-se.
    Se for utilizada a consola em modo gráfico do IIS, são até apresentados os tipos que implementam a interface IHTTPHandler numa drop down, de forma a facilitar o trabalho do administrador.

    addmh.png

    Para efeitos de retro-compatibilidade, os dois modos estão disponíveis no IIS7:

    Application Pools2.jpg

    Quando associamos uma aplicação web à application pool “Classic .NET AppPool”, estamos a utilizar o modelo anterior, em que os pedidos passam pela extensão ISAPI antes de chegar ao pipeline ASP.NET.
    A outra hipótese é criar uma application pool com o modo de pipeline integrado, introduzido nesta versão do IIS, onde podemos agrupar as aplicações Web que desejarmos.
    Cada application pool está associado a uma instância do worker process, ou seja, quando temos várias aplicações Web no mesmo application pool, estas estão a ser executadas no mesmo worker process. O encaminhamento do pedido para o worker process correcto é feito pelo serviço W3SVC. É este serviço que fica responsável por criar uma nova instância do worker process se necessário.

    iisSVC.jpg

    Por agora vou ficar por aqui, porque amanhã é dia de rumar para a UBI, na Covilhã, onde eu e o Nelson Correia vamos fazer uma apresentação, e ainda tenho algumas coisas para preparar. Ele vai falar sobre ASP.NET AJAX e eu sobre ASP.NET.

  • Primeiro Post

    O meu nome é Ricardo Portela, estudo no ISEL, onde estou no 8º semestre da Licenciatura em Engenharia Informática e de Computadores.

    Durante este ano tenho a felicidade de pertencer a um grupo extraordinário de pessoas, o grupo dos Microsoft Student Partners.

    Para além disso, sou membro do Centro de Cálculo do ISEL.

    Uma das estratégias que costumo seguir para interiorizar melhor as coisas é escrever sobre elas. Assim, vou usar este blog para fazer alguns posts acerca de temas que for achando interessantes, e assim, para além de estudar a plataforma, partilho o que vou aprendendo com a comunidade. Outra vantagem é que se interpretar algo mal, ou me falhe algum pormenor, existe sempre a possibilidade de receber o vosso feedback.