web 2.0

Lessons Learned: XMLWriter correct HTML elements laten sluiten

Vandaag had ik ruzie met het maken van HTML op basis van XML met een XSL stylesheet. De XMLTextWriter zorgde er voor dat lege HTML elements afgesloten werden als XML elementen. Een div werd als <div/> afgesloten inplaats van <div></div> dit zorgde voor slechte HTML en daardoor pagina's die er niet uitzagen. Het probleem zat in de XMLTextwriter van .Net. Deze heeft een setting OutputMethod die standaard op XML staat waardoor de elementen self closing zijn. Deze OutputMethod moet gezet worden op HTML, deze setting is echter internal en daardoor niet te wijzigen. 

De oplossing hievoor moet gezocht worden in het gebruiken van de settings die gezet worden in de XSL. 

In de XSL specificeer je de output methode

 

<xsl:output method="html" indent="yes" omit-xml-declaration="yes" />

 

In de code kunnen deze settings vervolgens weer overgenomen worden

 

XslCompiledTransform transformer = new XslCompiledTransform();
transformer.Load(xslFile);
XmlDocument xdoc = new XmlDocument();
xdoc.LoadXml(xmlContent);
//Hier worden settings voor de HTML output methode overgenomen
XmlTextWriter xtw = XmlWriter.Create(htmlFile, transformer.OutputSettings);
transformer.Transform(xdoc.CreateNavigator(), xtw);

 

Met dank aan tek-tips.

Lessons Learned: XML processing instruction toevoegen via XSL

Vandaag moest ik via een XSL template een XML processing instruction toevoegen. Dit werkte niet om het "gewoon" als inhoud van een template toe te voegen, dit moest via een <xsl:processing-instruction>

 

Gewenste situatie

 

<element>
<!-- hier moest een processing instruction komen, 
in dit geval voor het einde van een pagina -->
<?xpp ep?>
</element>

 

 

Template:

 

<xsl:template match="pagebreak">
  <xsl:processing-instruction name="xpp">ep</xsl:processing-instruction>
</xsl:template>

 

En andersom

 

<xsl:template match="processing-instruction('xpp')[.='ep']">
      <pagebreak/>
  </xsl:template>

Lessons Learned: configuratie aanpassen aan deployment

UPDATE: Er is een mooie extensie voor die het ng allemaal veel makkelijker maakt de Slow Cheetah

Binnen Visual Studio had ik de bestanden web.debug.config en web.release.config al eens zien staan maar er nooit echt wat mee gedaan. Dat was ook niet eerder nodig aangezien de deployment altijd door andere partijen werd gedaan. Dit maal moest ik echter zelf de web.config files opleveren en ben ik mij gaan verdiepen in het aanpassen van de config files op basis van de omgeving waar naar toe gepubliceerd zal worden. 

De basis blijft de "normale" web.config file en eigenlijk ga je vervolgens de afwijkingen per omgeving in de betreffende files vastleggen. Beste voorbeeld, de connectionstring naar de database. 

Standaard web.config

 

<connectionStrings>
    <add name="ApplicationServices" connectionString="Data Source=localhost;
       Initial Catalog=DatabaseNaam;User Id=User;Password=Password" />
  </connectionStrings>
 

 

Voor de release omgeving (web.release.config)

 

<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
<connectionStrings>     <add name="ApplicationServices" connectionString="Data Source=NIEUWE_SERVER;
    Initial Catalog=DatabaseNaam;User Id=User;Password=Password" xdt:Transform="SetAttributes" xdt:Locator="Match(name)/>
</connectionStrings>
 

 

De namespace  xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform" wordt toegevoegd zodat de verschillende commando's gebruikt/herkend kunnen worden. De belangrijkste hiervan zijn:

  • Locator="Match(name)" deze wordt gebruikt om te herkennen welk element aangepast moet worden indien er meerdere elementen van hetzelfde type zijn. Het attribuut wat gebruikt moet worden voor de identificatie staat bij de match, in dit geval het attribute name. 
  • Transform dit commando zorgt voor de daadwerkelijke transformatie en heeft een aantal mogelijke waardes
    • SetAttributes voor het zetten van de attributen gespecificeerd in de web.release.config naar de nieuwe web.config
    • Remove voor het verwijderen van het element
    • RemoveAttributes(attribuut naam) voor het verwijderen van bepaalde attributen bijvoorbeeld het debug attribuut op de compilation
    • Insert voor het toevoegen van een element
    • Voor de overige commando's zie de Microsoft link

 

 

