How to create a mapping to a primitive type with AutoMapper.

If you want to map one of your complex object to a primitive you cannot use the ForMember method of Automapper to do it. Instead, you have to use the ConvertUsing.

Here is a case of ComplexType which reprensent a boolean value.

	Mapper
	.CreateMap<ComplexType, bool>()
	.ConvertUsing(f=>f.ID);

	Mapper
	.CreateMap<bool, ComplexType>()
	.ConvertUsing(f => new ComplexType(f));

This is usefull if you have view models that represent primitive data and you want them to be represented into a view model object.

How to handle a null property with Automapper

AutoMapper is a library that you can find now at GitHub. It’s the same one that has been hosted on CodePlex previously. The purpose of the AutoMapper library is to allow you to transfert value from an object to another. This is usefull when you are working with DTO object or when you need to map properties between your model and view model.

In this article, I’ll show you how to handle a null property. This case occur if you have a source object that has a null property and you want to have in the destination a value. A simple example would be that you have a User class that can have a classe Address. If this one is null, you may want to have in the destination an empty string or a default string value.

public class UserSource
{
	public Address Address{get;set;}
}

public class UserDestination
{
	public string Address{get;set;}
}

First, the mapping require to have the indication of your action.

AutoMapper.Mapper.CreateMap<UserSource, UserDestination>()
					.ForMember(dest => dest.Address
					, opt => opt.NullSubstitute("Address not found")
					);

This indicate to map Address to Address (default behavior) but has the optional with NullSubstitute which let you specify an object to be used for the mapping if the source object is null. In the previous example, a string has been used but a default object could have been used without problem.

Here is how to call the mapper. The mapping is done without any other option than normal mapping.

var model = AutoMapper.Mapper.Map<UserSource, UserDestination>(user);
var models = AutoMapper.Mapper.Map<IEnumerable<UserSource>, IEnumerable<UserDestination>>(users);

Asp.Net MVC with JQuery DatePicker and default custom format date

If you want to use a date picker I suggest you to use JQuery UI Date Picker. It simple, doesn’t require to have a lot of configuration and it’s localized for you in several languages.

The whole process of adding JQuery Date Picker result to download JQuery UI and to create an editor template that will add a class that will let you bind the date picker into it.

Using JQuery UI DatePicker with a default date format in Asp.Net MVC

First step, in the layout you need to add JQuery UI. If you are using Asp.Net MVC 4.0+ you can use the Bundles. This should be located inside the App_Start folder of the project. The configuration is inside BundleConfig.cs.

bundles.Add(new ScriptBundle("~/bundles/jqueryui").Include(
                             "~/Scripts/jquery-ui-{version}.js"));

If you are getting JQuery UI with NuGet package, this will be automatically setup for you. Do not forget to add inside your masterpage (by default : _layout.cshtml) the use of this bundle.

@Scripts.Render("~/bundles/jqueryui")

The second step is to create a template that will be used for the binding of a DateTime type. You can put the template for DateTime into the Views/Shared folder. You just need to create (if not already there) a folder called “EditorTemplates” and create a .cshtml with the name of “DateTime”.

@model DateTime?

@if(Model.HasValue)
{
    @Html.TextBox(string.Empty,Model.Value.Date.ToString("yyyy-MM-dd"), new {@class = "ui-date-picker"})
}
else
{
       @Html.TextBoxFor(m => m, new {@class = "ui-date-picker"})
}

Here is an example. You could use instead of a hard coded format the format you want. In fact, if you do not define here with a ToString() the format you want, you will get the time. This way to proceed let you use JQuery date picker but let you have a default value for your date without the section. If you do not format, you will not only have a default value with date time but when the user will select a date with the date picker, this one will be formatted. Indeed, this will be very strange to have half of the time the date formatted. The first parameter of the TextBox helper is an empty string. This is because the view has a context that is aware of what the field prefix is and we do not need to specify it. Since we do not know which property that will use the template, it’s better to let it empty. We couldn’t use the TextBoxFor method because this one doesn’t let us bind on a method like the ToString.

