The Road To Delphi Prism (Part 2)

by John 11/28/2008 6:33:00 AM

At the end of my last blog post I had my data access code in separate assemblies compiling inside Delphi Prism but the web application was still in a Delphi 2007 project. So the final step would be to get this project running in Delphi Prism.

I had 2 immediate problems, one was Delphi Prism currently only supports website mode as opposed to Delphi 2007 which supported web application mode. The second problem was that Delphi Prism seems to expect the codebehind files to be the same name as the web file but with .pas at the end.

For example the codebehind for Default.aspx is Default.aspx.pas

This was a problem for me because I have been using multiple level namespaces. For example if I had a webapplication called webapplication1 and a folder called folder1 with a aspx called default.aspx the filename/namespace would be webapplication1.folder1.default.pas

Broken down into steps my conversion process was the following:-

1) Open the existing solution and add the web application project directory as a website.

2) Rename my codebehind files to match the name of the webfile ( problem 2)


3) Add public partial partial to all codebehind classes 


  TWebForm1 = class(System.Web.UI.Page)

  {$REGION 'Designer Managed Code'}


  TWebForm1 = public partial class(System.Web.UI.Page)


4) Modifying the page tag in the aspx. For 2, changing codebehind to codefile and the language to Oxygene

<%@ Page language="c#" Debug="true" Codebehind="WebForm1.pas" AutoEventWireup="false" Inherits="WebForm1.TWebForm1" %>



<%@ Page language="Oxygene" Debug="true" Codefile="WebForm1.aspx.pas" AutoEventWireup="true" Inherits="WebForm1.TWebForm1" %>

In the project manager I made use of the refresh folder menu option. As  I renamed .pas files and modified the page tags the .pas nodes slowly moved under the aspx in the project manager.


5) server control declarations are no longer required in the codebehind file so they can be removed.


6) InitializeComponent and OnInit are no longer reqired. I didn't remove those but instead commented them out. They are

required later. 


7) Webservices, services and handlers need their codebehind moved to

the app_code directory under the root of the 

This is an example of how the webservice tag needs to be changed .

<%@ WebService Language="Oxygene" Debug="true" Codebehind="~/App_Code/BookMarksWS.pas" Class="BookMarksWS.TBookMarksWS" %> 

8) I threw away my original global.asax file with its codebehind and copied existing code into new Global.asax looking like this

 <%@ Application Language="Oxygene" %>

<script runat="server">

  method Application_Start(sender: Object; e: EventArgs);



  method Application_End(sender: Object; e: EventArgs);



  method Application_Error(sender: Object; e: EventArgs);



  method Session_Start(sender: Object; e: EventArgs);



  method Session_End(sender: Object; e: EventArgs);





9) Using the commented out initializecomponents and on_init methods I modified the aspx files and added the eventhandlers. For example click 

Include(Self.SaveButton.Click, Self.SaveButton_Click) in intializecomponents


<asp:Button id="SaveButton" runat="server" width="38px" OnClick="SaveButton_Click" text="Save"></asp:Button> in the aspx


10) The final step was get the project to compile. Some of the problems I found have been covered in the previous blog post. One thing I will note is that I couldn't find any way of turning on compatibility mode, so I had to make additional changes such as removing named constructors and using new rather than create.


The whole process for a project with twenty or so aspx files took several hours. I was pleasantly surprised. 

One thing I think is worth mentioning is that I have been using the "model view presenter" pattern, in particular the objectcontainerdatasource control to separate my business logic from presentation. This resulted in alot less code in the codebehind files, and so speeded up the process.

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5


The Road To Delphi Prism

by John 11/27/2008 6:30:00 AM

I figured it might be quite interesting to take an existing web application created in Delphi 2007, move it into Delphi Prism and note down the kinds of changes I had to make. The application consisted of 2 assemblies with data access logic and a webapplication containing around 20 or so webpages.

I decided to break my attempt into two stages. The first stage would see me move the data access code into Delphi Prism, I would then reference those assemblies inside the webapplication from within Delphi 2007. The second and final stage would be moving the webapplication.

As a side note I was using Blackfish as my database and the CodeGear ASP.Net providers. 

I started stage one by creating a solution inside visual studio and adding empty assemblies. I then copied my delphi code into the folders and added them to the project. I then went into the project properties and turned on "allow create constructor calls" in the compatibility tab. Having done that I hit the build button and began the process of getting the assemblies to compile.

I made extensive use of the Delphi Prism wiki to get me up to speed on language changes.


This is a list of changes I made:-

1) I had used classes with static methods. For example

class procedure SomeMethod;static;

Delphi Prism has static classes, so I removed the static keyword from the individual method and set static at the class level.

SomeClass=public static class

2) TObject no longer exists, so I did a search and replace for TObject with object.

3) Delphi automatically makes classes public in assemblies. I went through all the classes and added public before the class

SomeClass=public class

4) The overload keyword isn't required so I removed that.

5) published doesn't exist. So I replaced that with public

6) I had turned on autoboxing {$AUTOBOX ON} in source files. I removed that.

7) I had been using Delphi namespaces quite extensively. For example I had filenames like namespace1.namespace2.namespace3.pas. The unit inside the .pas was the same as the filename.

To other dotnet languages classes inside the file would exist in namespace  namespace1.namespace2.

I decided to leave the filenames as is and shorten the namespace to the above.

8) attributes use := rather than =, so I modified any occurrences of those.

9) I had used for in like this

  for x in objects do


Which results in the warnings 

Warning    1    (PW12) Variable "x" may hide existing variable "x"  

Warning    2    (PW5) Local variable unused: "x"   

The scope of x in the loop is limited, so I decided to remove x from the var so that the code became

  for x:SomeObject in objects do


10) I had declared events as 

property someevent:eventhandler

I changed that to 

    event TagSelected:EventHandler;

11) Setlength doesn't exist

I used this page as a valuable reference and decided to go with this kind of type declaration.

StringArray2 = array[0..] of String;

uValues:= new StringArray2(fieldDescslength);

All in all I would say a very successful transition. I made full use of unit tests that I had and with minimal debugging I was able to get a working web application.

Stage 2 will follow in another post....

Currently rated 3.0 by 2 people

  • Currently 3/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5


Powered by BlogEngine.NET
Theme by Mads Kristensen

About the author

Name of author John Moshakis
I'm a software developer living in Toronto..

E-mail me Send mail


<<  June 2022  >>

View posts in large calendar


    Recent posts

    Recent comments



    Don't show


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

      © Copyright 2022

      Sign in