Navigatie

Contact

Send mail to the author(s) E-mail

View Richard Soeteman's profile on LinkedIn

RSS 2.0 | Atom 1.0 | CDF

Archief

Categorieën

Blogroll

Disclaimer
The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.

Sign In

Zoeken

# Sunday, 22 February 2009
Sunday, 22 February 2009 10:38:11 (GMT Standard Time, UTC+00:00) ( ASP.NET | Umbraco )

This Blog is not active anymore, further posts will be available on my company website. Read new posts here

Yesterday I gave a demo about events in Umbraco V4. I did this by describing a few "Business problems" that could be solved using events. A few facts about events in Umbraco V4:

  • You find events on every Component in Umbraco.
  • To uses events, you need references to the businesslogic, cms and interfaces assemlies.
  • To use events, you have to create a class that uses umbraco.BusinessLogic.ApplicationBase as the base class.  In the constructor you can wire up the event handler. These classes will be automaticly picked up when you put the file in the App_Code folder of Umbraco or put the compiled DLL in the bin folder of Umbraco. I prefer the last one.
  • Most of the event args derive from CancelEventArgs, so we can cancel the operation.
  • Because an event executes in the background you should always document that you're using events and make sure you will write a logmessage when you're event handler gets executed.

For my demo's, I've used an Umbraco V4 installation with the Creative Website Wizard installed.

Demo 1 Auto Expire news

In the first demo.I've showed how the document.BeforePublish can be used to check if  a news item is allready expired, if so cancel the publish event, otherwise check if the expire date is set and if not, set the expire date to 14 days from now.

   1:  using System;
   2:  using System.Collections.Generic;
   3:  using System.Text;
   4:  using umbraco.BusinessLogic;
   5:  using umbraco.cms.businesslogic.web;
   6:   
   7:  namespace AutoExpire
   8:  {
   9:      /// <summary>
  10:      /// 
  11:      /// </summary>
  12:      public class Expire :ApplicationBase
  13:      {
  14:          /// <summary>
  15:          /// Constructor used to wire up the event
  16:          /// </summary>
  17:          public Expire()
  18:          {
  19:              Document.BeforePublish += new Document.PublishEventHandler(Document_BeforePublish);
  20:          }
  21:   
  22:          /// <summary>
  23:          /// Check if the news item is expired, or check if we need to set the expire date
  24:          /// </summary>
  25:          void Document_BeforePublish(Document sender, umbraco.cms.businesslogic.PublishEventArgs e)
  26:          {
  27:              //Always LOG
  28:              Log.Add(LogTypes.Custom, sender.Id, "Event raised");
  29:              //Check if the doctype is news
  30:              if (sender.ContentType.Alias == "News")
  31:              {
  32:                  //Check if the expiredate is filled and the value is not allready expired
  33:                  if (sender.ExpireDate != DateTime.MinValue && sender.ExpireDate < DateTime.Now)
  34:                  {
  35:                      //Item is expired, cancel the publish
  36:                      e.Cancel = true;
  37:                  }
  38:                  else
  39:                  {
  40:                      //Date is not set set it now and save the doc. Probably better to to this in the before save event
  41:                      //since this is a demo it's allowed to do it here
  42:                      sender.ExpireDate = DateTime.Now.AddDays(14);
  43:                      sender.Save();
  44:   
  45:                  }
  46:              }
  47:          }
  48:      }
  49:  }

During this demo someone asked if it's possible to show a custom message in the speechbubble event when an event is canceled. This is not possible (tested it this morning), I've created an item on CodePlex.

Demo 2 Auto archive news