Niet alle configuratie items staan altijd in de web.config, soms staan deze ook in andere config bestanden zoals bijvoorbeeld de configuratie van de logging middels log4net. Deze heeft een eigen configuatie maar die wil ik ook wel aan kunnen passen middels deze techniek. Hiervoor moet een stukje code aan de csproj file toegevoegd worden om dit mogelijk te maken. 

 

<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
  <Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v10.0\WebApplications\Microsoft.WebApplication.targets" />
    <Target Name="AfterCompile" Condition="exists('log4net.$(Configuration).config')">
      <TransformXml Source="log4net.config"
        Destination="$(IntermediateOutputPath)$(TargetFileName).config"
        Transform="log4net.$(Configuration).config" />
      <ItemGroup>
        <AppConfigWithTargetPath Remove="log4net.config"/>
        <AppConfigWithTargetPath Include="$(IntermediateOutputPath)$(TargetFileName).config">
          <TargetPath>$(TargetFileName).config</TargetPath>
        </AppConfigWithTargetPath>
      </ItemGroup>
    </Target>
 

 

Nu worden beide config files aangepast aan de configuratie die ik kies. Standaard zijn de debug en release, maar er kunnen er natuurlijk nog veel meer toegevoegd worden. Nu hoef ik mijn configuratie alleen nog maar op de juiste omgeving te zetten en publish te kiezen voor het web project en mijn config zal juist gegenereerd worden en eventuele nieuwe keys die ik toegevoegd had in mijn eigen config worden automatisch meegenomen. 

 

Meer informatie:

 

IIS App pool user toegang geven tot SQL Server

Om een IIS gebruiker toegang te geven tot een SQL server database kan het volgende SQL statement gebruikt worden. 

 

CREATE LOGIN [IIS APPPOOL\My Pool] 
FROM WINDOWS WITH DEFAULT_DATABASE=[master] 
USE [database] 
CREATE USER [IIS APPPOOL\My Pool] 
FOR LOGIN [IIS APPPOOL\My Pool]

 

ASP.net mailen testen zonder SMTP

Een collega kwam met deze tip voor het testen van mail functionaliteit vanuit een .Net applicatie zonder dat je beschikking hebt tot een SMTP server of dat je gewoon niet wilt dat de mailtjes verstuurd worden.

De mailtjes worden dan opgeslagen in een folder waar IIS wel lees en schrijfrechten moet hebben.

Hieronder de volledige uitleg.

http://www.devcurry.com/2011/03/test-emails-in-aspnet-without-mail.html

Alleen overeenkomstige items selecteren met LINQ

Aangezien ik op het internet (nog) geen goed voorbeeld kon vinden hoe ik onderstaande situatie op kon lossen met LINQ heb ik er zelf maar even een stukje over geschreven wie weet help ik er iemand anders nog mee. 

De situatie is als volgt, ik heb een verzameling items en daaruit wil ik een lijst met bepaalde eigenschappen hebben. Echter dit is na filtering op meerdere waarden van een andere eigenschap en dan wil ik alleen de waardes hebben waarvoor beide filters gelden.

Voorbeeld:

 

* +=======================================+
* +SEGMENT + Periode begin + Periode eind +
* +=======================================+
* + A      + 1-1-2007      + 31-12-2007   + 
* + A      + 1-1-2008      + 31-12-2008   + 
* + A      + 1-1-2009      + 31-12-2008   +
* + B      + 1-1-2008      + 31-12-2008   +
* + B      + 1-1-2009      + 31-12-2009   +
* + B      + 1-1-2010      + 31-12-2010   +
* + C      + 1-1-2008      + 31-12-2008   +
* + C      + 1-1-2009      + 31-12-2009   +
* +=======================================+

Als nu A geselecteerd is, is het resultaat 1-1-2007, 1-1-2008 en 1-1-2009
Als nu B geselecteerd is, is het resultaat 1-1-2008, 1-1-2009 en 1-1-2010
Maar als nu A en B geselecteerd zijn is het resultaat 1-1-2008 en 1-1-2009

