# Friday, October 19, 2007

A few days ago a developer at a customer asked me how he could simplify the following code as he identified a pattern: X tries and the error handling.

public PlanungsGruppenLesenA PlanungsGruppenLesen(
    PlanungsGruppenLesenF param)

{

    PlanungsGruppenLesenA ret = new PlanungsGruppenLesenA();

 

    if (ret.PlanungsGruppen == null)

    {

        throw new ArgumentNullException("param.PlanungsGruppen");

    }

    int nRetry = 0;

    while (nRetry < DBWerkzeug.MaxWiederholungen)

    {

        try

        {

            using (XXX_POC.POC db =

                new XXX_POC.POC(
                    DBWerkzeug.GetConnectionString()))

            {

                var q =

                    from p in db.Stammdaten_Planungsgruppe

                    orderby p.Name.ToLower()

                    select new PlanungsGruppeDM

                    {

                        ID = p.Rowid,

                        Name = p.Name

                    };

                ret.PlanungsGruppen = q.ToList<PlanungsGruppeDM>();

            }

        }

        catch (ChangeConflictException e)

        {

            nRetry++;

            if (nRetry >= DBWerkzeug.MaxWiederholungen)

            {

                ret.FehlerText = e.Message;

                ret.HatFehler = true;

                throw;

            }

        }

        catch (Exception e)

        {

            ret.FehlerText = e.Message;

            ret.HatFehler = true;

            throw;

        }

    }

    return ret;

}

I ended up with this:

public PlanungsGruppenLesenA PlanungsGruppenLesen(
    PlanungsGruppenLesenF param)

{

    PlanungsGruppenLesenA ret = new PlanungsGruppenLesenA();

 

    if (ret.PlanungsGruppen == null)

    {

        throw new ArgumentNullException("param.PlanungsGruppen");

    }

    ret.PlanungsGruppen = CatchExceptions<PlanungsGruppeDM>(

        delegate

        {

            using (XXX_POC.POC db =

                new XXX_POC.POC(
                    DBWerkzeug.GetConnectionString()))

            {

                var q =

                    from p in db.Stammdaten_Planungsgruppe

                    orderby p.Name.ToLower()

                    select new PlanungsGruppeDM

                    {

                        ID = p.Rowid,

                        Name = p.Name

                    };

                return q.ToList<PlanungsGruppeDM>();

            }

        },

        ret);           

    return ret;

}

What calls the encapsulated X tries and the error handling:

public delegate List<T> MachMal<T>();

 

public static List<T> CatchExceptions<T>(MachMal<T> machMichFertig, BasisA ret)

{

    int nRetry = 0;

    while (nRetry < DBWerkzeug.MaxWiederholungen)

    {

        try

        {

            return machMichFertig();

        }

        catch (ChangeConflictException e)

        {

            nRetry++;

            if (nRetry >= DBWerkzeug.MaxWiederholungen)

            {

                ret.FehlerText = e.Message;

                ret.HatFehler = true;

                throw;

            }

        }

        catch (Exception e)

        {

            ret.FehlerText = e.Message;

            ret.HatFehler = true;

            throw;

        }

    }

    return null;

}

But I'm not quite sure If this made stuff really easier ;-)