In this Demo I've created some functionality to automaticly move a news item to the archive folder when a content manager sets the archive boolean to true. First an archive boolean must be added to the news document and a new Archive folder must be created where we can store the archived News items in.

   1:  using umbraco.BusinessLogic;
   2:  using umbraco.cms.businesslogic.web;
   3:   
   4:  namespace AutoMoveToArchive
   5:  {
   6:      /// <summary>
   7:      /// Auto move demo
   8:      /// </summary>
   9:      public class AutoMoveToArchive : ApplicationBase
  10:      {
  11:          /// <summary>
  12:          /// Wire up the event handler
  13:          /// </summary>
  14:          public AutoMoveToArchive()
  15:          {
  16:              Document.BeforeSave += new Document.SaveEventHandler(Document_BeforeSave);
  17:          }
  18:   
  19:          /// <summary>
  20:          /// Before a documents get saved we wil check if the archived proerty is.
  21:          /// When it's set move it to the archive folder.
  22:          /// Again it;s demo code, normally you should also check if it's not allready IN the archived foder ;-)
  23:          /// </summary>
  24:          void Document_BeforeSave(Document sender, umbraco.cms.businesslogic.SaveEventArgs e)
  25:          {
  26:              // Set Arrchive folder id, no excuse to use hard coded values in Umbraco ;-)
  27:              int archiveId = 1123; 
  28:              //Log that we are doing something
  29:              Log.Add(LogTypes.Custom, sender.Id, "Document After save Raised");
  30:   
  31:              //Check if the item is news and must be archived
  32:              if (sender.ContentType.Alias == "News" && sender.getProperty("archived").Value.Equals(1))
  33:              {
  34:                  //Yes, move to archive
  35:                  sender.Move(archiveId);
  36:   
  37:                  //Unpublish from current Node
  38:                  umbraco.library.UnPublishSingleNode(sender.Id);
  39:                  sender.UnPublish();
  40:                  //Publish will get called if the user selected Save and publish
  41:              }
  42:          }
  43:      }
  44:  }

Demo 3 Add Unpublish menu Item to the Context menu

In this demo I've showed that we can use events to modify the context menu. I'm missing a unpublish item  in the context menu. This example is a little bit harder because we we need to create a menu item also. A menu item can be created to create a class that derives from the IAction interface. I will leave the explanation of this interface for a future blogpost.

   1:  using System;
   2:  using umbraco.BusinessLogic;
   3:  using umbraco.cms.presentation.Trees;
   4:  using umbraco.interfaces;
   5:   
   6:  namespace UnpublishAction
   7:  {
   8:      /// <summary>
   9:      /// Add unpublish to the menu item
  10:      /// </summary>
  11:      public class AddUnpublishActionEvent :ApplicationBase
  12:      {
  13:          public AddUnpublishActionEvent()
  14:          {
  15:              BaseContentTree.BeforeNodeRender += new BaseTree.BeforeNodeRenderEventHandler(BaseTree_BeforeNodeRender);
  16:          }
  17:   
  18:          /// <summary>
  19:          /// Before a menu item gets rendered  we will add the unpublish action if the document is published
  20:          /// </summary>
  21:          private void BaseTree_BeforeNodeRender(ref XmlTree sender, ref XmlTreeNode node, EventArgs e)
  22:          {
  23:              ///Only unpublish when published
  24:              if (node.Menu!= null && !node.NotPublished.GetValueOrDefault(true))
  25:              {
  26:                  //Find the publish action and add 1 for the index, so the position of the ubpublish  is direct after the publish menu item
  27:                  int index = node.Menu.FindIndex(delegate(IAction a) { return a.Alias == "publish"; })+1;
  28:   
  29:                  //Insert unpublish action
  30:                  node.Menu.Insert(index, UnpublishAction.Instance);
  31:              }
  32:          }
  33:      }
  34:  }

Download the complete solution for this demo here.

Demo 4 Invisible for Writer Usertype

