View Data Form Implementations

View Data Form implementations inform the platform about how to load form field values when a View Data Form is opened. View Data Form implementations can be defined through a CREATE PROCEDURE statement declared inline with the spec XML or common language runtime code in a class referenced by the spec. With View Data Forms, there is a single implementation that loads data into the form. View Data Form implementations are similar to load implementations for Add and Edit Data Forms.

Stored Procedure Implementations

When a View Data Form (SP) is generated by the AddNew Item wizard, the implementation looks like this:

	<SPDataForm SPName="USR_USP_DATAFORMTEMPLATE_VIEW_IMPLEMENTATIONEXAMPLE">
		<common:CreateProcedureSQL>
			<![CDATA[
create procedure dbo.USR_USP_DATAFORMTEMPLATE_VIEW_IMPLEMENTATIONEXAMPLE
(
	@ID uniqueidentifier,
	@DATALOADED bit = 0 output,
	@FIELD1 nvarchar(10) = null output,
	@FIELD2 nvarchar(20) = null output,
	@FIELD3 nvarchar(max) = null output
)
as
	set nocount on;
	
	-- be sure to set this, in case the select returns no rows
	set @DATALOADED = 0;
	
	-- populate the output parameters, which correspond to fields on the form.  Note that
	-- we set @DATALOADED = 1 to indicate that the load was successful.  Otherwise, the system
	-- will display a "no data loaded" message.
	select @DATALOADED = 1,
		   @FIELD1 = FIELD1,
		   @FIELD2 = FIELD2,
		   @FIELD3 = FIELD3
	from dbo.TABLE1
	where ID = @ID
	
	return 0;
			] ]>
		</common:CreateProcedureSQL>
	</SPDataForm>

SPDataForm element contains the business logic for the form. The stored procedure name is firstly specified in the SPName attribute. Stored procedure implementations for View Data Forms are mostly defined by Transact-SQL CREATE PROCEDURE statements placed in a CDATA element inside a CreateProcedureSQL element. The stored procedure name is again defined by the CREATE PROCEDURE statement.

The names for custom stored procedures implementations should begin with USR_USP_DATAFORMTEMPLATE_VIEW. The USR_USP_DATAFORMTEMPLATE_VIEW prefix indicates by convention that the stored procedure is a custom stored procedure for a Blackbaud Infinity data form instance. All of that should be followed by a string to indicate the record type and possibly the data form instance.

The parameter declarations indicate a type, respectively uniqueidentifier, nvarchar(10), nvarchar(20), nvarchar(max) in the example. A default may be assigned to a parameter. For @FIELD1 in the example, a default null is assigned and the parameter is declared to be an output parameter to be returned by the stored procedure.

The @ID parameter maps to the primary key on a Blackbaud Infinity table. ID is provided to the data form through an expression or a search list. The existence of ID is assumed by the spec and @DATALOADED is a success flag returned by the procedure. Those fields are system parameters and do not have to be defined in the FormMetaData section of the spec. But there must be corresponding FormField elements for @FIELD1, @FIELD2, and @FIELD3 in FormMetaData. @FIELD1, @FIELD2, and @FIELD3 are also returned by the procedure to be loaded into the form.

This line indicates to not return the count of records returned:

	set nocount on;

MSDN: SET NOCOUNT (Transact-SQL). This is suggested as a possible best practice to improve performance in MSDN: CREATE PROCEDURE (Transact-SQL).

The body of the CREATE PROCEDURE statement for an implementation will usually and mostly be some variation of a SELECT statement to retrieve data from the database. In the illustrative example produced by the spec wizard, the set of records returned is narrowed to just those with ID equal to the @ID parameter. The presumption with the example is that only one value for @FIELD1, @FIELD21, @FIELD3 and @CONTEXTID are necessary since the goal is to load data for a single form. The variable @FIELD1 is assigned the value of the FIELD1 field for the row returned by the query.

	select @DATALOADED = 1,
		   @FIELD1 = FIELD1,
		   @FIELD2 = FIELD2,
		   @FIELD3 = FIELD3
	from dbo.TABLE1
	where ID = @ID

A Transact-SQL RETURN statement is an exit statement that returns a status. The following stops execution of the query and returns a status of 0.

  return 0;

MSDN: RETURN (Transact-SQL)

When the spec is loaded from the catalog into the application, the CREATE PROCEDURE is run and the stored procedure is added to the database for use by the data form's implementation. Subsequent loadings of the spec are handled by the platform as changes to the procedure and the platform modifies the CREATE PROCEDURE statement to be an ALTER PROCEDURE statement.

Common Language Runtime Implementations

CLR (Common Language Runtime) data form specs enable business logic beyond reading and writing to the application's transactional database. Two scenarios where this may be helpful are when reading data from an external source such as a web service and to create dynamic Transact-SQL with which to read or write to the application's transactional database.

When a CLR data form spec is created with the SDK wizard, the initial class file for the implementations contains overridden functions for the load and save logic. These functions are contained in a base class designed for to the spec type, in this case Blackbaud.AppFx.Server.AppCatalog.AppViewDataForm.

Imports Blackbaud.AppFx.Server

Public NotInheritable Class ImplementationExample2ViewDataForm
    Inherits AppCatalog.AppViewDataForm

    Public Overrides Function Load() As Blackbaud.AppFx.Server.AppCatalog.AppViewDataFormLoadResult

    End Function

End Class

There are three properties inherited from the base class to help access information about the request and context: RequestContext, RequestArgs, and ProcessContext.

RequestArgs contains information about the original request that initiated the invocation of the CLR implementation. This includes ClientAppInfo and UsesDatabaseConnection.

ProcessContext contains other useful information.

To read from the database, Transact-SQL code can be created within the Load() function and executed with methods in a library such as SqlClient. Accesses to other data sources, whether outside of the application or the application services, can be made using the API for those services.