Enterprise Asp.Net MVC Part 8: Asp.Net cache before repository

At some point in the life of your software the performance can become an issue. If you have optimized your queries or your Entity Framework configuration, than the next step is to think about keeping some data in memory or in an external cache. This has the advantage to have the data already available.

First of all, we need to have some infrastructure classes and interface because we want to have something flexible and not tightly bound to Asp.Net since this will be used in the Data Access Layer.

public interface ICacheConfiguration
{
	bool IsActivate();
}

The first interface configures the cache. So far, to keep it simple, only one property is set. It is about its activation. Caching system must always have a possibility to be desactivated. The reason is that if your data become not what you expect that you can turn off the cache and use the main persistence. If the problem is solved, than it means that the problem is the cache. Otherwise, the problem is with the persistence or the logic that use the data.

public interface ICacheProvider
{
	void Set<T>(T objectToCache) where T : ICachableModel;

	void Set(string key, Object objectToCache);

	T Get<T>(T key) where T : ICachableModel;

	object Get(string key);

	object Delete(string key);

	T Delete<T>(T objectTodelete) where T : ICachableModel;

	bool IsInCache(string key);

	bool IsInCache<T>(T objectToVerify) where T : ICachableModel;
}

This second interface allows you to have something in front of the technology used. You can have a memory cache, an external caching system or to have an Azure cache behind this interface.

public interface ICachableModel
{
    string GetCacheKey();
}

Most of the methods are defined twice. One use a string key, and the other use a ICachableModel. This interface allows to have the model class to have its logic to built its unique key.

public class MemoryCache:ICacheProvider
{
	private readonly ObjectCache cache;
	private readonly CacheItemPolicy defaultPolicy;
	private readonly ICacheConfiguration configuration;

	public MemoryCache(ICacheConfiguration configuration)
	{
		this.configuration = configuration;
		this.cache = new System.Runtime.Caching.MemoryCache(Constants.Configurations.CacheNameConfiguration);
		this.defaultPolicy = new CacheItemPolicy();
	}

	public void Set<T>(T objectToCache) where T : ICachableModel
	{
		if (configuration.IsActivate())
		{
			cache.Set(objectToCache.GetCacheKey(), objectToCache, defaultPolicy);
		}
	}

	public void Set(string key, object objectToCache)
	{
		if (configuration.IsActivate())
		{
			cache.Set(key, objectToCache, defaultPolicy);
		}
	}

	public T Get<T>(T objectToCache) where T : ICachableModel

	{
		if (configuration.IsActivate())
		{
			return (T) cache.Get(objectToCache.GetCacheKey());
		}
		else
		{
			return default(T);
		}
	}

	public object Get(string key)
	{
		if (configuration.IsActivate())
		{
			return cache.Get(key);
		}
		else
		{
			return null;
		}
	}

	public object Delete(string key)
	{
		if (configuration.IsActivate())
		{
			return cache.Remove(key);
		}
		else
		{
			return null;
		}
	}

	public T Delete<T>(T objectTodelete) where T : ICachableModel
	{
		if (configuration.IsActivate())
		{
			return (T) cache.Remove(objectTodelete.GetCacheKey());
		}
		else
		{
			return default(T);
		}
	}

	public bool IsInCache(string key)
	{
		if (configuration.IsActivate())
		{
			return cache.Contains(key);
		}
		else
		{
			return false;
		}
	}

	public bool IsInCache<T>(T objectToVerify) where T : ICachableModel
	{
		if (configuration.IsActivate())
		{
			return cache.Contains(objectToVerify.GetCacheKey());
		}
		else
		{
			return false;
		}
	}
}

This implementation uses the System.Runtime.Caching as you can see, it also use the configuration to disable the cache. This way to proceed does not affect any of the caller code. In fact, all method return the default value when the cache does not find the value. This should tell to the called to continue with the default persistence strategy.

The caller should be in the Services classes if you have followed previous post about Enterprise Asp.Net MVC application.