In the last demo I've showed how to use the AfterNodeRender event to make protected nodes invisble for the Writer UserType

   1:  using System;
   2:  using umbraco.BusinessLogic;
   3:  using umbraco.cms.presentation.Trees;
   4:   
   5:  namespace OnlyForAdmins
   6:  {
   7:      /// <summary>
   8:      /// Makes a document invisible for writers
   9:      /// </summary>
  10:      public class MenuIsNotForWriters : ApplicationBase
  11:      {
  12:          /// <summary>
  13:          /// Wire up the event handler
  14:          /// </summary>
  15:          public MenuIsNotForWriters()
  16:          {
  17:              BaseContentTree.AfterNodeRender += new BaseTree.AfterNodeRenderEventHandler(BaseContentTree_AfterNodeRender);
  18:          }
  19:   
  20:          /// <summary>
  21:          /// Removes node from menu tree if page is protected and the user is a writer
  22:          /// </summary>
  23:          void BaseContentTree_AfterNodeRender(ref XmlTree sender, ref XmlTreeNode node, EventArgs e)
  24:          {
  25:              //check if page is protecetd and the usertype is writer
  26:              if (node.IsProtected.GetValueOrDefault(false) && umbraco.helper.GetCurrentUmbracoUser().UserType.Alias == "writer")
  27:              {
  28:                  //Writers cannot see protected pages
  29:                  sender.Remove(node);
  30:              }
  31:          }
  32:      }
  33:  }

Overview of all Events

Class Events
Access  
 

BeforeSave
AfterSave
BeforeAddProtection
AfterAddProtection
BeforeRemoveProtection
AfterRemoveProtection
BeforeAddMemberShipRoleToDocument AfterAddMemberShipRoleToDocument BeforeRemoveMemberShipRoleToDocument AfterRemoveMemberShipRoleToDocument BeforeRemoveMembershipUserFromDocument AfterRemoveMembershipUserFromDocument BeforeAddMembershipUserToDocument AfterAddMembershipUserToDocument

BaseTree  
 

BeforeNodeRender
AfterNodeRender

CMSNode  
 

BeforeSave
AfterSave
AfterNew
BeforeDelete
AfterDelete
BeforeMove
AfterMove

content  
 

BeforeUpdateDocumentCache
AfterUpdateDocumentCache
BeforeClearDocumentCache
AfterClearDocumentCache
BeforeRefreshContent
AfterRefreshContent

CreatedPackage  
 

BeforeSave
AfterSave
New
BeforeDelete
AfterDelete
BeforePublish
AfterPublish

DataType  
 

Saving
New
Deleting

Dictionary  
 

Saving
New
Deleting

Document  
 

BeforeSave 
AfterSave 
New 
BeforeDelete 
AfterDelete 
BeforePublish 
AfterPublish 
BeforeSendToPublish 
AfterSendToPublish 
BeforeUnPublish 
AfterUnPublish 
BeforeCopy 
AfterCopy 
BeforeRollBack 
AfterRollBack 
BeforeAddToIndex 
AfterAddToIndex

DocumentType  
 

BeforeSave
AfterSave
New
BeforeDelete
AfterDelete

Domain  
 

BeforeSave
AfterSave
New
BeforeDelete
AfterDelete

InstalledPackage  
 

BeforeSave
AfterSave
New
BeforeDelete
AfterDelete

Language  
 

BeforeSave
AfterSave
New
BeforeDelete
AfterDelete

Macro  
 

BeforeSave
AfterSave
New
BeforeDelete
AfterDelete

Media  
 

BeforeSave
AfterSave
New
BeforeDelete
AfterDelete

MediaType  
 

BeforeSave
AfterSave
New
BeforeDelete
AfterDelete

Member  
 

BeforeSave
AfterSave
New
BeforeAddGroup
AfterAddGroup
BeforeRemoveGroup
AfterRemoveGroup
BeforeAddToCache
AfterAddToCache
BeforeDelete
AfterDelete

MemberGroup  
 

BeforeSave
AfterSave
New
BeforeDelete
AfterDelete

MemberType  
 

BeforeSave
AfterSave
New
BeforeDelete
AfterDelete

StyleSheet  
 

BeforeSave
AfterSave
New
BeforeDelete
AfterDelete

StylesheetProperty  
 

BeforeSave
AfterSave
New
BeforeDelete
AfterDelete

Template  
 

BeforeSave
AfterSave
New
BeforeDelete
AfterDelete

User  
 

Saving
New
Disabling
Deleting
FlushingFromCache
BeforeSave
AfterSave
New
BeforeDelete
AfterDelete
BeforePublish
AfterPublish

Comments [6] | | # 
# Monday, 02 July 2007
Monday, 02 July 2007 08:23:29 (GMT Daylight Time, UTC+01:00) ( ASP.NET )