C# | Projects
Friday, October 19, 2007 3:20:12 PM (W. Europe Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  | 
# Wednesday, April 04, 2007

My colleague Sergey is working on a really nice package around CardSpaces. Watch his blog for updates...

C# | Misc | Projects | Security
Wednesday, April 04, 2007 8:44:26 AM (W. Europe Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  | 
# Sunday, August 13, 2006

Microsoft introduces with Vista/IE7/Office2007 the Microsoft RSS Platform -

For some reasons my IE is not able to export the feeds that I read in IE7 and Outlook 2007 to OPML.

I had a look at the API and wrote this small console applictaion to export my feed list to the OPML format.

using System;
using System.IO;
using System.Runtime.InteropServices;
using System.Xml;
 
using Microsoft.Feeds.Interop;
using System.Collections.Generic;
 
namespace RssWindowsPlatformOpmlExporter
{
    class Program
    {
        static void Main(string[] args)
        {
            string pathToExport = "D:\\temp\\feeds.opml";
            if (args.Length > 0)
            {
                pathToExport = args[0];
            }
 
            FeedsManager mgr = new FeedsManager();
            Queue<IFeedFolder> queue = new Queue<IFeedFolder>();
            queue.Enqueue(mgr.RootFolder as IFeedFolder);
 
            while (queue.Count > 0)
            {
                IFeedFolder currentFolder = queue.Dequeue();
                IFeedsEnum subFolders = (IFeedsEnum)currentFolder.Subfolders;
 
                for (int i = 0; i < subFolders.Count; i++)
                {
                    queue.Enqueue((IFeedFolder)subFolders.Item(i));
                }
 
                using (XmlWriter opml = XmlWriter.Create(pathToExport))
                {
                    opml.WriteStartDocument();
                    opml.WriteStartElement("opml");
                    opml.WriteAttributeString("version", "1.0");
 
                    IFeedsEnum feeds = (IFeedsEnum)currentFolder.Feeds;
                    for (int i = 0; i < feeds.Count; i++)
                    {
                        IFeed feed = (IFeed)feeds.Item(i);
 
                        try
                        {
                            if (!string.IsNullOrEmpty(feed.Title) 
                                && !string.IsNullOrEmpty(feed.DownloadUrl))
                            {
                                opml.WriteStartElement("outline");
                                opml.WriteAttributeString("title", feed.Title);
                                opml.WriteAttributeString("xmlUrl", feed.url);
                                opml.WriteEndElement();
                            }
                        }
                        catch (COMException e)
                        {
                            Console.WriteLine(
                                "Error getting feed: {0}", 
                                e.Message);
                        }
                    }
 
                    opml.WriteEndElement();
                    opml.WriteEndDocument();
                }
            }
        }
    }
}
C# | Misc
Sunday, August 13, 2006 2:42:42 PM (W. Europe Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  | 
# Monday, July 17, 2006

thinktecture and newtelligence AG present a week of Windows Communication Foundation (WCF), Windows Presentation Foundation (WPF) and Windows Workflow Foundation (WWF): TornadoCamp WinFX.

Christian, Ingo, Michael and me will present from the 16th - 20th of october in Bad Ems in GERMAN!

C# | Event | Indigo | WCF
Monday, July 17, 2006 12:57:23 PM (W. Europe Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  | 

I posted some Bits Michael and I wrote recently in a WCF Project:

The Constraints-Extensions let you easily define attribute based limitations for input, output and return parameters. Limitations can be set to service contracts operations as well as to data contract data member implementations. The constraints validation gets called at runtime by the WCF infrastructure and the behavior will throw a ConstraintViolationException with descriptive messages in case of a constraint gets violated/the validation fails.

The following constraint attributes have been implemented:

  • Between
  • BetweenExclusive
  • CompareAgainst
  • EarlierThanNow
  • EarlierThanToday
  • EqualTo
  • GreaterEqualTo
  • GreaterThan
  • LaterThanNow
  • LaterThanToday
  • LessEqualTo
  • LessThan
  • Match
  • MaxElements
  • MaxLength
  • MinElements
  • MinLength
  • NotBetween
  • NotEmpty
  • NotEqualTo
  • NotNull
  • Nullable
  • OneOff·    

Data Contract Sample:

[DataContract]
class
TestClass
{
    [DataMember]
    [LessEqualTo(CompareAgainst.FieldOrProperty,"EndDate")]
    public DateTime StartDate;

    [DataMember]
    [GreaterEqualTo(CompareAgainst.FieldOrProperty, "StartDate")]
    public DateTime EndDate;

    public TestClass(DateTime startDate, DateTime endDate)
    {
        StartDate = startDate;
        EndDate = endDate;
    }
}

 

Service Contract Sample:

[ServiceContract, ConstraintsValidatorBehavior]
interface
ITestConstraints
{

    [OperationContract]
    [return:GreaterEqualTo(0)]
    int MethodA(
        [Between(0,100)]
        int a,
        [LessEqualTo(20)]
        double b,
        [NotEmpty]
        string c); 

    [OperationContract]
    int MethodB(
        [Between(0, 100)]
        int a,
        [LessEqualTo(20)]
        ref double b,
        [NotEmpty]
        out string c);

    [OperationContract]
    [return:LaterThanNow]
    DateTime MethodC(
        [GreaterThan(0)]
        int a);

 

    [OperationContract]
    void MethodD(
        [VerifyObject]
        TestClass a);
}


Download at wcf.netfx3.com

C# | Indigo | Projects | WebServices | WCF
Monday, July 17, 2006 12:43:28 PM (W. Europe Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [1]  | 
# Tuesday, May 16, 2006

Two tools really useful if you work with AJAX

ASP.NET | C#
Tuesday, May 16, 2006 1:04:19 PM (W. Europe Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  | 
# Thursday, February 23, 2006

Sometimes it happens that a form is processing and you need to make sure that the users don't panic and run away before it finishes.

 

A splash screen with a "Loading..." indicator can help to calm down frightened users and make life easier for technical support staff.

 

Back in the days of classic ASP (VBScript) which used a linear programming approach we had to start by setting the response buffer to true:

 

<%

Response.Buffer = True

%>

 

This line does nothing but instructing the server NOT to send anything back to the client until the page has been finished processing.

An exception can be forced by calling the flush command:

 

<%

Response.Flush()

%>

 

Calling flush lets the server send everything to the client that is processed so far.

This will also speed up your page since the server doesn't have to switch back and forth between executing the page and sending bits to the browser.

 

Using this we were able to accomplish the following steps:

 

  • Send e.g. a div-layer containing a "Loading..." graphic to the client
  • Process the long running task.
  • Send the results of the long running task to the client
  • Send a client side script to the client, that hides the div-layer containing the "Loading..." graphic

 

The script then might look like this:

 

<%

Response.Buffer = True

%>

<!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>

    <title>Wait Screen</title>

    <script type="text/javascript">

    //<![CDATA[

    <!--

        if(document.getElementById)

        {

             var upLevel = true;

        }

        else if(document.layers)

        {

             var ns4 = true;

        }

        else if(document.all)

        {

             var ie4 = true;

        }

 

        function hideObject(obj)

        {

            if (ns4)

            {

                 obj.visibility = "hide";     

            }

            if (ie4 || upLevel)

            {

                 obj.style.visibility = "hidden";

            }

        }

    // -->

    //]]>

    </script>

</head>

<body>

    <div id="splashScreen">

        <img src="wait.gif" width="75" height="15" />

    </div>

    <%

        Response.Flush()

 

        'All processing here...

 

        Response.Flush()

    %>

    <script type="text/javascript">

    //<![CDATA[

    <!--

        if(upLevel)

        {

               var splash = document.getElementById("splashScreen");

        }

        else if(ns4)

        {

               var splash = document.splashScreen;

        }

        else if(ie4)

        {

               var splash = document.all.splashScreen;

        }

        hideObject(splash);

    // -->

    //]]>

    </script>

</body>

</html>

 

I haven’t mentioned yet that client side Javascript initially checks what kind of browser we have to deal with (either up level like Internet Explorer 7.0, other Internet Explorer’s or Netscape 4.x).

 

But with ASP.NET we have got a complete different way of how the page is executed. Today we have a Page class, which has an event based execution model and controls – so how can this mechanisms be used in ASP.NET?

 

The difference between classic ASP and ASP.NET, that initially seems to be a problem, is really an advantage. It gives us the ability to write and store our code in a more structured manor.

 

This way we can separate infrastructure code form application logic code. It lets us focus on the things we, as application developers, really need to do – To get things done.

 

 

First of all we need to do a few initial steps:

 

·        Start Visual Studio (or use notepad.exe)

·        Creating a new Project of the type “Class Library” (on skip this if you are using notepad)

·         Rename Class1.cs to WaitScreen.cs (or just save your file as WaitScreen.cs using notepad)

·        Add a reference to the namespace “System.Web” (or remember to add the compiler switch /r pointing to the  assembly System.Web.dll)

 

After our environment has been set up we can start writing the code. First we outline the class to use it as a WebControl by deriving it from the WebControl class.

 

using System;

using System.ComponentModel;

using System.Web.UI;

using System.Web.UI.WebControls;

 

namespace StaticDust.Web.UI.Controls

{

    /// <summary>

    /// The WaitScreen control displays a grafic while a long running operation

    /// is running.

    /// </summary>

    public class WaitScreen : WebControl

    {

    }
}

 

Controls are reusable components so it is important to let the client side developer (the guy who uses the control in Visual Web Developer – this might also be you…) the opportunities to customize the layout of the control. In our case the only customization that can be done would be a different graphic that is displayed during the long running operation is executed on the server. Here is the code that allows the client side developer to easily set a URL, pointing to an graphics file, form an attribute on the ServerContol or by directly setting the value of the property from the code behind

 

...

// This field holds the URL pointing to an image

private string m_ImageUrl = "~/images/busy.gif";

...

 

The private field m_ImageUrl is initialized with a default image on the instantiation of the class so – if the image exists – the client side developer mustn’t explicitly set anything.

 

...

/// <summary>Gets/sets the URL pointing to an image.</summary>

/// <value>A <see cref="string">string</see> containing the URL pointing

/// to an image..</value>

/// <remarks>This property gets/sets the URL pointing to an image.

/// </remarks>

[Description("Gets/sets the URL pointing to an image.")]
public string ImageUrl

{

    get { return m_ImageUrl; }

    set { m_ImageUrl = value; }

}
...

The property ImageUrl just gives public access to the private field m_ImageUrl. Having (again) the client side developer in mind we provide the XML comments summary, value and remarks and additionally set the description attribute, which allows Visual Studio to display details in the properties window.


 

 

Delegates and events are one of the most powerful tools that come with .NET Framework and we can use them to let the client developer attach his/her custom long running operation as custom event handler code. Even more then one method can be attached so that all together are the “one long running task” that is processed while the graphic is displayed. Separated nicely from the infrastructure code (the control we are currently writing). Here is our event code:

 

public delegate void ProcessHandler(object sender, EventArgs e);

 

The delegate defines (like a function pointer) how the event handler code should look like.

 

/// <summary>

/// The process event.

/// </summary>

public event ProcessHandler Process;

 

The event named “process”, to attach custom long running operations to.

 

/// <summary>

/// Triggers the Process event.

/// </summary>

public virtual void OnProcess()

{

    Process(this, null);

}

 

The OnProcess method triggers the event and invokes the attached custom long running operations.

 

Now that the ability is given that custom code can be executed using the event/delegate we need to actually raise the event and before that ensure that the response buffer is set to true and the graphic is send to the client. The load event of out control does this job for us.

 

/// <summary>

/// Triggers the Load event.

/// </summary>

protected override void OnLoad(EventArgs e)

{

    base.OnLoad(e);

 

    Page.Response.Buffer = true;

 

    #region Show splash screen

 

    Page.Response.Write(

        string.Concat(@"<script type=""text/javascript"">

//<![CDATA[

<!--

 

if(document.getElementById)

{ // IE 5 and up, NS 6 and up

    var upLevel = true;

}

else if(document.layers)

{ // Netscape 4