var cacheResult = (YouEntity)this.cache.Get("YouUniqueKey123");
if (cacheResult == null)
{
	var repositoryResult = yourRepository.GetYourEntity();
	this.cache.Set("YouUniqueKey123", repositoryResult);
	return repositoryResult;
}
else
{
	return cacheResult;
}

This create a simple architecture for caching. It has the flexibility to use the concrete cache you want and to have high cohesive classes. Configurations could have additional information about how many time the entity must stay in cache, the information about external cache like which IP or PORT to use for MemCached for example.

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

Asp.Net MVC Custom Data Annotation

Asp.Net MVC Data Annotation is a powerful way to have business logic reusable over all your project. Some exist by default in the System.ComponentModel.DataAnnotations namespace. Among the most used Data Annotation is the Required and StringLength attribute.

Data Annotation is used by Asp.Net MVC Data Binder that convert Html input value back into your model. During this process, it calls every validations from Data Annotation. In fact, it use the IValidatableObject interface that you can even have your model inherit to have validation inside a method if you want.

At some point, you may have some validation that are repeated across multiple classes. This is the case for required field. Instead of validating with a IF statement in the Validate method provided by IValidatableObject or to have your setter check of the value of the property, an alternative is the Data Annotation. It has the advantage to be productive for you because you just need to add the attribute over the property and the validation is done. It can also be unit tested once and you can be sure that for every properties that use it that it is executed. Another point for Data Annotation is the possibility to have easily the Javascript doing the same thing for you. This mean that with a single Data Annotation you can have client side and server side validation.

Before going any further in the theory, let’s create a small project with a simple model class the custom Data Annotation is used.

public class MyClass
{
    [PrimeNumberOnly]
    [Display(Name = "Prime Number")]
    public int PrimeNumber { get; set; }
    public DateTime StartDate { get; set; }
    public DateTime EndDate { get; set; }
}

This is the model class. I have created the PrimeNumberOnly attribut which is my custom Data Annotation. I used the Display attribute because will use this instead of the property name in the custom Data Annotation for error. But, this is not required. If it is not declared, the property name is used.

The controller is very simple. It checks for the ModelState to see if it has error, if yes, it displays back the form otherwise it redirects to the list of my class.

[HttpPost]
public ActionResult Create(MyClass myClass)
{
    if (ModelState.IsValid)
    {
        return RedirectToAction("Index");
    }
    else
    {
        return View();
    }
}

Here come what is interesting, the custom Data Annotation.

public class PrimeNumberOnly : ValidationAttribute
{
    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        if (value != null)
        {
            int valueInteger;
            if (int.TryParse(value.ToString(), out valueInteger))
            {
                if (IsPrime(valueInteger))
                {
                    return ValidationResult.Success;
                }
                else
                {
                    return new ValidationResult(string.Concat(validationContext.DisplayName, " is not a prime number"));
                }
            }
            else
            {
                return new ValidationResult(string.Concat(validationContext.DisplayName, " must be an integer"));
            }
        }
        return ValidationResult.Success;
    }

    private bool IsPrime(int number)
    {
        //...
    }
}

The first thing we can notice is the inheritance of the class. It inherits from ValidationAttribute. This is the base class for Data Annotation attribute. It is totally perfect to inherit from an existing Data Annotation like the Required attribute if what you are doing enhance an existing Data Annotation. Therefore, it is not our case since we want to block non-prime number.

This interface lets override a method named IsValid that take two parameters. The first one is the value non-typed. The second is information about the context. The property name, the instance of the the class being validated is also available and the pretty name too (the one that use the display attribute). The IsValid must return Validation.Success if everything is fine. However, if something is wrong, it must return a ValidationResult object. The ValidationResult accepts a message that will be used by Asp.Net MVC to acknowledge. It is also possible to mark not only the property that is being tested but to mark other properties of the class with ValidationResult with the same error.

DataAnnotationError

If you want to pass the ErrorMessage to the attribute, you can. By default, it use the the FormatErrorMessage method that takes the property name. So, if you pass a custom error with a {0} the parameter is substitute. In the code above, the property display name is used and replaced in the error message.

return new ValidationResult(base.FormatErrorMessage(validationContext.DisplayName))