This Blog is not active anymore, further posts will be available on my company website. Read new posts here

Cheat sheets zijn echt handige hulpmiddelen om snel je informatie te vinden. Voor de ASP.Net AJAX Library zijn o.a. de volgende cheat sheets beschikbaar:

 

Comments [0] | | # 
# Thursday, 02 November 2006
Thursday, 02 November 2006 07:18:49 (GMT Standard Time, UTC+00:00) ( ASP.NET )

This Blog is not active anymore, further posts will be available on my company website. Read new posts here

Vorig jaar heb ik het al eens heel kort gehad over het vernieuwde compilatie en deployment model. Dit onderwerp is echter zeer uitgebreid. Rick Strahl heeft hier een zeer uitgebreid artikel over geschreven. Rick Strahl is tevens de maker van de tool die ik destijds genoemd had. Dit artikel is een must read.

Link naar het het artikel.

Comments [0] | | # 
# Tuesday, 31 October 2006
Tuesday, 31 October 2006 21:21:21 (GMT Standard Time, UTC+00:00) ( ASP.NET )

This Blog is not active anymore, further posts will be available on my company website. Read new posts here

Inmiddels is het al weer bijna twee weken geleden dat Microsoft ASP.NET Ajax Beta heeft released. Het project waar ik aan werk maakte gebruik van ATLAS en de upgrade van een CTP kostte ons slechts enkele minuten.  De upgrade van ATLAS naar Ajax .Net ging echter niet zo simpel. Dit heeft me overigens wel verbaasd heeft omdat de CTP releases erg goed waren, een gemiste kans.  Lees dit migratiedocument en let bij een upgrade op het onderstaande:

Configuratie:

De configuratie in web.config is compleet veranderd. Appendix "Manual Configuration Changes" beschrijft hoe je je huidige web.config kan aanpassen.

Aanpassing van tagprefix:

Verder is de Prefix <ATLAS:/> veranderd in <ASP:/>. Dit houdt in dat je al je verwijzingen dus kan aanpassen.  

Deployment:

Voorheen werd een losse DLL geleverd. Deze kon je in je bin folder plaatsen en je had direct ATLAS functionaliteit. In de huidige versie wordt de DLL in de GAC geplaatst. Wanneer je een deployment naar een server waar de installatie niet is uitgevoerd, bijvoorbeeld een hosting provider kom je in de problemen omdat de Microsoft.Web.Extensions DLL niet gevonden wordt. Je krijgt onderstaande foutmelding te zien:

Could not load file or assembly 'Microsoft.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' or one of its dependencies. The system cannot find the file specified.

De Microsoft.Web.Extensions DLL is echter wel gemakkelijk uit de GAC te halen. Je zult dit echter via de Command Line moeten doen, omdat windows explorer de Assembly folder anders weergeeft dan normale folders en de DLL's dus niet te kopiëren zijn.

  1. CMD
  2. CD c:\windows\assembly\Gac_msil\microsoft.web.extensions\1.*
  3. copy microsoft.web.extensions.dll [type hier de binfolder waar de dll geplaatst moet worden]

Meer Info

Deze post beschrijft alleen de punten die we zelf tegengekomen zijn tijdens de migratie van ons project. We zijn nog een probleem tegen aangelopen met HTTPModules waarover later meer. Voor meer informatie zie de volgende resources:

Comments [2] | | # 
# Thursday, 17 August 2006
Thursday, 17 August 2006 20:38:57 (GMT Daylight Time, UTC+01:00) ( ASP.NET )

This Blog is not active anymore, further posts will be available on my company website. Read new posts here

De bekende ASP.NET Page lifecycle poster gemaakt door Léon Andrianarivony. Aangezien de link naar zijn site niet meer werkt heb ik besloten hem op mijn eigen weblog te plaatsen.



Download de poster op ware grootte