If you go into the MVC framework we can see that it will check the TemplateInfo to get the current bound property and will assign the name property to the control:

 private static MvcHtmlString InputHelper(HtmlHelper htmlHelper, InputType inputType, ModelMetadata metadata, string name, object value, bool useViewData, bool isChecked, bool setId, bool isExplicitValue, string format, IDictionary<string, object> htmlAttributes)
    {
      string fullHtmlFieldName = htmlHelper.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(name);^
//...

DateTime format without a format. As you can see, the time section is bound.

Last step is to bind JQuery DatePicker to the class ui-date-picker that we have set in the template.

$(document).ready(function () {
 $(".ui-date-picker").datepicker({ dateFormat: 'yy-mm-dd' });
}

This is set in the document ready. This will hook the date picker to all element that has the ui-date-picker class.

How to localize The value ‘{0}’ is not valid for {1}

You cannot simply use an attribute like Required to specify the message your want for an invalid value. What you have to do is to change the default model binding resource class. When the model binder try to convert the input to the type of the model, if this one cannot be converted, a message is sent back to the client in the format : The value ‘{0}’ is not valid for {1}. To change the message, you need to go inside the Global.asax.cs, in the Application_Start method.

You need to set the name of a resource file that you will create.

DefaultModelBinder.ResourceClassKey = "GlobalErrorMessage" 

The file (in our case called GlobalErrorMessage) needs to be inside the App_GlobalResources of the assembly that use the view. Then, you need to add an entry called PropertyValueInvalid. For a French translation, you could use: La valeur ‘{0}’ n’est pas valide pour le champ {1}.

If you mistmatch the name of the resource class key and the file you may receive an error saying that it was correctly embedded.

Could not find any resources appropriate for the specified culture or the neutral culture. Make sure “Resources.MvcFrameworkMessage.resources” was correctly embedded or linked into assembly “App_GlobalResources.lmloxx4z” at compile time, or that all the satellite assemblies required are loadable and fully signed.

To solve this error, just rename the file or change the string. With this solution, you can now have a valid translated error message for invalid data type.

How to modify a FK constraint with Microsoft Server Management Studio 2008 R2

This task should be easy isn’t?

Well, if you go to the Microsoft Server Management Studio (2008 R2) designer to do it and that the constraint is located into a schema other than DBO, this might be more complex that you think.

Rename failed for ForeignKey ‘FK__ABC’. Either the parameter @objname is ambiguous or the claimed @objtype (OBJECT) is wrong. (Microsoft SQL Server, Error: 15248)

What’s happening it that the tool is trying to use SP_RENAME with DBO as the schema. This can be verified with the Sql Profiler. It’s also a known bug that Microsoft should have fixed in their latest release of SQL Server.

To be able to change the foreign key constrain name, you need to do it manually with the SP_RENAME function.

The syntax is ‘YourSchema.YourFKNameToChange’ followed by only the FK you want. Here is an example:

sp_rename 'YourSchema.YourFKNameToChange', 'YourNewFKName', 'OBJECT'

That’s it!

Asp.Net MVC HTTP Error 401.0 – Unauthorized

HTTP Error 401.0 – Unauthorized
You do not have permission to view this directory or page.

When an unauthorized action is trigged, the HttpUnauthorizedResult result called. It produces a 401 error. By default, a 401 error can be handled only by IIS and not directly like a 404 error with Asp. This would be easy if we could set a 401 error page in the web.config, but it’s not the case.

namespace System.Web.Mvc { 

    public class HttpUnauthorizedResult : HttpStatusCodeResult {

        // HTTP 401 is the status code for unauthorized access. Other code might 
        // intercept this and perform some special logic. For example, the
        // FormsAuthenticationModule looks for 401 responses and instead redirects 
        // the user to the login page. 
        private const int UnauthorizedCode = 401;
 
        public HttpUnauthorizedResult()
            : this(null) {
        }
 
        public HttpUnauthorizedResult(string statusDescription)
            : base(UnauthorizedCode, statusDescription) { 
        } 
    }
} 
// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.

What can be done is to transform the 401 error code into a standard code, like the 200 code. This response header code indicate that the webpage has been found. This will let us counter the 401 behaviors and redirect to a specific actions.

public abstract class HttpUnauthorizedWithRedirectToResultBase : HttpUnauthorizedResult
{
	protected ActionResult _result;

	public override void ExecuteResult(System.Web.Mvc.ControllerContext context)
	{
		if (context == null)
			throw new ArgumentNullException("context");

		if (context.HttpContext.Request.IsAuthenticated)
		{
			context.HttpContext.Response.StatusCode = 200;
			InitializeResult(context);
			_result.ExecuteResult(context);
		}
		else
			base.ExecuteResult(context);
	}

	protected abstract void InitializeResult(ControllerContext context);
}

We will create a new http unauthorized that will set area and view name. This will let us set the default page if we do not want to specify every time which action to use. If nothing will be defined, we will be able to simply put in the shared folder a view with the error.

public class HttpUnauthorizedWithRedirectToViewResult : HttpUnauthorizedWithRedirectToResultBase
{
	private readonly string _area;
	private readonly string _viewName;
	
	public HttpUnauthorizedWithRedirectToViewResult(string viewName, string area)
	{
		_viewName = viewName;
		_area = area;
	}

	protected override void InitializeResult(ControllerContext context)
	{
		if (!string.IsNullOrWhiteSpace(_area))
		{
			context.RequestContext.RouteData.DataTokens["area"] = _area;
		}
		_result = new ViewResult{ViewName = _viewName};
	}
}
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = false)]
public class AuthorizeWith401Support : AuthorizeAttribute
{
	private const string VIEW_NAME = "NoAccess401";
	private string _actionName;