If you want to add the member name you have to supply a second parameter.

return new ValidationResultbase.FormatErrorMessage(validationContext.DisplayName,new []{ validationContext.MemberName}))

In the case you want to have multiple parameters like having numbers or property names to shows, it is possible to combine resource files and formatting. To do, do not use FormatErrorMessage but use the ErrorMessageString and do by yourself the formatting.

return new ValidationResult(string.Format(this.ErrorMessageString,"One", "Two", DateToBeAfter), new[] { validationContext.MemberName);

So far, half of the job is done because if we erase the number and type a valid entry, the error will not go away before the form is submitted again. This is normal, we have coded only the server side aspect of the Data Annotation. A second interface is required to be inherited to have client side validation. This time, it is named IClientValidatable. This interface come from the System.Web.Mvc interface. This mean that if you are using View Model, do not inherit the model from this attribute but the view model. Otherwise, you are mixing back end classes and front end classes. For the purpose of this exercise, I am mapping directly the model class to the view, which mean that it is acceptable to have my model class inherit of System.Web.Mvc.IClientValidatable. Please, do not copy and paste that if you are developing serious application.

The IClientValidatable interface comes with the GetClientValidationRules method. This give us the possibility to extend the html generated for property. When Asp.Net MVC generates the input, it can add additional data- tag. These tag are required for the client side. They are called unobtrusive since it adds information to the Html input without attaching the Javascript. This mean that we have a third step to do which will be to tell Javascript to use those added attribute. But first, why adding data- to our Html input that has the custom Data Annotation? It is required for several reasons. First, if the logic is in error, we need an error message. It cannot be hard coded into the Javascript because this message can be localized. Adding a data- tag with the error message gives you the possibility to get the message and to expose it to your user if the error occurs. Second, you can add additional information to the Html input by attribute like value to be used in the Javascript validation. Here is an example.

public class PrimeNumberOnly : ValidationAttribute, IClientValidatable
{
    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        //...
    }

    private bool IsPrime(int number)
    {

        //...
    }

    public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
    {
        var rule = new ModelClientValidationRule {
            ValidationType = "primenumber",
            ErrorMessage = FormatErrorMessage(metadata.GetDisplayName()),
               
        };

        //This is not required. For the purpose of showing how to pass information to the Javascript I will set two values.
        rule.ValidationParameters.Add("primenumberparam1", "Value1");
        rule.ValidationParameters.Add("primenumberparam2", "Value2");

        yield return rule;
    }
}

In the example above, we are setting a single rule with a validation message (the ErrorMessage) that is set to the data-val-primenumber. I also added two lines that add validation parameters. In a real situation, this can be dynamic value to be checked during the Javascript method that will validate the input. For checking if a number is a prime number, no parameter is required.

Keep in mind that you cannot use capital letter in the ValidationType or you will have a yellow screen of the death with this message:

Validation type names in unobtrusive client validation rules must consist of only lowercase letters. Invalid name: “primeNumber”, client rule type: System.Web.Mvc.ModelClientValidationRule
This generate this Html output:

The result of the Html is :

<div class="col-md-10">
    <input class="text-box single-line" 
           data-val="true" 
           data-val-number="The field Prime Number must be a number." 
           data-val-primenumber="The field Prime Number is invalid." 
           data-val-primenumber-primenumberparam1="Value1" 
           data-val-primenumber-primenumberparam2="Value2" 
           data-val-required="The Prime Number field is required." 
           id="PrimeNumber" 
           name="PrimeNumber" 
           type="number" value="">
            <span 
                class="field-validation-valid" 
                data-valmsg-for="PrimeNumber" 
                data-valmsg-replace="true">
            </span>
        </div>

This need also to have some libraries installed and referenced in your Html page.

    <script src="~/Scripts/jquery.validate.js"></script>
    <script src="~/Scripts/jquery.validate.unobtrusive.js"></script>
    <script src="~/Scripts/PrimeNumberOnlyValidation.js"></script>

You may need to add with NuGet the unobstructive.js.
UnobstructiveJQuery

The validate.js must be before the unobstructive.js file.

