Building ASPNET MVC Applications
Unit of Work Scoping
To scope your UnitOfWork instances on a per request basis you will want to make use of the PerRequestUnitOfWorkScope<TUnitOfWork> helper class which is included as part of the Mindscape.LightSpeed assembly.
First you will want to declare your LightSpeedContext so it is accessible for creating UnitOfWork instances. We recommend that this is done as part of your Global.asax.cs so it is always available.
Example declaration of a static LightSpeedContext in Global.asax.cs |
public static LightSpeedContext<MyModelUnitOfWork> LightSpeedContext |
We recommend that you use the LightSpeedControllerBase<TUnitOfWork> class which is provided as part of the Mindscape.LightSpeed.Web assembly as the base for your controllers, as this provides a per request scoped UnitOfWork which uses PerRequestUnitOfWorkScope<TUnitOfWork> and handles the disposal of any UnitOfWork instances on your behalf by default.
Example controller declaration using LightSpeedControllerBase<TUnitOfWork> |
public class MyController : LightSpeedControllerBase<ModelUnitOfWork> |
By default the LightSpeedControllerBase will dispose of any created UnitOfWork instance as part of the OnResultExecuted handler or alternatively when the controller instance is disposed. If you wish to manually control the disposal behaviour, for example you may wish to dispose it at the end of the request to allow further access to the UnitOfWork instance through an external PerRequestUnitOfWorkScope<TUnitOfWork>, then you will need to set the DisposeUnitOfWorkOnResultExecuted property to false to disable the automatic behaviour.
Example of manual disposal code using the EndRequest event |
public class MyController : LightSpeedControllerBase<ModelUnitOfWork> |
Model Binding for LightSpeed Entities
If you are using the DefaultModelBinder which ships with ASP.NET MVC you may wish to improve the experience in binding your LightSpeed entities. By default the DefaultModelBinder will interrogate the Errors property on a LightSpeed entity causing any errors to be concatenated together.
The Mindscape.LightSpeed.Web assembly includes a custom model binder called LightSpeedEntityModelBinder which can be used with you ASP.NET MVC projects for binding LightSpeed entities. To register this model binder to just handle the entity types in your project, call the static LightSpeedEntityModelBinder.Register method, passing in the assembly which contains your entity types. Only types which derive from Mindscape.LightSpeed.Entity in that assembly will be associated with the LightSpeedEntityModelBinder.
Configuring the use of the ModelBinder in Global.asax.cs |
protected void Application_Start() |
One it has been set up your entities can be unbound either when unbinding takes place for an action argument or manually when you call UpdateModel. The main limitation to be aware of with the LightSpeedEntityModelBinder is that it will not traverse any loaded associations.
An alternative to using the custom model binder provided with LightSpeed is to create your own model binder, likely sub-classing DefaultModelBinder to afford yourself the benefits it already provides. If you take this approach then you will primarily be interested in correctly handling any errors after the model binding takes place. This can be achieved as shown below.
An example of implementing BindModel when sub-classing DefaultModelBinder and handling extracting error messages from your LightSpeed entity |
public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) |
Validation
When you approach validation with ASP.NET MVC you will be interested in handling both client and server side validation concerns. The standard approach for handling validation concerns with ASP.NET MVC is to use Data Annotation attributes. While LightSpeed has its own native validation framework you can use the LightSpeedMvcValidatorProvider which is part of the Mindscape.LightSpeed.Web assembly to automatically supply the appropriate Data Annotation attributes needed to allow automatic validation to be applied by ASP.NET MVC.
To make use of this you need to first add a new instance of the LightSpeedMvcValidatorProvider to your ModelValidatorProviders.Providers collection, typically this would be performed in your Global.asax.cs.
Initializing the LightSpeed Validation Provider in Global.asax.cs |
protected void Application_Start() |
The provider does not surface all LightSpeed validations because the Data Annotations framework does not contain equivalents for all of them. The following LightSpeed validations are surfaced:
· ValidatePresenceAttribute
· ValidateLengthAttribute
· ValidateRangeAttribute (int and double ranges only)
· ValidateFormatAttribute
For server side validation you will likely combine the use of a model binder with the integrated LightSpeed validation to check if an entity is in a valid state following a binding operation. Again for this we would check .IsValid. If you are using a model binder as described in the previous section then any errors will be assigned into ModelState so you can display these when you refresh your view.
An example of checking IsValid following a binding operation using UpdateModel |
try |
Samples
For example code, see the TV Guide MVC 2 sample or the Deals MVC 3 sample both of which have been installed alongside LightSpeed.