Websydian v6.1 online documentationOnline documentation - Websydian v6.5

BinaryPageGenerator

Overview

The BinaryPageGenerator pattern is used when you want to let the user download a file from the application to his PC/browser.

The file can either be a static file or it can be a file that you have generated at an earlier step in the processing of the user request.

The BinaryPageGenerator reads the file and streams the content unaltered to the browser after setting HTTP-headers that describe the content.

Interface

DocumentName

The file name of the file to download.

DocumentPath

The full path to the folder containing the file to download. This must end with a path separator ("\" or "/", depending on the variant).

The DocumentPath and DocumentName are concatenated to create the location of the file to download.

The DocumentName will be used as the name of the file in the default content type header set by the system.

HTTP-Headers

The developer must specify the HTTP-headers, which is sent before the file-content.

The HTTP-headers describe the content of the file and how the browser should handle the file.

The pattern does not have any way to determine the content of the file that is being handled, so the developer must ensure that the correct headers are sent.

The unaltered BinaryPageGenerator sends three headers (described below). You can add additional headers if needed.

Content-Type

The Content-Type entity-header field indicates the media type of the entity-body sent to the recipient. This header makes it possible for the browser to determine which application it can use to handle the file-content (based on the users system preferences/browser settings).

Content-disposition

The Content-disposition header is used by the browser to determine whether the file content should be handled as content that should be shown right away as part of the web site being loaded (Content-disposition:inline) or whether file should be handled as a downloaded file that the user can choose to either save or display (Content-disposition:attachment).

For Content-disposition:attachment, you can also specify the filename the user will be informed about - this results in the format:

Content-disposition:attachement;filename="myfilename".

Filename

As far as can be determined, no current browser versions use this header.

Specifying headers (DWA-Specific)

This section only describes how headers are specified for the DWA variants of Websydian.

The headers are specified in the subroutine "Send headers" in the BinaryPageGenerator.

If you need to add further headers it is vital that it is done in this subroutine, as the headers must be set after the connection is initialized, but before the file content is streamed.

You can add additional headers by setting the values for the local fields Local<HeaderName> and Local<HeaderValue> followed by a Go Sub write document line statement.

If you want to change the values of the three headers the standard BinaryPageGenerator already specifies, you must undefine the entire subroutine, copy the content of the subroutine and set the headers to the values described above.

Media-types

To be able to send the correct information in the Content-type header, it is necessary to know the media type that corresponds to the file content.

Note that MS-Office changed the document formats in version 2007. This means that each MS-Office program has two separate formats, which each has it's own media type.

For example, Word documents have a version (.doc), which corresponds to the media type application/msword and a version (.docx), which corresponds to the media type: application/vnd.openxmlformats-officedocument.wordprocessingml.document.

The content of the file determines which media type you must specify.

Note that no matter the content will be shown by the application the user has specified for the media type you specify in the headers. If the user has selected a program that can't open the media an error will occur. If the user hasn't selected an application for the specified media type, he will be prompted to select one.

Browser Specific Handling

The way the different browsers handle the Content-Type and Content-disposition headers are not same.

When using the BinaryPageGenerator, it is even more important than usual to test all combinations of browsers, browser versions, and file content that you want to support. Even for a specific browser the handling of a specifc content type can be different in different versions of the borwser.

Examples

Note that these examples are DWA-specific.

If you use the PC webserver or iSeries webserver variants, the headers are set in a different manner.

PDF - show in browser

Headers

The media type for pdf is: application/pdf

When the default behavior is to show the file in the browser, the Content-disposition should be set to inline.

Implementing

 

Define the BinaryPageGenerator by specifying the triple:

Source Object Verb Target Object
MyBinaryPageGenerator is a FNC BinaryPageGenerator

Create two messages that will be used to create the Content-type and Content-disposition header values

Source Object Verb Target Object
MyBinaryPageGenerator message MSG ContentType
MyBinaryPageGenerator message MSG ContentDisposition

Specify the following literal values:

MyBinaryPageGenerator.ContentType: application/pdf

MyBinaryPageGenerator.ContentDisposition: inline

 

In the Post Point "Start Send Headers enter the following code:

 

+If Variant: WsyBase/DWA - Windows

+Else

    Call WsyBase/WpkaSetResponseCharset

Map with:

WsyBase<ConnectionPointer>

ResponseCharset<*BINARY>

Set Document<TypeInfo> = <TypeInfo.Specific>

Set Document<DocumentAction> = <DocumentAction.Open>

Set Local<HeaderName> = <HeaderName.Content-type>

Format Message Message: MyBinaryPageGenerator.ContentType, Local<HeaderValue>

Go Sub Write document line

Set Local<HeaderName> = <HeaderName.Content-disposition>

Format Message Message: MyBinaryPageGenerator.ContentDisposition, Local<HeaderValue>

Go Sub Write document line

+++Undefine Field: FIELDS/+Subroutine

You should note that the last statement ensures that the normal handling performed by the subroutine is not generated.

The call to WpkaSetResponseCharset is is normally made in the subroutine itself, but as this handling has bee undefined, you have to enter the call in the post point.

The rest of the code just sets the values for the Content-Type and Content-disposition headers.

Notes

It seems the Chrome browser can't load the pdf inline if the target is a frame. This means that there can very well be problems when loading a pdf in a frame in WebsydianExpress. You can avoid this issue by specifying target=_top in the HTML form for the event that shows the pdf.

PDF - as file attachment

Headers

The media type for pdf is: application/pdf

When the default behavior is to show the file in the browser, the Content-disposition should be set to attachment - and a suggested filename should be specified.

Implementing

 

Define the BinaryPageGenerator by specifying the triple:

Source Object Verb Target Object
MyBinaryPageGenerator is a FNC WSYBASE/BinaryPageGenerator

Create two messages that will be used to create the Content-type and Content-disposition header values

Source Object Verb Target Object
MyBinaryPageGenerator message MSG ContentType
MyBinaryPageGenerator message MSG ContentDisposition
MyBinaryPageGenerator.ContentDisposition parameter FLD WSYBASE/DocumentName

Specify the following literal values:

MyBinaryPageGenerator.ContentType: application/pdf

MyBinaryPageGenerator.ContentDisposition: attachment; filename="&(1:)"

 

In the Post Point "Start Send Headers enter the following code:

 

+If Variant: WsyBase/DWA - Windows

+Else

    Call WsyBase/WpkaSetResponseCharset

Map with:

WsyBase<ConnectionPointer>

ResponseCharset<*BINARY>

Set Document<TypeInfo> = <TypeInfo.Specific>

Set Document<DocumentAction> = <DocumentAction.Open>

Set Local<HeaderName> = <HeaderName.Content-type>

Format Message Message: MyBinaryPageGenerator.ContentType, Local<HeaderValue>

Go Sub Write document line

Set Local<HeaderName> = <HeaderName.Content-disposition>

Format Message Message: MyBinaryPageGenerator.ContentDisposition, Local<HeaderValue>

Map with:

Document<DocumentName>

Go Sub Write document line

+++Undefine Field: FIELDS/+Subroutine

You should note that the last statement ensures that the normal handling performed by the subroutine will not be generated.

The call to WpkaSetResponseCharset is is normally made in the subroutine itself, but as this handling has been undefined, you have to enter the call in the post point.

The rest of the code just sets the values for the Content-Type and Content-disposition headers.

If you want to suggest a filename to the user that is not the same as the one used in your file system, specify a field containing this value for the parameter to the format message statement for the ContentDisposition message.

Notes

In Chrome 10, this will show a standard file/folder selection dialog. This only allows the user to save the file.

In Firefox 4, this shows a dialog, where the user can select to either save or open the file. The default will be the last selection the user has made.

In Internet Explorer 8, this shows a dialog where the user can select to either save or open the file. The default seems to be to cancel the download.

Force download

In Firefox 4, when you choose Content-disposition attachment, the user will be shown a dialog, where he can choose to either save the file or open it.

It seems that the selection will be the one the user has selected the last time - not necessarily the save option.

In some cases, the application should always propose that the file should be saved. This seems to be possible using a slightly different combination of Content-Type and Content-disposition.

In this case, you specify the Content-Type: application/force-download and the Content-disposition: attachment;filename="myfilename.pdf".

This instructs the application that it should always propose that the file should be saved.

Internet Explorer 8 and Chrome 10 seems to be indifferent to whether the Content-Type is set to application/pdf or to application/force-download.

Note that application/force-download is not a standard media type, so you can't be certain that all browsers will be able to handle it. Therefore, you should only use this if you need to ensure that the save option is selected when the user uses Firefox.

Implementing

 

Define the BinaryPageGenerator by specifying the triple:

Source Object Verb Target Object
MyBinaryPageGenerator is a FNC WSYBASE/BinaryPageGenerator

Create two messages that will be used to create the Content-type and Content-disposition header values

Source Object Verb Target Object
MyBinaryPageGenerator message MSG ContentType
MyBinaryPageGenerator message MSG ContentDisposition
MyBinaryPageGenerator.ContentDisposition parameter FLD WSYBASE/DocumentName

Specify the following literal values:

MyBinaryPageGenerator.ContentType: application/force-download

MyBinaryPageGenerator.ContentDisposition: attachment; filename="&(1:)"

 

In the Post Point "Start Send Headers enter the following code:

 

+If Variant: WsyBase/DWA - Windows

+Else

    Call WsyBase/WpkaSetResponseCharset

Map with:

WsyBase<ConnectionPointer>

ResponseCharset<*BINARY>

Set Document<TypeInfo> = <TypeInfo.Specific>

Set Document<DocumentAction> = <DocumentAction.Open>

Set Local<HeaderName> = <HeaderName.Content-type>

Format Message Message: MyBinaryPageGenerator.ContentType, Local<HeaderValue>

Go Sub Write document line

Set Local<HeaderName> = <HeaderName.Content-disposition>

Format Message Message: MyBinaryPageGenerator.ContentDisposition, Local<HeaderValue>

Map with:

Document<DocumentName>

Go Sub Write document line

+++Undefine Field: FIELDS/+Subroutine

You should note that the last statement ensures that the normal handling performed by the subroutine will not be generated.

The call to WpkaSetResponseCharset is is normally made in the subroutine itself, but as this handling has been undefined, you have to enter the call in the post point.

The rest of the code just sets the values for the Content-Type and Content-disposition headers.

If you want to suggest a filename to the user that is not the same as the one used in your file system, specify a field containing this value for the parameter to the format message statement for the ContentDisposition message.

Notes

In Chrome 10, this will show a standard file/folder selection dialog. This only allows the user to save the file.

In Firefox 4 and later, this shows a dialog, where the user can select to either save or open the file. The default will save.

In Internet Explorer 8, this shows a dialog where the user can select to either save or open the file.