The PrimeNumberOnlyValidation.js file contains the validation in Javascript. It is required to be configured once than you just need to have the script added to your file. Here is the complete file:

$.validator.addMethod("primenumber", function (value, element, params) {
    if (value) {
        if (value == 1)
            return false;
        if (value == 2)
            return false;

        for (var i = 3; i < value; i = i + 2) {
            if (value % i == 0) return false;
        }
    }
    return true;
});

$.validator.unobtrusive.adapters.add('primenumber'
                                    , ['primenumberparam1', 'primenumberparam2']
                                    , function (options) {
                                        options.rules["primenumber"] = {
                                            primenumberparam1: options.params.primenumberparam1,
                                            primenumberparam2: options.params.primenumberparam2
                                        };
                                        options.messages["primenumber"] = options.message;
                                    }
                                    );

The first statement register the method to be called when the validation is trigged. It is the same algorithm to check prime number in Javascript than in C#. If it return false, then the error message specified in the C# code is shown. This is possible because the error message is inside the data tag of the input. The tag is “data-val-primenumber”. The second adds an adapter to JQuery validator. The first parameter is the name of the validator. It is the same name than the method. Then, you specify the parameter set in C#. Finally, a anonymous function let you transfert the value of each parameters from C# to the JQuery validation plugin. It does the hook between the html attribute data- generated from C# to Javascript.

Conclusion

If you are getting problem with the plugin, verify that you have all Javascript loaded in the good sequence. To test the plugin, you have to hit the button save. By default, JQuery Validator does not validate on blur but when the form is submitted. Finally, you can get the whole project code in GitHub.

How to create your own Asp.Net MVC Html Helper namespace

Html helper allows to have reusable code around your application about html creation. For example, the Html helper for a textbox create a Html Input of type text. It allows to set the name and the value from the model. Html helpers are a must to use with Asp.Net MVC.

At some point, custom helpers are required to be developed in house for specific needs. A simple approach is to simply create an extension method to the html helper. Here is a small example of creating an Html helper. The Html helper is an extension to the HtmlHelper class.

public static class MyHtmlHelpers
{
	public static MvcHtmlString OutputName(this HtmlHelper helper, string name)
	{
		return new MvcHtmlString(string.Format("<h1>{0}</h1>",name));
	}
}

This can be used into views this way:

@Html.OutputName("Patrick")

The problem with this approach is that is become harder and harder with the time to know which Html Helper are from Asp.Net MVC and which ones is a custom ones. It become also cumbersome to not have namespace inside the helpers.

This problem converge us to this blog post, we will put all customs Html helper into a specific method inside the HtmlHelper. What we want is to create segmentation of all Html Helpers. The following code is the result of what we want to create. Inside the HtmlHelper class, we will inject method that will be our namespaces. We could set all our inputs controler into Input and divide with other “namespace” other Html input. To be short, we will create only the input one in this blog post and only for the creation of a select list. As you will see, we will create a non-generic Helper, like in the code below, but also the generic one. This will give us the possibility to use a lambda expression to specify which property to use instead of specifying it with a string.

@Html.Input().SelectorFor("MyPropertyName", new[] { "Item1","Item2"})
@Html.Image()... //And so on.

First, we need to inject the method for our namespaces.

public static class HtmlHelperNameSpaces
{
	public static HelperExtensionInputFactory Input(this HtmlHelper helper)
	{
		return new HelperExtensionInputFactory(helper);
	}

	public static HelperExtensionInputFactory<TModel> Input<TModel>(this HtmlHelper<TModel> helper)
	{
		return new HelperExtensionInputFactory<TModel>(helper);
	}
}

In the code above, we see that we have two Input method. One takes an HtmlHelper and the other one HtmlHelper. We can have more method for more namespace. The same logic apply. We need to take the HtmlHelper as the first parameter to create the extension. Then, we need to return the Html Helper that has the code.

/// <summary>
/// Generic
/// </summary>
public class HelperExtensionInputFactory<TModel> : HelperExtensionInputFactory
{
	private HtmlHelper<TModel> HtmlHelper { get; set; }