Comments [1] | | # 
# Sunday, 13 August 2006
Sunday, 13 August 2006 14:15:38 (GMT Daylight Time, UTC+01:00) ( ASP.NET | C# )

This Blog is not active anymore, further posts will be available on my company website. Read new posts here

Afgelopen week wilde ik het standaard Xml Control wilde gebruiken, echter was het niet mogelijk XSLT direct als String door te geven, wat voor mijn toepassing wel nodig was. Voor de rest doet het Xml Control exact wat ik wil, dus uitbreiden maar.

Allereerst maken we een nieuwe klasse aan welke erft van System.Web.UI.WebControls.Xml. 
public class XmlExtender : System.Web.UI.WebControls.Xml

Op dit punt kunnen we exact hetzelfde dat het Xml Control kan. Vervolgens maken we een extra property TransformContent.

public string TransformContent
{
  set
  {
    XslTransform xslTrans = new XslTransform();
    xslTrans.Load(XmlReader.Create(new StringReader(value)));
    this.Transform = xslTrans;
  }
}

De naam is zorgvuldig gekozen, er bestaat reeds een property DocumentContent welke xml als string verwacht. TransformContent creeert een xslTransformer en leest de string in. Vervolgens geef ik de de xslTransformer aan Property Transform van het Xml control en heb ik exact de functionaliteit die ik wil hebben. Simpel maar doeltreffend.

Nu kunnen we het control gebruiken in een webapplicatie. Voor het testen van het control heb ik een  demo site ontwikkeld wat een kleine lijst met boeken toont. 

In default.aspx registreren we ons control

<%@ Register Assembly="XmlControlExtender" Namespace="ControlExtenders" TagPrefix="ext" %>

Vervolgens plaatsen we het control op de pagina.

<ext:XmlExtender ID="xmlDemo" runat="server" />

In ons codebehind geven we de documentContent en de Transformcontent mee.

xmlDemo.DocumentContent = GetXml();
xmlDemo.TransformContent = GetXslt();

GetXml geeft het xml document als string terug.

private string GetXml()
{
     StringBuilder s = new StringBuilder();
     s.Append("<?xml version=\"1.0\" encoding=\"utf-8\" ?>");
     s.Append("<books>");
     s.Append("<book><title>Programming .Net Components</title><author>Juval L&#246;wy</author></book>");
     s.Append("<book><title>.Net 2.0 Generics</title><author>Tod Golding</author></book>");
     s.Append("<book><title>Head First Design Patterns</title><author>Freeman &amp; Freeman</author></book>");
     s.Append("</books>");
     return s.ToString();
}

GetXslt geeft de xslt als string terug.

private string GetXslt()
{
   StringBuilder s = new StringBuilder();
   s.Append("<?xml version=\"1.0\" encoding=\"utf-8\"?><xsl:stylesheet version=\"1.0\"  xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\">");
   s.Append("<xsl:template match=\"/books\">");
   s.Append("<html><body>");
   s.Append("<xsl:for-each select=\"book\">");
   s.Append("Titel: <xsl:value-of select=\"title\"/><br/>");
   s.Append("Auteur: <xsl:value-of select=\"author\"/><br/><br/>");
   s.Append("</xsl:for-each>");
   s.Append("</body></html>");
   s.Append("</xsl:template>");
   s.Append("</xsl:stylesheet> ");
   return s.ToString();
}

Na het starten van de webapplicatie wordt het XML document netjes opgemaakt door de opgegeven stylesheet.

Met deze blogpost hoop ik aangetoond te hebben dat standaard Webcontrols zich makkelijk laten uitbreiden en moedig een ieder zeker aan dit ook eens te doen. 

XmlControlExtender is vrij te gebruiken in je eigen applicatie. Download de Sourcecode inclusief demo of alleen het control.

Comments [0] | | # 
# Friday, 11 August 2006
Friday, 11 August 2006 22:25:39 (GMT Daylight Time, UTC+01:00) ( ASP.NET )

This Blog is not active anymore, further posts will be available on my company website. Read new posts here

Onlangs heb ik een project moeten migreren van .Net 1.1 naar .Net 2.0. Vele warnings kreeg ik omdat klassen obsolete waren. Vandaag had ik het Xml Webcontrol nodig en wilde daar dynamisch xslt aan meegeven. Hiervoor had ik de Transform property nodig, welke een XslTransform object verwacht. Hey was deze niet obsolete? Raar dat je tijdens een migratie eerst alle obsolete klassen moet vervangen en dan vervolgens  bij de eerstvolgende toevoeging weer een obsolete klasse moet gebruiken. Ik weet wel dat de warnings te omzeilen zijn maar ik vind het niet netjes van Microsoft ze hier geen aandacht aan hebben geschonken.

Comments [0] | | # 
# Sunday, 30 July 2006
Sunday, 30 July 2006 16:21:32 (GMT Daylight Time, UTC+01:00) ( ASP.NET | Atlas )

This Blog is not active anymore, further posts will be available on my company website. Read new posts here

Regelmatig spreek ik ASP.Net ontwikkelaars. Vaak vraag ik hen of ze wel eens gebruik maken van Atlas, het Ajax Framework van Microsoft. De meest gehoorde antwoorden zijn; “ja”, “duurt lang om te implementeren” , “maar dat is toch nog niet officieel uit?” “ransig met Javascript”, “ransig met dat XML script”. Op antwoord twee wil ik me voor nu even concentreren.

Via onderstaande ASP.Net applicatie kan een gebruiker zijn/haar naam invoeren en na een druk op de submit knop wordt de invoer getoond, lijkt mij een wereld applicatie :-).