In LINQ kan dit nu als volgt
var selection = (from i in items
    group i.Segment by new {i.PeriodeBegin, i.PeriodeEind}
       into igroup 
       where igroup.Distinct().Count() ==
             (from s in items select s.Segment).Distinct().Count()
    select new {
                      igroup .Key.sPeriodeBegin,
                      igroup .Key.PeriodeEind
                    }
      ).Distinct().ToList();

 

 

Wie weet is er iemand anders nog mee geholpen

Linkedin en Greetz werkten niet

Sinds we verhuisd zijn had ik een heel raar probleem met sommige websites. Ik kon bij Greetz geen kaarten meer versturen en afgezien van de homepage werkte op Linkedin ook bijna  niets meer. Andere sites leken het goed te doen in ieder geval daar had ik geen problemen.

Standaard oplossingen als opnieuw opstarten, andere browser (ik had dit probleem in IE, firefox en Chrome), browser opnieuw installeren hadden allemaal geen effect. Zelfs firewall en anti virus uit hadden geen effect.

Via posts zoals deze kwam ik ook op het idee om mijn MTU settings te veranderen. Onder XP kan dat gemakkelijk met deze tool. Gebruik hiervan is op eigen risico maar bij mij heeft het gewerkt om mijn MTU te verlagen naar circa 1400.

Zoals ik het begrijp wat je MTU doet is eigenlijk aangeven hoe groot de deur is waardoor je het internet naar binnen laat komen. Een berichtje moet in dergelijke kleine stukjes gehakt worden anders past het niet door de deur. Waarom dat ik dat nu ineens aan moest passen geen idee, maar het werkte wel. Voor mensen die iets meer info willen over MTU hier een wikipedia artikel.

Wonen in de regenboog?

 Morgen is het zover, we gaan praten over een nieuwe woning met de projectontwikkelaar. Wie weet gaan we in de toekomst wonen in de regenboog (naast de pot met goud). Dat schijnt terug te komen in de voordeur en als de kleuren kloppen die we gezien hebben krijgen we de meest lelijke kleur die ze hebben maar wel het leukste huis. Althans dat vinden we zelf natuurlijk Cool. Hieronder is een impressie van het project te zien wat gelegen is in de leuke wijk Fascinatio. Om een idee te krijgen hoe de wijk in elkaar zit en wat gevolgen zijn van uitbouwen en opbouwen heb ik met Google Sketchup de hele wijk nagetekend en daar vervolgens een indruk gekregen hoe het werkt met de schaduw in de verschillende maanden. Dat is echt een fantastisch programma en ik kan het iedereen aanbevelen om je eigen huis en de buurt eens te tekenen. Ik heb me nu beperkt tot de buitenkant, binnenkort ga ik de binnenkant tekenen om  eens te zien wat een leuke keuken indeling is, met een kookeiland of zonder en of de afzuigkap voor het raam heel storend is of niet. Hopelijk later meer over de voortgang van ons nieuwe huis project.

Wonen op maat

Bij nieuwbouw woningen heb je over het algemeen een beperkt aantal keuzes om je toekomstige woning aan je wensen aan te passen. Het zogenaamde meer en minder werk.

Nu ben ik vandaag een nieuw concept tegen gekomen (wat ongetwijffeld al langer bestaat maar ik wist het gewoon niet). Dat nieuwe concept noemen ze wenswonen. Hierbij krijgt de potentiële koper een CD-Rom waarbij hij de kavel uit kan zoeken om vervolgens zijn droomhuis uit een aantal bouwstenen samen te stellen. het begint bij de vorm van het huis, maar gaat door naar inrichting, aantal ramen vorm van de deur, kleur van de baksteen noem maar op en je ziet meteen wat de kosten van je droomhuis wordt.

Dus misschien toch niet die uitbouw op zolder maar liever een grotere badkamer. Op deze site zie je een voorbeeld van wat er mogelijk is. Zelf heb ik een CD-Rom aangevraagd voor een ander project, ik ben benieuwd wat er nog mogelijk is en of ik mijn eigen droomhuis kan samenstellen.