	public HelperExtensionInputFactory(HtmlHelper<TModel> htmlHelper) : base(htmlHelper)
	{
		HtmlHelper = htmlHelper;
	}

	public MvcHtmlString SelectorFor<TValue>(Expression<Func<TModel, TValue>> property, IEnumerable<string> items)
	{
		var meta = ModelMetadata.FromLambdaExpression(property, this.HtmlHelper.ViewData);
		string fullPropertyName = HtmlHelper.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(ExpressionHelper.GetExpressionText(property));

		var selectBuilder = new TagBuilder("select");
		selectBuilder.MergeAttribute("name", fullPropertyName);
		selectBuilder.MergeAttribute("id", fullPropertyName);
		selectBuilder.MergeAttribute("class", "selector");

		foreach (var item in items)
		{
			var optionBuilder = new TagBuilder("option");
			optionBuilder.MergeAttribute("value", item);
			optionBuilder.SetInnerText(item);
			selectBuilder.InnerHtml += optionBuilder.ToString();
		}
		return new MvcHtmlString(selectBuilder.ToString());
	}
}

/// <summary>
/// Non-Generic
/// </summary>
public class HelperExtensionInputFactory
{
	private HtmlHelper HtmlHelper { get; set; }

	public HelperExtensionInputFactory(HtmlHelper htmlHelper)
	{
		this.HtmlHelper = htmlHelper;
	}

	public MvcHtmlString SelectorFor(string fullPropertyName, IEnumerable<string> items)
	{

		var selectBuilder = new TagBuilder("select");
		selectBuilder.MergeAttribute("name", fullPropertyName);
		selectBuilder.MergeAttribute("id", fullPropertyName);
		selectBuilder.MergeAttribute("class", "selector");

		foreach (var item in items)
		{
			var optionBuilder = new TagBuilder("option");
			optionBuilder.MergeAttribute("value", item);
			optionBuilder.SetInnerText(item);
			selectBuilder.InnerHtml += optionBuilder.ToString();
		}
		return new MvcHtmlString(selectBuilder.ToString());
	}
}

The generic version inherit of the non-generic. Both take the HtmlHelper in parameter. This allow to use anything from the Html helper. It gives information about the ViewContext and give you the possibility to use other Html Helper within your Html Helper.

The code in this blog post create an Html Select input for a property passed in parameter and fill everything from a list of string. This could be better to have distinction between caption and value but this is not the goal of this blog post. We could also reuse a lot of code between both… Nevertheless, the interesting part is how everything is bound together. As you can see, only the HtmlHelperNameSpacesis static. Everything underneath is concrete. It also gives the possibility the have generic and non-generic helpers. Finally, we can have several namespace by adding two methods every time to the HtmlHelperNameSpaces class.

HtmlHelper

Here is a screen shot of the code explained above. You can find the source code of namespaced HtmlHelper at GitHub.

IIS 8.0 Application Initialization for fast startup everytime

Since IIS 8, application pool has an advanced option that allow to never sleep. Instead of being active on demand, which boot up the application pool only when someone call the website. This is problematic for performance because the first person to hit the website as a booting time that can be several seconds if not minutes. Even with the configuration that indicate to not recycle the application pool, this has the problem of the first start-up. Also, having the application pool to never reset is not a good practice. In fact, it is a good practice to reset the application pool in a schedule where your website is not in a big time window. For example, if you do not have a lot of visit at 2 am, you can specify to recycle at 2am. Still, before IIS 8.0, this was possible but the first person to hit the website will pay the price. Before going any further, you need to have installed the Application Initialization module. It is free and available by the Web Platform. A link is available if you select inside IIS the root node of your server.

IIS_Application_Initialization

With IIS 7.5 and after, it is possible to select the Start Mode. The Start mode can be “On Demand” or “Always Running”. “On demand” starts the application pool from a HTTP request. “Always running” uses the Windows Process Activation Service (WAS) to start the application pool. This was available with IIS 7.5 but IIS 8.0 does have this configuration within IIS without having to modify any applicationhost.config file. It is more convenient.
IIS_AppPool_AlwaysRunning