Onderstaand de source:

HTML:

<%@ Page Language="C#" AutoEventWireup="true"  CodeFile="Default.aspx.cs"
Inherits="_Default" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    <title>Een webapplicatie</title>
</head>
<body>
    <form id="wepappForm" runat="server" defaultbutton="submit">
    <div>
        <asp:Label ID="applicatieInfo" runat="server" Text="" />
        <br /> <br />
        <asp:Label ID="yourName" runat="server" Text="Naam:" />
        <asp:TextBox ID="nameField" runat="server" />
        <asp:Button ID="submit" runat="server" Text="Submit" OnClick="submit_Click" />
        <br /><br />
        <asp:Label ID="typedValue" runat="server" Font-Bold="True" Font-Size="Large" />
        </div>
    </form>
</body>
</html>

C# CodeBehind :

using System;
using System.Configuration;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;

public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
this.applicatieInfo.Text = string.Format("Datum: {0} ", DateTime.Now);
}
protected void submit_Click(object sender, EventArgs e)
{
this.typedValue.Text = string.Format("Uw naam is {0}",this.nameField.Text);
}
}

Wanneer de applicatie wordt gestart wordt bij elke submit de pagina compleet ververst, zie de tijdsindicatie.



Applicatie gestart zonder Atlas functionaliteit




Submit zonder Atlas functionaliteit


Wat je eigenlijk zou willen is dat alleen het formulier wordt ververst en niet de gehele pagina. Met Atlas is dit binnen 5 minuten te realiseren. Allereerst downloaden en installeren we de nieuwste versie van het Atlas Framework. 

Vervolgens kopiëren we de Microsoft.Web.Atlas.dll naar de bin folder van onze applicatie en maken een referentie naar deze DLL.  Deze DLL is te vinden in \Mijn documenten\Visual Studio 2005\Templates\ProjectTemplates\Visual Web Developer\CSharp\ASPNETAtlasWebApplicationCS.zip voor cSharp developers, of Mijn documenten\Visual Studio 2005\Templates\ProjectTemplates\Visual Web Developer\VisualBasic\ASPNETAtlasWebApplicationVB.zip voor de Visual Basic variant.

Voeg aan je system.web sectie van je web.config onderstaande elementen toe

     <pages>
      <controls>
        <add namespace="Microsoft.Web.UI" assembly="Microsoft.Web.Atlas" tagPrefix="atlas"/>
        <add namespace="Microsoft.Web.UI.Controls" assembly="Microsoft.Web.Atlas" tagPrefix="atlas"/>
      </controls>
    </pages>

Dit zijn overigens de minimaal benodigde instellingen. Download hier een volledig voorgeconfigureerde web.config.

Aan de HTML Source voeg ik een Scriptmanager en een Updatepanel toe(in Bold en Italic weergegeven).