	public string ActionName
	{
		get	{return string.IsNullOrWhiteSpace(_actionName)? VIEW_NAME : _actionName;}		
		set { _actionName = value; }
	}

	public string Controller { get; set; }
	public string Area { get; set; }

	protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
	{
		if (filterContext.IsChildAction)
		{
			base.HandleUnauthorizedRequest(filterContext);
		}
		else
		{
			if (string.IsNullOrWhiteSpace(ActionName))
                throw new ArgumentException("You must set an ActionName");

            if (string.IsNullOrWhiteSpace(controller))
                filterContext.Result =  new HttpUnauthorizedWithRedirectToViewResult(ActionName, area);
 		}
	}
}

Now, you need to use it as you would use the AuthorizeAttribute. It’s the same behavior because the AuthorizeWith401Support inherit from AuthorizeAttribute. However, you have the additionnal ‘ActionName’, ‘Area’ and ‘Controller’ property that let you specify the error action. Of course, if nothing is specifie, the action ‘NoAccess401’ will be used.

[AuthorizeWith401Support(Roles = "admin")]
public ActionResult Index()
{
	//...
}

How to have custom role to use with the Authorize attribute of Asp.Net MVC

If you are developing a website with Asp.Net MVC you might use the [Authorize] attribute over actions of your controllers. The Authorize attribute let you mark the method access to a user or a group of user (called role).

[Authorize(Roles = "groupName1, groupeName2")]
public ActionResult Creation()
{
    //...
}

The code in the example above illustrate the authorization of the creation method to the groupeName1 and groupeName2.

The Authorize method use the IPrincipal to get the current username logged. It use the “IsInRole” method. Here is a part of the code from the MVC framework.

public bool IsInRole(string role) 
{ 
    if (_Identity == null)
        throw new ProviderException(SR.GetString(SR.Role_Principal_not_fully_constructed)); 

    if (!_Identity.IsAuthenticated || role == null)
        return false;
    role = role.Trim(); 
    if (!IsRoleListCached) {
        _Roles.Clear(); 

        string[] roles = Roles.Providers[_ProviderName].GetRolesForUser(Identity.Name); 
        foreach(string roleTemp in roles)
            if (_Roles[roleTemp] == null) 
                _Roles.Add(roleTemp, String.Empty);

        _IsRoleListCached = true;
        _CachedListChanged = true; 
    }
    return _Roles[role] != null; 
}

As we can see, it first check if the user is authenticated, if not, then no need to check anything. Then, it checks with the Roles.Providers[].GetRolesForUser(…).

This code call the RoleProvider to get the complete list of roles for the logged user and check if the role specified by the attribute is inside the collection. If it is, then the access is granted, otherwise, a 401 errors will raise.

So, to create a custom role provider, you need to create a new class that inherit from System.Web.Security.RoleProvider. This will let you override two important methods:

  • bool IsUserInRole(string username, string roleName)
  • string[] GetRolesForUser(string username)

The first one will call the second one. The second one, GetRolesForUser is the one used by IPrincipal (and by this mean used by the attribute Authorized).

From here, you can do what ever you want to do. For example, in a project, I had to use the WindowsTokenRoleProvider but to check for a specific suffix. If the user had the suffix “_PROJECTNAME” than it was a possible role, other roles were not checked. That mean that if the user ABC has “admin_PROJECT1” and “admin_PROJECT3” and that this user log to the PROJECT3 that it shouldn’t be authorized. Fine, but the problem was that I couldn’t simply add the attribute over the method with the full name for some reason. I had to use [admin] and not [admin_PROJECT3]. So, the task was to implement a custom RoleProvider, get the list of all available role for the user and then filter by project to return in fact a list of role for the project. Of course, I had to also remove the suffix to be able to return a clean list that would be comparable with the role name like “admin”.

public class MyRoleProvider:System.Web.Security.RoleProvider
{
	private readonly WindowsTokenRoleProvider _windows;

	public MyRoleProvider()
	{
		_windows = new WindowsTokenRoleProvider();
	}

	public override void Initialize(string name, NameValueCollection config)
	{
		base.Initialize(name, config); //config can access attribute specified in the web.config
	}

	public override bool IsUserInRole(string username, string roleName)
	{
		return GetRolesForUser(username).FirstOrDefault(s => s == roleName)!=null;
	}

	public override string[] GetRolesForUser(string username)
	{
                var sufix = "PROJECT1";
		return _windows.GetRolesForUser(username).ToList().Where(s => s.EndsWith(sufix)).Select(s => s.Replace(sufix, string.Empty).ToArray();           
	}
}

Here is a short example, in fact the sufix was taken from a configuration file. From there, it’s possible to use the attribute with the role without having to specify anything about the sufix. The sufix can be set to the configuration file. This could be useful for different deployment server where in some server user have different role. You could set “admin_Testing” and “admin_Production” where you can set developer to “Patrick” a developer the role of “admin_Testing” but not to “admin_Production”. IN the web.config, you just set “_Testing” for the testing environment and on the production “_Production”. So, if Patrick log to the testing environment, he should be able to do what ever this role give him access but no when he goes into production.

The MyRoleProvider is specified in the web.config under system.web