To enable the preloaded, a modification to the machine configuration is required. IIS 8 does not have any screen that allow you to enable it. The file is located here : C:\Windows\System32\inetsrv\config\applicationHost.config

<sites>
            <site name="Default Web Site" id="1">
                <application path="/">
                    <virtualDirectory path="/" physicalPath="%SystemDrive%\inetpub\wwwroot" />
                </application>
                <application path="/TestToDelete" applicationPool="II8NoSleep" preloadEnabled="true">
                    <virtualDirectory path="/" physicalPath="C:\inetpub\wwwroot" />
                </application>
                <bindings>
                    <binding protocol="http" bindingInformation="*:80:" />
                </bindings>
            </site>

The line 6 of the previous XML is the one you want. In fact, you need to search for you site which is under the sites XML element. Then, you see the application path that need to be modified. The “preloadedEnabled=true” is the attribute to add. This file needs to be edited with administration privileges.

At this point, any time the application pool is recycled, this one will boot it to be available.

But, since it send a fake request to your website to boot up, would it be great if you could choose which page that the WAS use? Yes and it can be configurable. This a must if you have a page that load data into the cache or to wake up manually other resources. To customize the page to be called by IIS, you need to open the web.config of your website and add a XML element.

<applicationInitialization
    remapManagedRequestsTo="Startup.htm" 
    skipManagedModules="true" >
  <add initializationPage="/default.aspx" />
</applicationInitialization>

The XML has a remapManagedRequestsTo which is the page to be displayed when the loading is executed. Instead of having blank screen with a long loading progress bar, this allow to display a static message to the visitor. The initializationPage is the page to be called by the WAS.

Handling Creation and Edition Screen with EditorFor

Creation and Edition screen share a lot of similar information. The view is the same but change if it has a read only screen. Nevertheless, the create and edit view should share the same cshtml to limit future modification like adding a field or modifying existing fields.

It is possible to have the Creation.cshtml and Edition.cshtml use the same partial class. The code above shows how it can be done.

PartialViewForSharing

One way to do it is to use the html helper EditorForModel. Often, EditorFor and DisplayFor are used for individual input control but this can be used also for regrouping them. So, the EditorForModel is used to share between edition and creation the same group of edition control and inside the EditorTemplates you have a file name that has the model (or view model if you are using view model) used by the controller. Inside the editor templates of the model, you can use EditorFor to leverage the dynamic of editor template for controls.

EditorForForSharedModel

The form are not shared because they generate by the controller that have called them. For example, the edition one.

<form action="/House/Edit/1" method="post">

Using Migration DbMigration class for Up and Down action

Entity Framework (EF) and Migration tools can be used in several ways. The most effective and complete one is to generate DbMigration class by the Entity Framework Migration Tools. It allows to have the creation of the table with all attributes like foreign key, size, primary key and so on. It allows to rollback in the situation that you have to get an older release. Often, this is possible with a source control but it is harder to have the database to be restored in time. Migration tools let you restore the database in the time which is a big plus. Also, it has the advantage to create a a database quickly which is very important for automatically testing or to simply create a new database for a developer. Migration also let you seed data into the database. Instead of having a database empty every time, you can have a database with minimal values.

Before talking about commands that you will use during the development. One command is required to be executed once. It is the one that configure the migration tool.

Enable-Migrations

You can have help by using : get-help Enable-Migrations

You can specify the folder

First of all, there are commands that you will use often. You can create a solution items folder and create power shell scripts with them. This will simplify the use of them. In both case, these commands needs to be executed in the Package Manager Console.

param([String]$migrationName)

Write-Host "MigrationName: $migrationName"

Add-Migration -Name $migrationName `
			  -ConfigurationType YourDLL.Migration.YourDBContextConfiguration `
			  -StartUpProjectName YourStartupDLL `
			  -ProjectName YourDLL.Migration `
			  -Verbose

Usage:

.\AddMigration.ps1 TheMigrationClassToBeGenerated

