Since Powerbuilder 11 you can use WebForms deployment to bring you classic application to the web. The idea opening to the web was good, but WebForms lags in several ways. It isn’t compatible with browsers excepted the Internet Explorer and so e.g. the growing mobile device market next to Windows Phone is cut off. In Powerbuilder .NET WebForms deployment isn’t possible anymore.
Some developer were frustrated about the fact there isn’t a replacement to proceed this way. Appeon could work, but is a heavy solution. Powerbuilder 15 with the shiny new HTML5 Datawindow is even on the horizon.
It’s time to search for options. This article describes how to implement a rendering engine from the scratch in PB .NET. It’s not the idea to migrate an application to the web. It’s the idea to get some basics to build up a PB.NET Web framework. Have fun!
The Key is an Interface: IHttpHandler
In .NET HttpHandlers are responsible to process a request to a web application. Common handlers are to process .aspx or .asmx sites. There are integrated handlers but it’s also possible to define your own. In this case for sites with postfix .pb (you are free to choose another one).
The Handler is a .NET or Powerbuilder .NET class implementing the IHttpHandler or the IHttpAsyncHandler. You can read about it in msdn. In this example only IHttpHandler is used.
You can see here why we have to use Powerbuilder .NET and we can’t implement this in Classic. Powerbuilder Classic can’t implement .NET interfaces.
After we implement the .NET interface there a method and a property we have to care about.
|IsReusable||Let this return false in this example. If it is true, the object will be pooled. It’s faster to reuse but maybe vulnerable to bugs caused by variable states.|
|ProcessRequest||This is the main method to process the Request and write back or data.|
Getting started for the first Handler
Create a new target of type .NET-Assembly in Powerbuilder .NET. After you did you can create a new nonvisual object. To let it implement the interface add the reference to System.Web in the target. Let your nonvisual implement the IHttpHandler interface.
You can fill the get method of the property IsReusable with return false. The ProcessRequest method can implement something like this.
context.Response.Write("Hello World") context.Response.@End()
So is the coding work done? Not at all. If we try to compile, PB will quit because there is no exported function. The easiest way to prevent this message is to create a dummy method e.g. of_version with return 1 and set it to export in the project painter.
Bring it to my IIS
Now we have to bring the application to the IIS. In the IIS it’s necessary to create a new application. After that copy all files from the output directory to subfolder /bin to the new application.
To let the IIS know what Requests can be handled, we have to do some configure work in IIS or we can use this simple web.config. The web.config must be in the root of the application.
<?xml version="1.0" encoding="utf-8"?> <configuration> <system.web> <compilation debug="true" targetFramework="4.0" /> </system.web> <system.webServer> <modules runAllManagedModulesForAllRequests="true"> </modules> <handlers> <add name="PBHandler" path="*.pb" verb="*" type="pbwebhandler.n_pbwebhandler" resourceType="Unspecified" requireAccess="Script" preCondition="integratedMode" /> </handlers> <security> <requestFiltering> <fileExtensions> <add fileExtension=".pb" allowed="true" /> </fileExtensions> </requestFiltering> </security> </system.webServer> </configuration>
After restarting the IIS you can check the settings in the configuration console (->Handlers).
Open http://localhost/<applicationname>/test.pb. You should see the Hello World message. It doesn’t matter what site do you choose (test.pb, abc.pb) because the handler proceed every request with postfix .pb. To separate the actions you have to extend the ProcessRequest method.
There are lot more interaction you can bring to your application. I wrote two simple examples to the attached demo application. The first is a simple login form, the second is a rendered Datastore.
What I supposed to say with this article is NOT that this is the first way to bring PB to the web. In this status this solution is just usable for very simple tasks. But this could be a basic solution for a full web framework in PB .NET. It has to be coded and has to be done by the community. So maybe someone is interested to start it up.