      <roleManager enabled="true" defaultProvider="MyRoleProvider">
        <providers>
          <clear />
          <add name="MyRoleProvider"  type="YourNameSpace.RoleProvider.MyRoleProvider" />
        </providers>
      </roleManager>

The add of the provider element can have custom attribute to add information that can be read by the Role Provider inside the Initialize method.

An attribute argument must be a constant expression, typeof expression or array creation expression of an attribute parameter type

If you are trying to use a static string in an attribute for an action inside a Asp.Net MVC’s controller, you will get a strange error.

An attribute argument must be a constant expression, typeof expression or array creation expression of an attribute parameter type

This is because you are using static string instead of constant.

public static string AdministratorRole="admin";

The code below works because it’s a public const string instead of a public static string.

public const string AdministratorRole="admin";

Enterprise Asp.Net MVC Part 6: The three layers of validation

Validations is definitely a serious subject. If no validation is made, then the system is compromise. Whatever the architecture, whatever the hardware setup and whatever the idea of the product, you need to implement validations to protect your system. This is why it must be taken seriously.

By default, Asp.Net MVC handles validation and also Entity Framework uses the same interface to handle validation entities. So, why not use what is already in place and not try to reinvent the wheel. In fact, we follow the KISS principle.

Here is an overview of the article in a single image.

We have 3 layers of validation. The first layer and third layer are built-in with .Net with the IValidatableObject interface. I have already discussed about this interface for validating entity but I’ll show you how to use it in a more “enterprise way”.

Using IValidatableObject

This interface lets you have a single method called Validate which lets you return error message linked to a property method. If you want a general error, you can also specify an empty string for the property name. Simple? Yes. Powerful? Even more! The framework know this interface and it automatically uses the validation when the model is bound from a Http request to your view model by the Model Binder. The .Net framework automatically call this method when Entity Framework try to save entities to the database. This mean that you have nothing to do, but to add your business logic validation.

From here, it’s interesting to force every model to have this interface and this is why a good place to inherit from IValidatableObject is in the BaseModel.

public abstract class BaseModel : IValidatableObject
{
    public const int NOT_INITIALIZED = -1;
    public int Id { get; set; }

    #region Implementation of IValidatableObject

    public abstract IEnumerable<ValidationResult> Validate(ValidationContext validationContext);

    #endregion

}

Every model have to define the Validate method. If no validation is required, the method is simply empty. Let’s go back with the Workout entity and add some validations.

public class Workout : BaseModel, IUserOwnable
{
    public DateTime StartTime { get; set; }
    public DateTime? EndTime { get; set; }
    public string Name { get; set; }
    public string Goal { get; set; }
    public ICollection<WorkoutSession> Sessions { get; set; }

    public override IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
    {
        if (string.IsNullOrEmpty(Name))
        {
            yield return new ValidationResult("Name is mandatory", new[] {"Name"});
        }
        if (EndTime.HasValue)
        {
            if (StartTime > EndTime.Value)
            {
                yield return new ValidationResult("EndTime must be after the StartTime", new[] {"StartTime", "EndTime"});
            }
        }
    }

    #region Implementation of IUserOwnable

    public int UserId { get; set; }