This first script calls the Add-Migration command. It takes a configuration type. This file inherit from DbMigrationsConfiguration which is generic. The generic type is the DbContext class. This DbContext must have all entities so if you have split your context is several files than you must create a specific one for the migration. Your DbMigrationsConfiguration allows you to override a seeding method. This is where you can specify values to be inserted into your tables. It works by giving in parameter the DbContext that let you insert entity and SaveChanges.

The project name is the parameter that let you specify the migration project. That should be the same project where you have the configuration type. The StatUpProjectName allows the migration tool to know where to search for config file. This is needed to get the connection string.

The power shell script let you configure all these setting once and then just let you specify the file name that contains the generated creation command. The file generated will be prefixed by the data and the time. This allows Entity Framework Migration tool to know the order of the execution of the file.

The second script is to update the database. Let say that your team has created some script with the Add-Migration. The one that executed the code is up-to-date but not you. This is why, to update your database, you need to get the code (from your source control) and then execute a command to update.

The update command is Update-Database. To make it simpler, like the Add-Migration, a small power script can be used.

Update-Database -ConfigurationTypeName "YourDLL.Migration.YourDBContextConfiguration" `
				-ProjectName "YourDLL.Migration"  `
				-StartUpProject "YourStartupDLL" `
				-Verbose 

Parameters are pretty much the same. This time, it will execute migration file. If you want to update not every file but just few files you can set the -TargetMigration. It takes after this command the file name to be the last file to be executed. If you have 10 migrations file and that you want to migrate up to the third file, than you need to target the third file. This can be useful if you need to rollback.

This is almost for it. You could remove all the files creation and use automatic migration. However, you have less control over what is executed. With migration file, you can always edit them to add additional instructions which is handy in the case of complex situation. This is almost all the time the case for enterprise application where rollback method needs to handle foreign key manipulations.

How to generate web.config in every compilation for every build configuration

This article explains how to generate web.config or app.config to every build configurations when compiling. This can be useful if you want to apply transformation for every built without having to compile multiple time. Normally, you have to specify what is the target build to apply the configuration to the web.config. The problem is it requires to compile multiple times for the same code. If you are working in a DEV then TEST then PROD, you have to compile 3 times which could insert bug if code change or is not compiled in the same environment.

This is why, it is better to have all configuration files generated when everything is compiled before any testing. The challenge is that the transformation file is a good system. It allows to not have to copy paste the whole configuration files to change only few settings. To be able to use the transformation within a single compilation, we have to modify the web project file in notepad.

This is the xml code that needs to be pasted into the .csproj at the end of the file within the project xml element.

<Target Name="BeforeBuild">
	<!-- Variable that contains the path of where the configuration file will be located -->
	<ItemGroup>
		<TransformedWebConfigsDir Include="$(OutDir)..\_TransformedWebConfigs" />
	</ItemGroup>
    <!-- MSBuild transform the web.config into the destination folder-->
	<!-- Remove the temporary folder where transformation are located. This is used only after this process as run once -->
    <RemoveDir Directories="@(TransformedWebConfigsDir)" />
	<!-- Create the transformation directory only if not existing. -->
    <MakeDir Directories="@(TransformedWebConfigsDir)" Condition="!Exists('@(TransformedWebConfigsDir)')" />
	<!-- Transform for debug -->
    <TransformXml Source="Web.config" Transform="Web.Debug.config" Destination="@(TransformedWebConfigsDir)\Web.Debug.config" StackTrace="true" />
	<!-- Transform for release -->
    <TransformXml Source="Web.config" Transform="Web.Release.Dev.config" Destination="@(TransformedWebConfigsDir)\Web.Release.Dev.config" StackTrace="true" />
  </Target>
  <Target Name="BeforeClean">
    <RemoveDir Directories="@(TransformedWebConfigsDir)" />
</Target>

The XML creates a target before build that specify an output directory which in my case is named “_TransformedWebConfigs” in the project directory. It cleans everything then it create the directory and apply the transformation for Debug and Release Dev. If you have a Test and Production than you have to have additional lines that specify the Transformation name (build name in Visual Studio) and the destination of the file. As you can see, the XML has a ItemGroup that let you reuse the path everywhere in your MsBuild command.