Index Popups 2008.2.9.10 Update
Index popups for Inmagic Webpublisher Pro have been updated to fix some subtle bugs: - Entering certain characters in find box causes invalid XML errors.
- Previous Page and Last Page do not work with some secondary fieldnames, or when fieldname is provided whose sentence case does not match actual field exactly.
- Passwords are not passed through after the initial page. (Ok, not so subtle this one.)
- Code fields can cause invalid XML errors.
- Last Page fails if icsweb.ini/dbtwpub.ini SoapFormat=0 or SoapFormat=n and fieldname requires modification for XML use.
Unfixable issue: - Previous Page fails if icsweb.ini/dbtwpub.ini SoapFormat=0 or SoapFormat=n and fieldname requires modification for XML use. (Can only fix by changing SoapFormat=1 due to Webpublisher restrictions on fetching index lists with a key delta.)
Download Index Popups 2008.2.9.10 (~600 kB) Labels: inmagic, Webpublisher
CSS absolute positioning while using ASK
is NOT recommended.
Usually not added when you first install WPP, check your DBTWPUB.ini file in your WPP installation folder on your web server. Make sure that you do not have the line of code " WebCSSOpt=2" as our ASK web forms will not display properly.
You can edit the DBTWPUB.ini file in Notepad and either change it to WebCSSOpt=0 or delete that line entirely.
Below is the DB/TextWorks Help file article for more information....
WebPublisher PRO: Form layout
By default, WebPublisher version 4.1 and later uses Cascading Style Sheets (CSS) and absolute positioning, so that report, display, and edit forms look as much as possible as they would look in DB/TextWorks.
WebPublisher detects whether the browser supports Cascading Style Sheets. If not, WebPublisher uses simple HTML (boxes will be left-justified, box labels will appear on top rather than to the left, and so forth).
Forms that contain Raw HTML or inline images are incompatible with absolute positioning. Forms containing these elements will have overlapping text unless very carefully designed. Therefore, simple HTML is used for this type of form unless you explicitly set WebCSSOpt=2 in your DBTWPUB.INI file (see below).
Note: DB/TextWorks tabular forms do not use absolute positioning, so this issue does not affect them.
You can use picture boxes in place of inline images to retain CSS formatting. The Image size option specified using Box Properties>Position in the Form Designer is used. In order for the image sizing to work properly, the images must reside either in the textbase folder (for example, C:\CATALOG\) or the folder specified in the Image field in the record (for example, C:\IMAGES\COYOTE.JPG).
To control whether the site uses CSS, set the WebCSSOpt= parameter in the [WebPublisher] section of your DBTWPUB.INI file equal to one of the following:
0 = do not use CSS
1 = the default behavior
2 = use CSS regardless of whether forms contain Raw HTML or inline images
Example
[WebPublisher]
WebCSSOpt=0
Note: The WebCSSOpt= parameter affects all forms and all textbases, unless you override it using the CS= parameter in an individual query screen. Labels: ASK, Webpublisher
How to install Webpublisher on 64-bit IIS 7
Further to my post called Webpublisher on Windows Vista, here is how to install Inmagic Webpublisher on IIS 7 in a 64-bit environment such as Windows Vista x64 or Windows Server 2008 x64. These instructions are valid for DB/Text Webpublisher as well as CS/Webpublisher. Steps 1 - 5 are valid for 32-bit IIS 7 as well. 1. Ensure IIS is enabled This screenshot shows which IIS features are enabled on my Vista x64 machine. The highlighted one is particularly important (IIS metabase and IIS 6 configuration compatibility). 2. Install Inmagic Webpublisher Follow the usual Inmagic install instructions. 3. Enable ISAPI-dll handler mapping on dbtw-wpd or ics-wpd virtual directory Open the IIS Manager. Open the Handler Mappings for the dbtw-wpd or ics-wpd virtual directory. (Figure below shows dbtw-wpd.) The ISAPI-dll handler is disabled by default. Enable the ISAPI-dll handler: right-click it, choose "Edit Feature Permissions", and check the "Execute" box. Click OK. 4. Set the Webpublisher dll as an allowed restriction In the IIS Manager, click on the machine root - this is the top level of the tree in the left column, which shows the machine name. You should see a number of machine-level features, including "ISAPI and CGI Restrictions", as below. If you do not see "ISAPI and CGI Restrictions", you have not properly enabled IIS settings in step 1. Open ISAPI and CGI Restrictions. You may see Inmagic Webpublisher as an allowed restriction already. The path will point to the install location of dbtwpub.dll or icswppro.dll, depending on which version of Webpublisher you installed. If you do not see Inmagic Webpublisher as an allowed restriction, you must add it. (Figure below shows DB/Text Webpublisher.) 5. Create an application pool for Webpublisher Open Application Pools from the IIS Manager. Add a new application pool to be used with Webpublisher, called "WebpublisherAppPool". Go to the dbtw-wpd or ics-wpd virtual directory and open its Advanced Settings. Set the Application Pool to the new WebpublisherAppPool just created. 6. Enable 32-bit applications on the Webpublisher application pool Open Application Pools from the IIS Manager. Right-click on WebpublisherAppPool and select Advanced Settings. Set "Enable 32-Bit Applications" to true. Click OK. 7. Get a drink. You're done. Whatever drink you like. I like red wine, or on a hot day, gin and tonic. Some more explanation Whereas in IIS 6 you could run worker processes in either 32-bit or 64-bit mode, but not both, IIS 7 can run 32-bit and 64-bit worker processes simultaneously. And, as the above instructions make implicitly clear, you can set this behaviour on individual application pools. Labels: IIS 7, Vista, Webpublisher, x64
A Webpublisher Xml class library and polymorphism
Last fall I wrote a new class library to handle Inmagic Webpublisher XML API calls with elegance and grace. That was the motivation anyway. One might well grasp the wind with chopsticks. Each XML request type (query, insert, update, etc.) has some mandatory elements (e.g. textbase) and some optional elements (e.g. sort fields), so I used the Decorator Pattern to attach optional bits. The pattern provided the solution I was looking for, but threw me roughly into the world of OOP inheritance and polymorphism, where I felt at every turn like a man lost in a thorny thorn field without his pants. I just found a way to remove a particularly sharp and prickly thorn. The problem - Unable to access properties specific to a derived class Consider this snippet of code: // XmlInput is abstract base class, XmlQuery is derived from XmlInput XmlInput query = new XmlQuery(tn, commandQuery, page, mr); // Decorator wraps an XmlInput object query = new SortFieldsDecorator(query, "Name|Product_Number".Split("|".ToCharArray()));
It's classic Decorator. The query object is at all times an XmlInput (the base class) type. You can pass it in to multiple decorators, and because it was instantiated as an XmlQuery, a class that derives from XmlInput, it gets some special XmlQuery-specific behaviour too (e.g. commandQuery, page, mr).
Trouble is, because the query object must be passed to decorators as XmlInput, there is no way to access the XmlQuery-specific public members:
// Cannot access XmlQuery-specific CommandQuery property! This doesn't work: query.CommandQuery = "find blah =blah";
One consequence of this for me was that the derived classes such as XmlQuery had to jam every conceivable property into the constructor as a parameter, because they couldn't be set after the object was initialized. Not so bad with XmlQuery, as it happens, but a nightmare with XmlBatchModify which has many many properties:
// OMG!!! That's not even all of them! public XmlBatchModify(string textbase, string password, ValidationType validation, BatchModifyActionType batchModifyAction, BatchModifyEntryType batchModifyEntry, bool matchCase, bool matchWholeWord) {}
Clearly something had to be done.
The fix? - Casting derived classes to base classes
I can go with the XmlQuery derived class from the get-go, set public properties after the constructor is called, and then cast the query object to the XmlInput base class before passing it to a decorator:
XmlQuery query = new XmlQuery(tn, commandQuery, page, mr); // Now I can access XmlQuery-specific CommandQuery property query.CommandQuery = "find blah =blah"; // Cast query object to XmlInput XmlInput q = (XmlInput) query; // Decorator accepts q = new SortFieldsDecorator(q, "Name|Product_Number".Split("|".ToCharArray()));
This works: properties specific to XmlQuery are not lost. I'm just not sure that it's entirely legal, or what consequences it may have in the long run. Labels: C#, Webpublisher
Avoid Application Pool Conflicts
In IIS 6.0, different versions of the .NET framework can co-exist on the same website but must use separate application pools. Once a .NET process "grabs" the app pool, other .NET processes are denied its use and report generic server errors in the browser. Which .NET process gets an app pool first depends on which is first requested after an application pool recycle. For example the .NET 2.0 process might get the application pool first, and all .NET 1.1 applications that rely on the application pool fail to run; end users see generic server errors that do not report what is really going on. Installing Inmagic Webpublisher or Genie Although Webpublisher inmagicbrowse and Genie inmagicgenie virtual directories are correctly set to use .NET 2.0, the installer lets the parent website determine which application pool to use. A typical Windows 2003 Server might have .NET 1.1 and DefaultAppPool as the default on new websites. If there are any .NET 1.1 applications already on the server that rely on DefaultAppPool, then inmagicbrowse and inmagicgenie are setting the server up for an application pool conflict. Separate Application Pools Set up a separate application pool just for Genie, and one for Webpublisher. This way you avoid any conflict with applications currently on the server, but also allow for changes in .NET dependency in future: when Genie starts using .NET 3.5 you won't have to worry about re-organizing application pools. It's also good practice to isolate applications like this so that when one does go down, it doesn't take other applications with it. Labels: asp.net, IIS 6.0, inmagic, Webpublisher
Short Persistent URLs for Database Queries
Inmagic Webpublisher canned query URLs can be very very long, so I wrote a .NET HttpHandler that shortens them and bolsters their persistence into the bargain. Here's an example of a very long Webpublisher query string that displays a single record from the sample cars database. http://localhost/dbtw-wpd/exec/dbtwpub.dll?AC=GET_RECORD&XC=/dbtw-wpd/exec/dbtwpub.dll&BU=&TN=cars&SN=AUTO29781&SE=267&RN=0&MR=0&TR=0&TX=1000&ES=0&CS=1&XP=&RF=&EF=&DF=&RL=0&EL=0&DL=0&NP=1&ID=&MF=&MQ=&TI=0&DT=&ST=0&IR=1&NR=0&NB=0&SV=0&SS=0&BG=&FG=&QS=&OEX=ISO-8859-1&OEH=ISO-8859-1
See? Looooooooong. Not at all memorable, and difficult to display or pass around. But with the handler in play, I can now shorten it:
Both get the same result:
Porsche
A classic best-seller, the Porsche 911's anodized aluminum tub chassis has a strong front brace for extra support. A steel mount holds the engine snugly in place. Mounted on 25-degree caster blocks, the A-arms are longer than most and can be adjusted for low-speed steering or short tracks. The upper links have coated turnbuckles which can also be adjusted for different terrains. The rear suspension uses extra-long arms and variable shocks. The engine is side mounted and sits lower than many models. The clutch, which happens to double as the brake drum, is mounted on the crankshaft.
Configuration
In the case of the short URL, the original query remains valid, but is held in the application's web.config:
<PermanentUrlSettings> <queries> <add name="mycarquery" uniqueIDField="Product-Number" queryParameters="/dbtw-wpd/exec/dbtwpub.dll?AC=qbe_query&TN=cars" /> </queries> </PermanentUrlSettings>
The original query is called upon with an alias: qn=mycarquery. The id parameter is appended to focus the query to a single record, or, if no id parameter, the base query is run as-is.
The short URL path is /shorturl.ashx, but this is completely imaginary. And configurable in web.config:
<httpHandlers> <add verb="GET" path="shorturl.ashx" type="Andornot.Web.PermanentUrlHandler"/> <add verb="GET" path="/shorturl" type="Andornot.Web.PermanentUrlHandler"/> <add verb="GET" path="whatever/" type="Andornot.Web.PermanentUrlHandler"/> </httpHandlers>
Using the examples above, any one of the following would be valid.
http://localhost/shorturl.ashx?qn=mycarquery
http://localhost/shorturl?qn=mycarquery
http://localhost/whatever/?qn=mycarquery
None of the paths exist on disk, which is what an HttpHandler is all about. The handler hijacks the request to any path bound to it, whether the path exists on disk or not.
Advantages
Mapping entire queries to simple aliases has some immediate and obvious advantages:
- Short URLs.
- URLs are friendlier, more memorable, and hackable. (If you are trying to make your information available this is a *good* thing.)
- You can map almost any URL path you want to the handler, in order to organize query paths into pleasing hierarchies of your own devising:
- e.g. /catalog/queries?qn=mycatalogquery
- /archives/photos?qn=myphotoquery
- etc.
- You can define and update queries in one central location.
- URLs become more persistent. Modifications to queries will not break URLs already in the wild:
- Switch from Dbtext to Content Server without breaking any canned queries
- Switch display forms or any parameter
- Switch hostname, even
Labels: asp.net, class library, inmagic, Webpublisher
|