    #endregion
}

Every time we have an error we return a ValidationResult. We specify a message and an array of properties that are concerned by the error. In this example, the name is validated and the EndTime property too but only when this one is specified.

The first layer of validation : Model Binding inside the controller

We have implemented the IValidatableObject and when a Http request is done to the server, the controller bind the data to the model. Since we are using the ViewModel approach, this validation is not triggered! But, since we have a BaseController and already have defined the new approach of having the model to be automapped automatically it hooks the validation and apply it when the ViewModel is mapped to the Model. (You have to go read previous post of “Business” category to understand why it’s automatically mapped.)

The first modification occurs in the override method OnActionExecuting that should be already overrided with the modification of the mapper. We simply need to check if the model bound is really a IValidatableObject and to trig the validation mechanism.

protected override void OnActionExecuting(ActionExecutingContext filterContext)
{
	base.OnActionExecuting(filterContext);
	if(filterContext.ActionParameters.Any())
	{
		var possibleViewModel = filterContext.ActionParameters.FirstOrDefault(x => x.Value.GetType() == typeof(TViewModel));
		if (possibleViewModel.Value!=null)
		{
			var viewModel = (TViewModel) possibleViewModel.Value;
			var model = (TModel) Activator.CreateInstance(typeof (TModel));
			Model = _mapperFactory.Map(viewModel, model);
			ApplyOwnership();
			ApplyErrorsToModelState();
		}
	}
}

private void ApplyErrorsToModelState()
{
	if (Model is IValidatableObject)
	{
		var errors = (Model as IValidatableObject).Validate(new ValidationContext(this));
		foreach (var validationResult in errors)
		{
			foreach (var memberName in validationResult.MemberNames)
			{
				ModelState.AddModelError(memberName, validationResult.ErrorMessage);
			}
		}
	}
}

What we are doing is a general method that works for any entities. We verify if the Model bound from the ViewModel is really inherited from a IValidatableObject. From here, we do what the framework would do if we weren’t using view model : calling the Validate method of the interface. We then loop all error and assign everything to the ModelState. This will give us the possibility to act like if no view model has been used.

The code above about the method “ApplyErrorsToModelState” could be replaced with the code below to be able to validate the data annotation AND also the IValidatableObject interface.

private void ApplyErrorsToModelState()
{
        ModelMetadata metadata = ModelMetadataProviders.Current.GetMetadataForType(() => Model, Model.GetType());

        foreach (ModelValidationResult validationResult in ModelValidator.GetModelValidator(metadata, this.ControllerContext).Validate(null))
        {
            var propertyName = validationResult.MemberName;
            ModelState.AddModelError(propertyName, validationResult.Message);
        }
}

The code above validate the data annotation and the IValidatableObject. This can be used in a scenario where you need to have deeper validation process. For example here is the same code as above with enhanced validation on the mapping. This required to have split both validation.

private void ApplyErrorsToModelState(TModel model, TViewModel viewModel)
{
    //Data Annotation validation
    ICollection<ValidationResult> result;
    ValidateDataAnnotation(model, out result);
    foreach (ValidationResult validationResult in result)
    {
        foreach (string memberName in validationResult.MemberNames)
        {
            ModelState.AddModelError(memberName, validationResult.ErrorMessage);
        }
    }

    //IValidatableObject validation
    if (Model is IValidatableObject)
    {
        IEnumerable<ValidationResult> errors = (Model as IValidatableObject).Validate(new ValidationContext(this));
        foreach (ValidationResult validationResult in errors)
        {
            if (validationResult is EnhancedMappedValidationResult<TModel>)
            {
                var enhanced = (EnhancedMappedValidationResult<TModel>)validationResult;
                var viewModelPropertyName = _mapperFactory.GetMapper(model, viewModel).GetErrorPropertyMappedFor(enhanced.Property);
                ModelState.AddModelError(viewModelPropertyName, validationResult.ErrorMessage);
            }
            else
            {       
                        
                if (validationResult.MemberNames.Any())
                {
                    foreach (string memberName in validationResult.MemberNames)
                    {
                        ModelState.AddModelError(memberName, validationResult.ErrorMessage);
                    }
                }
                else
                {
                    ModelState.AddModelError(string.Empty, validationResult.ErrorMessage);
                }
            }
        }
    }
    /*
    //This validate underlying entity which can be not fully loaded in the case of reference
    ModelMetadata metadata = ModelMetadataProviders.Current.GetMetadataForType(() => Model, Model.GetType());

    foreach (ModelValidationResult validationResult in ModelValidator.GetModelValidator(metadata, this.ControllerContext).Validate(null))
    {
        var propertyName = validationResult.MemberName;
        ModelState.AddModelViewModelToErrorsMap(propertyName, validationResult.Message);
    }*/
}

private bool ValidateDataAnnotation(object entity, out ICollection<ValidationResult> results)
{
    var context = new ValidationContext(entity);
    results = new List<ValidationResult>();
    return Validator.TryValidateObject(entity, context, results, true);
}
[HttpPost]
public ActionResult Create(WorkoutViewModel viewModel)
{
    if (ModelState.IsValid) //This is the default Asp.Net MVC way to validate entity
    {
    //Save the entity

This is great because it’s the default way to validate object that has been bound in MVC. The IsValid doesn’t only validate our business logic but also validate all data annotation that could have been set. It’s even greater because people that are used to use the ModelState for validation won’t have to learn a new way to act with controllers because it’s the same.

The second layer of validation : Service layer

So far, the validation works fine but it doesn’t handle the case that you need to validate across many entities. You can have case that you need to validate an entity dependently of the value of others entities. It can also be a validation from some value that are inside the database. Since Model doesn’t have access to the repository, at this moment, we couldn’t validate. To solve this problem, the second layer of validation is required and the perfect place it’s in the Service layer. The reason is that this layer does have access to all entities and also have access to all repositories. Contrary to the first layer of validation, this one will require some manual explicit call for validation. The concrete implementation of this second layer of validation will be done with the Workout entity. What we want to implement is a validation that the active user cannot create more than 3 workouts per month without a premium account. That mean that we need to go check in the database the amount of workout for a specific user for a specific month. This couldn’t be validate in the Workout class because it doesn’t have access to the database.

public int Create(Workout model)
{
     int amountWorkout = Repository.Workout.GetAmountWorkoutForCurrentMonth();
     if (amountWorkout>3)//More than 3 workouts done without premium account
     {
        throw new ValidationErrors(new GeneralError("You have reach the limit of 3 workouts per month, you need premium or wait the next month"));
     }
     return Repository.Workout.Insert(model);
}

This get the amount of workout for the month and if it’s over a certain threshold will raise the error.

The error is handled by the controller that verify that the action executed has been completed without error. Here is the Create action of the Workout controller with the first layer validation and with the catch for the second layer.

[HttpPost]
public ActionResult Create(WorkoutViewModel viewModel)
{
	if (ModelState.IsValid)
	{
		try
		{
			_service.Create(Model);
		}
		catch (ValidationErrors propertyErrors)
		{
			ModelState.AddValidationErrors(propertyErrors);
		}
	}
	return View("Create");
}

The exception type is ValidationErrors which is our custom error handler. The reason is that we do not want to use specific exception from other layers. This is why cross layers classes will be used to transport exception through all layers. This will be discussed after the third layer of validation.

The third layer of validation : Persistence layer

The persistence layer is where the call to the database is done. This is an automatic validation with Entity Framework that call the IValidatableObject interface of the entity before save it to the database.

But, since we do not want to raise a DbEntityValidationResult up to the controller (because it’s a class that belong to Entity Framework (System.Data.Entity.Validation), we will use our own exception classes.

We will create an interface that will hold the property name in error and also the error message.

public interface IBaseError
{
    string PropertyName { get; }
    string PropertyExceptionMessage { get; }
}

Two classes will inherit from this interface. One for a property error and one for a general error.

public class PropertyError:IBaseError
{
    public string PropertyName { get; set; }
    public string PropertyExceptionMessage { get; set; }
    public PropertyError(string propertyName, string errorMessage)
    {
        this.PropertyName = propertyName;
        this.PropertyExceptionMessage = errorMessage;
    }
}

public class GeneralError:IBaseError
{
    #region Implementation of IBaseError

    public string PropertyName { get {return string.Empty; }}
    public string PropertyExceptionMessage { get; set; }

    public GeneralError(string errorMessage)
    {
        this.PropertyExceptionMessage = errorMessage;
    }

    #endregion
}

Then, we add the interface IValidationErrors which holds all IBaseError to be send back through all layers.

public interface IValidationErrors
{
    List<IBaseError> Errors { get; set; }
}

The first implementation can be used anywhere, like in the service layers.

public class ValidationErrors : Exception, IValidationErrors
{
    public List<IBaseError> Errors { get; set; }
    public ValidationErrors()
    {
        Errors = new List<IBaseError>();
    }

    public ValidationErrors(IBaseError error): this()
    {
        Errors.Add(error);
    }

}

The second is more specific to database.

public class DatabaseValidationErrors : ValidationErrors
{
       
    public DatabaseValidationErrors(IEnumerable<DbEntityValidationResult> errors):base()
    {
        foreach (var err in errors.SelectMany(dbEntityValidationResult => dbEntityValidationResult.ValidationErrors))
        {
            Errors.Add(new PropertyError(err.PropertyName,err.ErrorMessage));
        }
    }
}

The last one is used by the repository. In fact, when we SaveChanges() to the database, we need to validate before Entity Framework executes the SaveChanges. Of course, we could let Entity Framework but we would have to catch the exception. Since they are a way without having to catch an exception, I prefer to use it.

If you remember correctly, our DatabaseContext inherit from IDatabaseContext which have SaveChanges() method. We simply need to override this one instead of relying on the one from DbContext and call the DbContext one if everything is fine.

public override int SaveChanges()
{
    var errors = this.GetValidationErrors();
    if (!errors.Any())
    {
        return base.SaveChanges();
    }
    else
    {
        throw new DatabaseValidationErrors(errors);
    }
}

The exception thrown will loop all errors and be trig to a higher level. In fact, this exception is raised to the service layer which doesn’t handle the exception. So, the exception will be raised to the controller layer. This is the same patch of exception than having an exception thrown from the service in the layer 2 because of business logic validation! We are reusing the same mechanism and this is possible because of the exceptions classes we have created which are abstracted with interface.

Model State and custom exceptions classes

If you remember, the controller does have a catch for ValidationErrors.

//...
catch (ValidationErrors propertyErrors)
{
     ModelState.AddValidationErrors(propertyErrors);
}

By default, the model state doesn’t have this method that accept our interface IValidationErrors. This is an extension method.

public static class ControllersExtensions
{
    public static void AddValidationErrors(this ModelStateDictionary modelState, IValidationErrors propertyErrors)
    {
        foreach (var databaseValidationError in propertyErrors.Errors)
        {
            modelState.AddModelError(databaseValidationError.PropertyName, databaseValidationError.PropertyExceptionMessage);
        }
    }
}

Using IValidationErrors lets handle errors from the service layer or the database error. In fact, at this point, it doesn’t really matter because we want to loop through all exceptions and to use the model state to attach doesn’t exception to the correct property (or if general exception to the string.empty which will be a global error message).

Conclusion

Validation of the model could be more complex. It could have been used external classes for each validation. We could have create our own system for validation message and not using the IValidatableObject interface. We could have completely not using the ModelState and create our own html helper with custom mechanism for validating across all layers. We could have add a layer of abstraction between Entity Framework and the service and to handle validation there. But at the end, having solution that are short and efficient seem to be better in my point of view. The current solution give a lot of flexibility concerning the validation and keep the code easy to maintain. In fact, add a validation are a two steps. First, where the validation should be coded? Second, adding the validation. I have seen patterns for validation that goes so beyond MVC and respect even more the single responsibility principle that adding a single validation take over 30 minutes. For me, this is not acceptable. Abstractions levels never should make the development of the code harder. In theory, adding levels of abstraction ain’t cost a thing, but in real enterprise code, where people have to maintain the code base, this can lead to problem.

The solution proposed here use layers previously defined without adding overhead to handle validation.

Series Articles

Article #1: Asp.Net MVC Enterprise Quality Web Application
Article #2: Asp.Net MVC Enterprise Quality Web Application Model
Article #3: Asp.Net MVC Enterprise Quality Web Application Controller
Article #4: Asp.Net MVC Enterprise Quality Web Repository Layer
Article #5: Asp.Net MVC Enterprise Quality Web with Entity Framework
Article #6: Asp.Net MVC Enterprise Quality Layers
Article #7: Asp.Net MVC Enterprise Quality Web Security

Source code on GitHub

Enterprise Asp.Net MVC Part 5: Database Context and Impersonate data

The database context is abstracting the connection between entity and Entity Framework. We won’t abstract all method of the Entity Framework and Linq to Entity like “Where”, “Select”, “Find”, “First”, etc but we will abstract the entry point : DbSet. In fact, the reason is to be able to add ability to impersonate later and to be able to configure your entity that you need to have this DatabaseContext. The role of the factory is not to configure Entity Framework, neither to impersonate. The database context role is to do those task.

public interface IDatabaseContext   
{
	int SaveChanges();
	IDbSet<TEntity> SetOwnable<TEntity>() where TEntity : class, IUserOwnable;
	DbSet<TEntity> Set<TEntity>() where TEntity : class;
	DbEntityEntry<TEntity> Entry<TEntity>(TEntity entity) where TEntity : class;
	void InitializeDatabase();
	UserProfileImpersonate Impersonate(ICurrentUser userProfile);
}

For the moment, the interface of IDatabaseContext looks like this. We have a SaveChanges because we might want to do operation over several repository and want to manually commit changes in a specific time. This will be the role of SaveChanges method. The SetOwnable<> method will act like the default Set method but will automatically assign the user to the entity. This will be good for the loading and for the saving. When in the loading, we won’t have to specify every time that we want the workout for the userA, etc. It will be automatically. This save us time, possibility of error and also improve the security because by default, everything will be bound the the current user. The InitializeDatabase method will be a method to configure extra database stuff. For example, in this project, I am using this method to setup the WebSecurity (membership layout for WebMatrix). The last method is the method that will give us some impersonation for the time of a query depending of another user profile.

public class DatabaseContext : DbContext, IDatabaseContext
{
	public const string DEFAULTCONNECTION = "DefaultConnection";

	public DatabaseContext(IUserProvider userProvider)
	{
		UserProvider = userProvider;

		base.Database.Connection.ConnectionString = ConfigurationManager.ConnectionStrings[DEFAULTCONNECTION].ConnectionString;
		Configuration.ProxyCreationEnabled = false;
	}

	public IUserProvider UserProvider { get; set; }

	public ICurrentUser CurrentUser
	{
		get { return UserProvider.Account; }
	}

        public new DbSet<TEntity> Set<TEntity>() where TEntity : class
        {
            if (typeof(IUserOwnable) is TEntity)
            {
                throw new SecurityException("You cannot by pass the ownable security");
            }
            return base.Set<TEntity>();
        }
	public IDbSet<TEntity> SetOwnable<TEntity>() where TEntity : class, IUserOwnable
	{
		return new FilteredDbSet<TEntity>(this, entity => entity.UserId == CurrentUser.UserId, entity => entity.UserId = CurrentUser.UserId);
	}

	public void InitializeDatabase()
	{
		WebSecurity.InitializeDatabaseConnection(DEFAULTCONNECTION, "UserProfile", "UserId", "UserName", autoCreateTables: true);
	}

	protected override void OnModelCreating(DbModelBuilder modelBuilder)
	{
		base.OnModelCreating(modelBuilder);
		//Call here some other classes to build the configuration of Entity Framework
	}

	public UserProfileImpersonate Impersonate(ICurrentUser userProfile)
	{
		return new UserProfileImpersonate(this, userProfile);
	}
}

This is a small example. That talk for itself. The two interesting part is the SetOwnable that use a FilteredDbSet which the code has been trimmed from a version that you can find over the web and that we will discuss later. The other part is the Impersonate method that we will talk now.

Lets start with the end result. For now, if you want to insert into the database a new Workout entity you need in the WorkoutRepository to do :

DatabaseContext.SetOwnable<Workout>().Add(entity);      

This will automatically insert a new workout to the current logged user. If you want to change the user, you could use the Set but because we override the Set method and check if the it inherit from the IUserOwnable interface. This is the required interface to use SetOwnable method. This way, we can get the user id. But, to protect developer to by pass this mechanism, an exception is thrown if we use Set method with entity that are ownable. That doesn’t mean that you cannot save to an other user, but will require more work with impersonating. Why adding some over head and not letting the developer directly use the Set when he want to save an entity to someone else authority? Simply because all entity will inherit from IUserOwnable because it will be a lot easier to work with without having to always specify the user inside the repository. Also, repository doesn’t have access directly to the user id. That’s say, it’s a painful process. Not letting access directly to the Set avoid the mistake to simply user Set method for an entity. An exception will be thrown and the developer will automatically remember to user the SetOwnable method instead. If he really mean to use the Set method, than the impersonate method will be appropriate.

For general entity, let say that we have a list of status that are shared across all entities or shared across all users, the entity won’t inherit of IUserOwnable because it’s not a user ownable entity. So in theory it works, let check in practice!

using (var db = DatabaseContext.Impersonate(new UserProfile { UserId = 1 }))
{
     db.SetOwnable<Workout>().Add(entity);
}

This would be in the repository instead of the last piece of code. As you can see, we impersonate with a UserProfile with the Id 1. The code is around curly bracket and give us the scope of when the impersonation start and end.

The DatabaseContext class implementation of Impersonate simply call a new DbContext.

public UserProfileImpersonate Impersonate(ICurrentUser userProfile)
{
    return new UserProfileImpersonate(this, userProfile);
}

A new class is used because we want to have a scope which is done by inherit from IDisposable interface. we will create a new instance of Impersonate and dispose it to come back with the real Current User and not the impersonate one. The class is mostly the same as the DbContext but has a reference to the user profile before the impersonate because we want to set it back once it’s done.

public class UserProfileImpersonate : IDatabaseContext, IDisposable
{
	private readonly DatabaseContext _databaseContext;

	private readonly IUserProvider _oldUserProvider;

	#region Implementation of IDisposable

	public UserProfileImpersonate(DatabaseContext dbContext, ICurrentUser userProfile)
	{
		_databaseContext = dbContext;
		_oldUserProvider = dbContext.UserProvider;
		_databaseContext.UserProvider = new ImpersonateUserProvider(userProfile);
	}

	public void Dispose()
	{
		_databaseContext.UserProvider = _oldUserProvider;
	}

	#endregion

	#region Implementation of IDatabaseContext

	public int SaveChanges()
	{
		return _databaseContext.SaveChanges();
	}

	public IDbSet<TEntity> SetOwnable<TEntity>() where TEntity : class, IUserOwnable
	{
		return _databaseContext.SetOwnable<TEntity>();
	}

	public DbSet<TEntity> Set<TEntity>() where TEntity : class
	{
		return _databaseContext.Set<TEntity>();
	}

	public DbEntityEntry<TEntity> Entry<TEntity>(TEntity entity) where TEntity : class
	{
		return _databaseContext.Entry(entity);
	}

	public void InitializeDatabase()
	{
		_databaseContext.InitializeDatabase();
	}

	public UserProfileImpersonate Impersonate(ICurrentUser userProfile)
	{
		return _databaseContext.Impersonate(userProfile);
	}

	#endregion
}

Simple isn’t? We simply call the same database context method but only change the current logged user profile. Single task to do which respect the single responsibility principle.

Series Articles

Article #1: Asp.Net MVC Enterprise Quality Web Application
Article #2: Asp.Net MVC Enterprise Quality Web Application Model
Article #3: Asp.Net MVC Enterprise Quality Web Application Controller
Article #4: Asp.Net MVC Enterprise Quality Web Repository Layer
Article #5: Asp.Net MVC Enterprise Quality Web with Entity Framework
Article #6: Asp.Net MVC Enterprise Quality Layers
Article #7: Asp.Net MVC Enterprise Quality Web Security

Source code on GitHub