MVC

Mvc is an old pattern that fits perfectly in environments with request/response nature such as web. It is employed in many server-side technologies like Java, PHP, .NET, NodeJs, Python, etc.

Chameleon makes use of MVC pattern as well. It contains a RoutingMiddleware that together with a MvcMiddleware, make Chameleon an MVC framework.

RoutingMiddleware's main job is finding a route matching current URL and determining name of a controller stored-procedure that will return response of current request. MvcMiddleware is a middleware that runs after routing and executes controller stored-procedure.

In other MVC frameworks, usually controller is defined as a class and actions are defined as its methods. Since SQL Server does not have such a feature or a feature to categorize stored procedures and user-defined functions, in Chameleon a controller stored-procedure is a combination of both a controller and an action.

In general, name of a controller stored procedure follows a simple pattern as below:

dbo.USP_{controller}_{action}

e.g. dbo.USP_Product_List or USP_Home_Index.

The dbo schema, USP prefix, underline separator and even the whole name can all be customized. This is explained in RoutingMiddleware.

All controller stored procedures must have a single int parameter through which the context-id of current request is passed. Inside of the controller stored-procedure the developer should carry out any appropriate task he wants and should finally specify response of current request. Developers are free to directly insert final response into chameleon._response table and set apprpriate headers in chameleon._responseHeaders table based on the response type. However, Chameleon provides a few helper stored-procedures that come in handy and make controller stored-procedures more brief. In he next section, these helpers are explained.

Response Helpers

chameleon.ViewResult

This stored procedure returns a view as the response of current request. It sets Content-Type header to text/html by default.

        CREATE OR ALTER PROCEDURE [chameleon].[ViewResult]
(
  @context_id	int,
  @name		nvarchar(100),
  @model		nvarchar(max),
  @Cache		varchar(500)
)
      

Parameters:

  • @context_id: request context-id
  • @name: view name.
  • @model: model passed to the view
  • @cache: caching options.

Examle:

        CREATE OR ALTER PROCEDURE [dbo].[usp_About_index]
(
  @context_id	int
)
as
begin
  set nocount on

  exec [chameleon].[ViewResult] @context_id, '', '',''
end
GO
      

If @name is not specified, a default value in the format below will be used:

{area ? area + '.' : ''}{controller}.{action}

For example if current URL is /product/list and it is matched to a route like {controller}/{action}, the name that chameleon.ViewResult uses by default for @name parameter will be product.list.

Parametric views

If the view we intend to return is parametric (has a model string parameter), we can pass our desired model to it through @model parameter.

Example:

      CREATE OR ALTER PROCEDURE [dbo].[usp_Product_show]
(
	@context_id	int
)
as
begin
	set nocount on

	declare @id int
	declare @model nvarchar(max)

	set @id = [chameleon].[Route.GetValue](@context_id, 'id')
	set @model = (select * from dbo.Products where productId = @id for json path, without_array_wrapper)

	exec [chameleon].[ViewResult] @context_id, '', @model, ''
end
GO
    

Caching

Using @cache parameter, it is possible to cache a view in order to prevent redundant view rendering and increase performance. The @cache could be an integer (the number of seconds the rendered view should be cached) or a JSON string that specifies caching options in detail.

Example:

      CREATE OR ALTER PROCEDURE [dbo].[usp_Product_show]
(
	@context_id	int
)
as
begin
	set nocount on

	declare @id int
	declare @model nvarchar(max)

	set @id = [chameleon].[Route.GetValue](@context_id, 'id')
	set @model = (select * from dbo.Products where productId = @id for json path, without_array_wrapper)

	exec [chameleon].[ViewResult] @context_id, '', @model, '60'	-- cache for 1 minute (60 seconds)
end
GO
    

You can learn more about Caching in Chameleonhere.

chameleon.FileResult

This stored procedure returns a file as the response of current request.

      CREATE OR ALTER PROCEDURE [chameleon].[FileResult]
(
	@context_id		int,
	@filenameAndPath	nvarchar(4000),
	@bufferSize		int,
	@raiseOnErrors		bit
)
    

Parameters:

  • @context_id: request context-id
  • @filenameAndPath: path to a file in Chameleon File tables
  • @bufferSize: buffer length in order to stream file content towards the host.
  • @raiseOnErrors: raise error if no filename specified