<%@ Page Language="C#" AutoEventWireup="true"  CodeFile="Default.aspx.cs"
Inherits="_Default" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    <title>Een webapplicatie</title>
</head>
<body>
    <form id="wepappForm" runat="server" defaultbutton="submit">
<atlas:ScriptManager  runat="server" ID="scriptMngr" EnablePartialRendering="true" /> 
    <div>
        <asp:Label ID="applicatieInfo" runat="server" Text="" />
        <br /> <br />
        <atlas:UpdatePanel ID="updName" runat="server">
        <ContentTemplate>
            <asp:Label ID="yourName" runat="server" Text="Naam:" />
            <asp:TextBox ID="nameField" runat="server" />
            <asp:Button ID="submit" runat="server" Text="Submit" OnClick="submit_Click" />
            <br /><br />
            <asp:Label ID="typedValue" runat="server" Font-Bold="True" Font-Size="Large" />
        </ContentTemplate>
        <Triggers>
        <atlas:ControlEventTrigger ControlID="submit" EventName="Click" />
        </Triggers>
        </atlas:UpdatePanel>
     </div>
    </form>
</body>
</html>

In een latere blogpost kom ik nog gedetailleerder op de Scriptmanager en Updatepanel terug, maar voor nu is het voldoende om te weten dat de scriptmanager verantwoordelijk is voor de communicatie tussen Atlas controls en code behind files. Het Update panel is verantwoordelijk voor het verversen van de controls die binnen het ContentTemplate element vallen en het doorsluizen van events die binnen het triggers element vallen. 

In ons geval wordt na het drukken op de submit knop Event Click afgevangen, de postback wordt uitgevoerd en het formulier wordt ververst. Nu starten we onze webapplicatie met Atlas functionaliteit



Applicatie gestart met Atlas functionaliteit


 

Submit met Atlas functionaliteit

Constateer dat de datum/tijd dit keer niet veranderd omdat deze buiten het update panel is geplaatst en dus niet ververst wordt. Ook heb ik niks aan mijn codebehind file hoeven aan te passen. Uiteraard is dit slechts basis functionaliteit, maar in een volgende blogpost over Atlas zal ik dieper ingaan op het Framework.

Downloads:
Comments [4] | | # 
# Monday, 23 January 2006
Monday, 23 January 2006 20:19:16 (GMT Standard Time, UTC+00:00) ( ASP.NET )

This Blog is not active anymore, further posts will be available on my company website. Read new posts here

Afgelopen week liep ik tegen een probleem aan waarbij authenticatie timeout minuten eerder optrad dan sessie timeout, terwijl beide op 20 minuten stonden ingesteld. De oorzaak was een verschil tussen de werking van sessie timeout en authenticatie timeout.

Sessie timeout wordt elke keer vernieuwd wanneer een pagina wordt opgevraagd. Dus wanneer je in je web.config aangeeft dat de sessie na 20 minuten verloopt, zal deze elke keer dat een pagina wordt opgevraagd 20 minuten na nu worden gezet(wat logisch is). Authenticatie timeout wordt pas vernieuwd wanneer 50% van de resterende tijd verstreken is. Dus wanneer je de authenticatie timeout dezelfde waarde geeft als sessie timeout zal deze de eerste 10 minuten niet vernieuwd worden. Even terug naar de pagina waar een gebruiker inlogt om 8:00. De volgende waarden worden gezet:

Sessie Timeout = 8:20
Authenticatie Timeout = 8:20

Vervolgens doet de gebruiker na 8 minuten weer een actie. De volgende waarden worden gezet:

Sessie Timeout = 8:28
Authenticatie Timeout = 8:20

Om 8:25 vraagt de gebruiker een pagina op en wordt naar de loginpagina verwezen omdat er een authenticatie timeout is opgetreden. Het menu wordt echter opgebouwd aan de hand van een sessie variabele.  Deze variabele bestaat nog steeds en toont dus het verkeerde menu. Ik heb dit opgelost door authenticatie timeout drie keer hoger te zetten dan sessie timeout.

In het Session_OnStart event van het global.asax bestand log ik middels onderstaande regel de gebruiker automatisch uit wanneer een nieuwe sessie wordt gestart(zelfs als deze niet is ingelogd).