Example:

      CREATE OR ALTER PROCEDURE [dbo].[usp_Product_list_download]
(
	@context_id	int
)
as
begin
	set nocount on

	exec [chameleon].[FileResult] @context_id, '/products/list.pdf', '',''
end
GO
    

chameleon.FileResult sets the following response headers based on the specified file:

  • Content-Type
  • Content-Disposition
  • Content-Length
  • ETag
  • Last-Modified

If @bufferSize is not specified, chameleon.FileResult uses Chameleon.Middlewares.Mvc.BufferSize setting which by default is 32KB.

Streaming file content from SQL Server towards the host increases performance as the host does not need to allocate memory for file content first and writes it onto Http Response. Instead, it binds SQL Server data stream directly to Http Response.

chameleon.RedirectResult

This stored procedure is used to redirect client to another path or URL.

      CREATE OR ALTER PROCEDURE [chameleon].[RedirectResult]
(
	@context_id	int,
	@Url		nvarchar(4000),
	@status		int
)
    

Parameters:

  • @context_id: request context-id
  • @Url: path the user should be redirected to
  • @status: response status when returning redirect result

Possible values for @status when redirecting are as follows:

  • 301 : Moved Permanently
  • 302 : Found
  • 303 : See Other
  • 304 : Not Modified
  • 305 : Use Proxy
  • 306 : Switch Proxy
  • 307 : Temporary Redirect
  • 308 : Permanent Redirect

The default value is 301.

chameleon.ContentResult

This stored procedure is used to return a raw content to the client.

      CREATE OR ALTER PROCEDURE [chameleon].[ContentResult]
(
	@context_id		int,
	@data			nvarchar(max),
	@contentType		varchar(150)
)
    

Parameters:

  • @context_id: request context-id
  • @data: raw content to be returned
  • @contentType: MIME content type

Example:

      CREATE OR ALTER PROCEDURE [dbo].[usp_Home_Index]
(
	@context_id	int
)
as
begin
	set nocount on

	exec [chameleon].[ContentResult] @context_id, '<h1>Hello World</h1>', 'text/html'
end
GO
    

chameleon.StatusCodeResult

This stored procedure is used to return a specific response status code (and optionally a content and content type) to the client.

      CREATE OR ALTER PROCEDURE [chameleon].[StatusCodeResult]
(
	@context_id		int,
	@status			int,
	@data			nvarchar(max),
	@contentType		varchar(150)
)
    

Parameters:

  • @context_id: request context-id
  • @status: returned status code
  • @data: optional raw content to be returned
  • @contentType: MIME content type

Example:

      CREATE OR ALTER PROCEDURE [dbo].[usp_Product_show]
(
	@context_id	int
)
as
begin
	set nocount on

	set @id = [chameleon].[Route.GetValue](@context_id, 'id')

	if not exists (select 1 from dbo.Products where productId = @id)
		exec [chameleon].[StatusCodeResult] @context_id, 404, '', ''
	else
	...
end
GO
    

chameleon.JsonResult

This stored procedure is used to return a json content to the client. It internally sets Content-Type header to application/json.

      CREATE OR ALTER PROCEDURE [chameleon].[JsonResult]
(
	@context_id		int,
	@data			nvarchar(max)
)
    

Parameters:

  • @context_id: request context-id
  • @data: json content to be returned

Example:

      CREATE OR ALTER PROCEDURE [dbo].[usp_Product_get]
(
	@context_id	int
)
as
begin
	set nocount on

	declare @id int
	declare @data nvarchar(max)

	set @id = [chameleon].[Route.GetValue](@context_id, 'id')
	set @data = (select * from dbo.Products where productId = @id for json path, without_array_wrapper)

	exec [chameleon].[JsonResult] @context_id, @data
end
GO
    

Related Settings

[Chamaleon.Middlewares.Mvc.ViewBufferSize]: int (default = 0)

This setting specifies buffer-size for rendered views when they are returning to the host. This increases performance since returned view will be directly streamed from SQL Server to the Http Response.

[Chamaleon.Middlewares.Mvc.BufferSize]: int (default = 32768)

This setting specifies default buffer-size (in Bytes) for returning files using chameleon.FileResult.

[Chamaleon.Middlewares.Mvc.ViewEngine]: string (default = Gila)

This setting specifies default view-engine.