FormsAuthentication.SignOut()

De reden waarom ik dit in het Session_OnStart event heb geplaatst is dat het Session_OnEnd event niet altijd getriggerd wordt en op deze manier weet ik zeker dat een gebruiker niet is ingelogd wanneer een sessie start.

Comments [0] | | # 
# Sunday, 11 December 2005
Sunday, 11 December 2005 08:52:15 (GMT Standard Time, UTC+00:00) ( ASP.NET )

This Blog is not active anymore, further posts will be available on my company website. Read new posts here

Via onderstaande link word je uitgelegd hoe je een website project vanuit windows explorer kan starten. Erg handig.

Lees meer

Comments [0] | | # 
# Wednesday, 19 October 2005
Wednesday, 19 October 2005 16:59:46 (GMT Daylight Time, UTC+01:00) ( ASP.NET )

This Blog is not active anymore, further posts will be available on my company website. Read new posts here

Om een website te compileren en te deployen in ASP.Net 1.x was een build, copy van ASPX files en de bin directory voldoende. ASP.Net 2.0 maakt geen gebruik meer van dit mechanisme. ASP.Net 2.0 compileerd de bestanden on the fly en maakt van elk codebehind file een kleine DLL wanneer een gebruiker een pagina van de website opvraagt. Dit houdt in dat Codebehind files ook op de server geplaatst moeten worden, iets dat we absoluut niet willen. Daarom is een command line tool beschikbaar waarmee de website volledig gecompileerd wordt.  Deze command line tool heet aspnet_compiler.exe.

Via onderstaand commando heb ik ons eerste .Net 2.0 project succesvol gecompileerd. 
aspnet_compiler -p e:\Inetpub\tom-du.net\Framework c:\compiled -v tomdu.

-p staat voor physieke locatie op schijf
e:\Inetpub\tom-du.net\Framework is de locatie van de sources
c:\Compiled is de target folder
-v staat voor virtuele folder (in ons geval tomdu)

In bovenstaand voorbeeld wordt code en layout gecompileerd in Dll's. In de aspx vind je alleen "This is a marker file generated by the precompilation tool, and should not be deleted!". Mocht je de aspx file wel willen wijzigen zonder opnieuw te compileren kan je de optie -u gebruiken.  

Om nu niet teveel te typen kan je via www.west-wind.com is een gratis tool downloaden wat beschikt over een GUI.

Comments [0] | | # 
# Friday, 14 October 2005
Friday, 14 October 2005 09:14:43 (GMT Daylight Time, UTC+01:00) ( ASP.NET )

This Blog is not active anymore, further posts will be available on my company website. Read new posts here

De Ajax.Net Library is vernieuwd, nieuwe features:

  • Enums in JavaScript client-side code
  • DateTime, Date en Timezone functies
  • Session State Handlers

Meer Info

Comments [0] | | # 
# Friday, 22 July 2005
Friday, 22 July 2005 13:16:18 (GMT Daylight Time, UTC+01:00) ( ASP.NET )

This Blog is not active anymore, further posts will be available on my company website. Read new posts here

Gisteren liep ik in Visual studio 2005 tegen het volgende probleem aan:

- Plaats een Login control (uiLogin)op de pagina.
- Plaats Password Required tekst in PasswordRequiredErrorMessage.
- Plaats Username Required tekst in UserNameRequiredErrorMessage.
- Plaats een validationsummary control (uiValid) op de pagina.
- plaats in uiValid.ValidationGroup het Id van uiLogin.

Volgens MSDN zou het validationsummary control nu de Password Required tekst en Username Required tekst kunnen tonen.

Door een bug in het validationsummary control is dit echter niet het geval. Een workaround is door in uiValid.ValidationGroup het unieke ID van uiLogin te plaatsen, dit kan alleen in code. Na het toevoegen van onderstaande c# regel aan het Page_Load event is uiValid in staat de Password Required tekst en Username Required tekst te tonen.

uiValid.ValidationGroup = uiLogin.UniqueID;

Klik hier voor meer info over deze bug en mijn geposte workaround.

Comments [0] | | #