суббота, 31 августа 2013 г.

HTTP Redirection in IIS 7 on Windows Server 2008

If you have a website and want to change domain names or if you need to change the architecture of your site, you won’t want visitors following links from other sites and search engines such as Google to get an error while visiting your website. This can cause visitors to click away and a loss of rankings in the search engines.
Luckily there is a fairly simple and straightforward way to remedy the situation through the use of redirects. First, let’s look at the different types of redirects that are available in IIS 7:
  • 301 – Permanent: This redirect tells the Web client that the location of the requested resource has moved permanently
  • 302 – Standard: This redirect tells the Web client to issue a new request to the location specified
  • 307 – Temporary: This redirect tells the Web client to resend POST data, which prevents a Web browser from losing data when the browser issues an HTTP POST request
In most circumstances you will want to use a 301 redirect, as this will inform search engines to update their index with the resource’s new location. In some cases a 302 will be appropriate if the change is going to be short term such as a special page that is seasonal.
For this article I will assume that you already have a site setup on a Windows Server 2008 system setup in a web server role, and are familiar with getting into IIS manager.

Redirect to a Different URL

The first and most simple of the redirects will go from one domain to another, useful if you are changing domain names. I have setup the following two domains TSOriginal.com andTSRedirect.com on my test server as you can see:
IIS 7 Redirection - 1
As you can see, we setup the original domain as TSOriginal.com and have put a simple index.html file in place that looks like this:
IIS 7 Redirection - 2
Now let’s walk through the steps required to setup a redirect to our target domainTSRedirect.com. If it works correctly then we should see the new index.html page below:
IIS 7 Redirection - 3
1. Open IIS Manager by going to Start -> Administrative Tools -> IIS Manager
IIS 7 Redirection - 4
2. Once IIS Manager opens, expand the WebServer, then the Sites folder, and choose the domain, in this case TSOriginal.com.
IIS 7 Redirection - 5
3. Click on HTTP REDIRECT in the main panel
IIS 7 Redirection - 6
4. Place a check next to Redirect requests to this destination: and fill in the target url in the text box below. In this instance it will be TSRedirect.com.
IIS 7 Redirection - 7
5. In the Redirect Behavior we have several decisions to make about how we want the redirects to work. Let’s explore each of these options.
  • Redirect all requests to exact destination – If this object is checked all requests no matter what the original destination will be redirected to the exact location in the text box above. If unchecked everything will be redirected relative to the destination.
  • Only redirect requests to content in this directory (not subdirectories) – By default, when you enable redirection, content can be served by subdirectories below the main directory. If you choose this option you can limit requests to just the directory you want without effecting the subdirectories.
  • Status Code – In this drop down you choose which status code to return when redirecting. As discussed earlier in this article your options are 301302, and 307.
6. For this example we will leave everything unchecked and set a status of 301 in the dropdown menu. Click Apply to set the options.
IIS 7 Redirection - 8
7. The changes are now in place and if we navigate to TSOriginal.com it will redirect us to TSRedirect.com.
To test if the 301 status redirects correctly we will use the live HTTP headers plugin for Firefox. It will allow us to see the status codes. Here are the results for the test:
IIS 7 Redirection - 9
As you can see from the highlighted area the status was returned 301.
All requests now for TSOriginal.com will be sent to TSRedirect.com with a 301 status code relative to the domain name.

Redirect a Single Page to Another Page on the Same Site

This type of redirect is especially useful when you might have some temporary changes to a webpage because of seasonal or holiday changes.
In the case of a seasonal page that will return to normal after a short time, it is best to use a 302redirect. This lets search engines and other sites know that this change is expected and not to change their index or links.
For this example we have removed the site redirect we had placed on TSOriginal.com, and added two pages of content to the site:
oldpage.html
IIS 7 Redirection - 10
newpage.html
IIS 7 Redirection - 11
Now let’s setup a temporary 302 redirect from oldpage.html to newpage.html while.
1. Select the site in IIS manager that you want to set the redirect for.
2. In the Features window switch to Content View, Right click on the page you want to work with, oldpage.htm in this case, and left click on Switch to Features View
IIS 7 Redirection - 12
3. The page now selected in the Connections Pane, click on HTTP Redirect in the features pane
IIS 7 Redirection - 13
4. Check the box next to Redirect requests to this destination, and fill in the destination pagenewpage.htm and set the dropdown menu to 302, and click Apply.
IIS 7 Redirection - 14
5. Now if we navigate to the page TSOriginal.com/oldpage.htm we will be redirected toTSOriginal.com/ newpage.htm.
We will again use the Live HTTP Headers plugin for Firefox to view the redirect. As you can see the pages redirect with the correct 302 status code.
IIS 7 Redirection - 15
You are now ready to do basic redirects in IIS 7 on Windows 2008 server.
These redirects can also be setup using Appcmd.exe at the command line, but this is beyond the scope of this article. If you’re interested check out the Live HTTP plug-in for Firefox.

The log or differential backup cannot be restored because no files are ready to rollforward.

If you have found this page, it is likely that you encountered the following error when you tried to restore a differential backup using Microsoft SQL Server 2005. Restore failed for Server ''. (Microsoft.SqlServer.Smo) Additional Information:System.Data.SqlClient.SqlError: The log or differential backup cannot be restored because no files are ready to rollforward. (Microsoft.SqlServer.Smo) What this error is telling you is that there is no database that was left in non-operational mode, and thus has not been cleaned up such that uncommitted transactions have not been rolled back. The easy way to reproduce this error is to backup your database using full recover model, and do full and differential backups. Once you have your full and differential backup files you, if you want to restore your database all you have to do is restore the full backup first, and then one of the differential files (differential backups have all the changes since the last full backup) that brings you up to the point you want to restore to. You will get the above error when you try to restore the differential backup (after you just restored the full backup). Unfortunately, you forgot one critical detail (just like I did at first). You MUST restore all but the last (in this case the full backup) with NORECOVERY option. In the Microsoft SQL Server Management Studio there are three options on the Option "page" when you restore a database. Option 1 (the default): Leave the database ready to use by rolling back uncommitted transactions. Additional transaction logs cannot be restored.(RESTORE WITH RECOVERY) Option 2: Leave the database non-operational, and do not roll back uncommitted transactions. Additional transaction logs can be restored.(RESTORE WITH NORECOVERY) To properly restore a database that is backup up using full recovery mode with full and differential backups, here are the steps you need to follow to not get the above error. Restore Full backup
  1. Open the Restore Database window in Microsoft SQL Server Management Studio
  2. Ensure the To database field is filled in with the name you want.
  3. Choose From device as the Source for restore.
  4. Choose the full backup file you want to restore. In most cases this is the most recent full backup file.
  5. Click the Options page on the left navigation.
  6. Choose Leave the database non-operational, and do not roll back uncommitted transactions. Additional transaction logs can be restored.(RESTORE WITH NORECOVERY). This is the most important step!!!
Restore Differential backup
  1. Open the Restore Database window in Microsoft SQL Server Management Studio
  2. Ensure the To database field is filled in with the name you want. The same that you specified in step 2 for the Restore Full backup
  3. Choose From device as the Source for restore.
  4. Choose the differential backup file you want to restore. In most cases this is the most recent differential backup file.
  5. Click the Options page on the left navigation.
  6. Choose the default: Leave the database ready to use by rolling back uncommitted transactions. Additional transaction logs cannot be restored.(RESTORE WITH RECOVERY) Make sure to choose this if you want to use your database after the restore.
That is it, no more error. If you are lucky :)

Automated differential backup using 7zip for linux/windows

There are a lot of ways of doing differential backups, tons of software, freeware of shareware. I want to share one I didn't know about which I liked very much. It is unfair so little information can be found the Net about 7-zip archival tool, which can handle differential backups with ease.  Article is for CLI geeks, who understands where to push these commands )

What are Differential and Incremental backups?

Incremental backup

is a backup method in which multiple backups are kept (not just the last one). These backups will be incremental if each original piece of backed up information is stored only once, and then successive backups contain only the information that changed since a previous backup.

Differential backup

is a cumulative backup of all changes made since the last full or normal backup, i.e., the differences since the last full backup
I am talking about Differential backup, which contains one FULL archive and several DIFFERENTIAL archives on different date each.

Using 7zip for automated backup

Is really great tool for archiving files. Linux and win32 platform support, crossplaform archiving, multi threading support.

7zip installation

  1. Windows, download
  2. Ubuntu: aptitude install p7zip

7zip commands to create a backup of files

First step is to create full backup which is fairly easy:
7za a c:\archive.7z  c:\folder_to_archive
Next is to create differential backup with name diff1.7z
7za u c:\archive.7z  c:\folder_to_archive  -ms=off -mx=9 -t7z -u- -up0q3r2x2y2z0w2!c:\diff1.7z
  • Where command switches stand for:
  • -mx=9 - best compression
  • -t7z - 7z archive type
Wtf "-up0q3r2x2y2z0w2!c:\diff1.7z" is ?
Actions mask to determinite 7z behavior
p - File exists in archive, but is not matched with wildcard.
q - File exists in archive, but doesn't exist on disk.
r - File doesn't exist in archive, but exists on disk.
x - File in archive is newer than the file on disk.
y - File in archive is older than the file on disk.
z - File in archive is same as the file on disk
w - Can not be detected what file is newer (times are the same, sizes are different)
Number means action:
0 Ignore file (don't create item in new archive for this file)

1 Copy file (copy from old archive to new)

2 Compress (compress file from disk to new archive)

3 Create Anti-item (item that will delete file or directory during extracting). This feature is supported only in 7z format
More detailes on this switch here:

How to extract files from 7zip differential backup

First step is to extract full backup  archive:
7za.exe x c:\archive.7z -oc:\recovery_path\
Next,  to extract needed differential  backup on top to the same folder
7za.exe x c:\archive.7z -aoa -y -oc:\recovery_path\
-aoa Overwrite All existing files without prompt.
-y (assume Yes on all queries) switch
After extraction destination folder will contain exact structure and files on date of backup!

What is 7zip anti-item

When creating differential archive 7zip matches files that have been deleted and creates anti-file entry which tells 7zip extractor actually do delete file when overriding master archive. Thats why resulting recovery folder will look the same as on archiving stage.

7zip backup limitations

DO NOT USE the 7-zip format on Linux/Unix  for system backup purposes, because of 7zip does not store the owner/group of the file.
On Linux/Unix, in order to backup directories you should use tar
to backup a directory
tar cf – directory | 7za a -si directory.tar.7z
to restore your backup :
7za x -so directory.tar.7z | tar

SQL Server Full Backups

OverviewThe most common types of SQL Server backups are complete or full backups, also known as database backups.  These backups create a complete backup of your database as well as part of the transaction log, so the database can be recovered. This allows for the simplest form of database restoration, since all of the contents are contained in one backup.
ExplanationA full backup can be completed either using T-SQL or by using SSMS.  The following examples show you how to create a full backup.

Create a full backup of the AdventureWorks database to one disk file
T-SQL
BACKUP DATABASE AdventureWorks TO DISK = 'C:\AdventureWorks.BAK'
GO
SQL Server Management Studio
  • Right click on the database name
  • Select Tasks > Backup
  • Select "Full" as the backup type
  • Select "Disk" as the destination
  • Click on "Add..." to add a backup file and type "C:\AdventureWorks.BAK" an click "OK"
  • Click "OK" again to create the backup

SQL Server Differential Backups

OverviewAnother option to assist with your recovery is to create "Differential" backups.  A "Differential" backup is a backup of any extent that has changed since the last "Full" backup was created.
ExplanationThe way differential backups work is that they will backup all extents that have changed since the last full backup.  An extent is made up of eight 8KB pages, so an extent is 64KB of data.  Each time any data has been changed a flag is turned on to let SQL Server know that if a "Differential" backup is created it should include the data from this extent.  When a "Full" backup is taken these flags are turned off.
So if you do a full backup and then do a differential backup, the differential backup will contain only the extents that have changed.  If you wait some time and do another differential backup, this new differential backup will contain all extents that have changed since the last full backup.  Each time you create a new differential backup it will contain every extent changed since the last full backup.  When you go to restore your database, to get to the most current time you only need to restore the full backup and the most recent differential backup.  All of the other differential backups can be ignored.
If your database is in the Simple recovery model, you can still use full and differential backups. This does not allow you to do point in time recovery, but it will allow you to restore your data to a more current point in time then if you only had a full backup.
If your database is in the Full or Bulk-Logged recovery model you can also use differential backups to eliminate the number of transaction logs that will need to be restored.  Since the differential will backup all extents since the last full backup, at restore time you can restore your full backup, your most recent differential backup and then any transaction log backups that were created after the most recent differential backup.  This cuts down on the number of files that need to be restored.

Create a differential backup of the AdventureWorks database to one disk file
T-SQL
BACKUP DATABASE AdventureWorks TO DISK = 'C:\AdventureWorks.DIF' WITH DIFFERENTIAL
GO
SQL Server Management Studio
  • Right click on the database name
  • Select Tasks > Backup
  • Select "Differential" as the backup type
  • Select "Disk" as the destination
  • Click on "Add..." to add a backup file and type "C:\AdventureWorks.DIF" and click "OK"
  • Click "OK" again to create the backup

четверг, 8 августа 2013 г.

Understanding Database Initializers in Entity Framework Code First


Entity Framework Code First allows you to create data model classes prior to creating a database. When you run the application for the first time, a database is created for you on the fly based on the classes you created. Database initializers allow you to decide a strategy of database creation and seed data generation. Code First provides its own set of database initializer classes and also allows you to create your own. In this article you will learn to use the inbuilt database initializers in your application. You will also learn to create your own database initializers. Additionally, the article will illustrate how to populate a database with seed data during the initialization process.
Note:
This article will not discuss the basics of Code First. If you are not familiar with Code First readIntroduction to Entity Framework Code First. You will be using the same code sample in this article and we won't discuss the sample application in detail again.

What is Database Initialization?

A database initializer is a class that takes care of database creation and initialization in a Code First application. It is the job of database initializer to create the database and required tables based on the data model classes you create. To understand the role of database initializer, let's create a simple console application (see code download accompanying this article).
Have a look at the following model classes from the application:
  1. [Table("BlogPosts")]
  2. public class BlogPost
  3. {
  4. [Key]
  5. public Guid Id { get; set; }
  6. public string Title { get; set; }
  7. public string Content { get; set; }
  8. public DateTime PublishDate { get; set; }
  9.  
  10. [ForeignKey("Category")]
  11. public Guid CategoryId { get; set; }
  12. public virtual Category Category { get; set; }
  13. }
  14.  
  15. [Table("Categories")]
  16. public class Category
  17. {
  18. [Key]
  19. public Guid Id { get; set; }
  20. public string Name { get; set; }
  21. public virtual ICollection<BlogPost> BlogPosts { get; set; }
  22. }
The BlogPost class represents a blog post and corresponds to a BlogPosts table as indicated by the [Table] attribute. Similarly, Category class represents a blog post category and corresponds to the Categories table. Also have a look at the BlogContext class that represents a database context:
  1. public class BlogContext : DbContext
  2. {
  3. public BlogContext():base()
  4. {
  5. }
  6.  
  7. public DbSet<BlogPost> BlogPosts { get; set; }
  8. public DbSet<Category> Categories { get; set; }
  9. }
The Main() method then makes use of these classes to add a record in both of the tables.
  1. static void Main(string[] args)
  2. {
  3. using (var db = new BlogContext())
  4. {
  5. Guid postId = Guid.NewGuid();
  6. Guid catId = Guid.NewGuid();
  7. var cat = new Category { Id = catId, Name = "ASP.NET" };
  8. var post = new BlogPost { Id=postId,Title="Title1", Content="Hello World!", PublishDate=new DateTime(2011,1,1), Category=cat};
  9. db.Categories.Add(cat);
  10. db.BlogPosts.Add(post);
  11. Console.WriteLine(db.Database.Connection.ConnectionString);
  12. int i = db.SaveChanges();
  13. Console.WriteLine("{0} records added...", i);
  14. }
  15. Console.ReadLine();
  16. }
If you run the application you will find a database created as shown below:
The database was created automatically
Figure 1: The database was created automatically
Notice that the database CodeFirstDbInitializerDemo.BlogContext was created automatically and contains two application tables viz. BlogPosts and Categories. There is also a metadata table - EdmMetadata - that stores model metadata. This all happened because of an inbuilt database initializer - CreateDatabaseIfNotExists. As the name suggests the default database initializer will create a database only if it doesn't exist. Now, manually delete the BlogPosts table and run the application again.
This time you will get an exception indicating that the already existing database was used and since it no longer has BlogPosts table the code throws an exception while saving the changes.
DbUpdateException
Figure 2: DbUpdateException

Available Database Initializers

Entity Framework Code First comes with three basic database initializers viz. CreateDatabaseIfNotExists, DropCreateDatabaseWhenModelChanges and DropCreateDatabaseAlways.

CreateDatabaseIfNotExists

This is the default database initializer class used by Code First unless you specify some other class. As the name suggests, the CreateDatabaseIfNotExists class creates a database only if it doesn't exist. This initializer also comes in handy when you wish to avoid any accidental deletion of the database.

DropCreateDatabaseWhenModelChanges

This database initializer creates a database if it doesn't exist already. Additionally, if a database is already present but there is a mismatch between the model classes and table schema then it deletes the database and re-creates it. You will find this more useful during development and testing when models are changing often.

DropCreateDatabaseAlways

The DropCreateDatabaseAlways class deletes and creates a database irrespective of whether it is already present or not. This way, with every run of the application you will be deleting and re-creating the database. You will find this initializer useful during testing when you want to run the application with a fresh set of data.
You can also create your own database initializer by implementing the IDatabaseInitializer interface. You will develop a custom database initializer in the later sections.

Using Inbuilt Database Initializers

Now that you are aware of the inbuilt database initializers provided by Code First, let's see how to use them in your application.
To use a particular database initializer add the following piece of code at the beginning of the Main() method:
  1. Database.SetInitializer(new DropCreateDatabaseAlways<BlogContext>());
The SetInitializer() method takes an instance of database initializer class and sets it as a database initializer for the current application domain. When you set a database initializer, it won't be called immediately. It will be called when the context (BlogContext) is used for the first time. In the preceding example, the actual database creation will occur only when you add a new Category and BlogPost and not when a new instance of BlogContext is created.
  1. static void Main(string[] args)
  2. {
  3. Database.SetInitializer(new DropCreateDatabaseAlways<BlogContext>());
  4. using (var db = new BlogContext()) //initializer won't be called here
  5. {
  6. ...
  7. db.Categories.Add(cat); //initializer will be called here
  8. db.BlogPosts.Add(post);
  9. ...
  10. }
  11. Console.ReadLine();
  12. }
If you wish to use CreateDatabaseIfNotExists database initializer, you need not do anything specific since it is the default database initializer. Of course, you can set it explicitly using SetInitializer() method as shown above.
By default, Code First runs the database initialization logic once per AppDomain when the context is used for the first time. You can, however, override this default behavior using the Initialize() method. You may wish to call a database initializer explicitly when your model is complex and initialization is going to take more time to run. This way rather than spending time at some later stage you are running the initialization process at some known step (and can show a wait message to the end user). To use the Initialize() method you will need to modify your code as shown below:
  1. Database.SetInitializer(new DropCreateDatabaseAlways<BlogContext>());
  2. using (var db = new BlogContext())
  3. {
  4. db.Database.Initialize(false);
  5. ...
  6. }
In the above code snippet you are calling the Initialize() method immediately after creating a context instance. In this case, the database will be created immediately after calling the Initialize() method instead of waiting until the context is used for the first time. The Initialize() method takes a boolean parameter that controls whether the initialization process should re-run if it has already run for the application. Specifying false will skip the initialization process if it has already executed. A value of true will initialize the database again even if it was already initialized.
At times you may want to use an existing database with Code First. In such cases you may not want to execute any initialization logic at all. You can suppress the database initialization process altogether by passing null to SetInitializer() method.
  1. Database.SetInitializer<BlogContext>(null);

Seeding Data

During the testing phase you often need to populate database tables with sample data. At times you also need to populate some application data at the time of database creation. For example, while creating our sample database you may want to populate the Categories table with some predefined categories. Such seed data can be added to the database being created by overriding the Seed() method of the database initializer class. Consider the following piece of code :
  1. public class BlogContextSeedInitializer : DropCreateDatabaseAlways<BlogContext>
  2. {
  3. protected override void Seed(BlogContext context)
  4. {
  5. Category cat1 = new Category { Id = Guid.NewGuid(), Name = ".NET Framework" };
  6. Category cat2 = new Category { Id = Guid.NewGuid(), Name = "SQL Server" };
  7. Category cat3 = new Category { Id = Guid.NewGuid(), Name = "jQuery" };
  8. context.Categories.Add(cat1);
  9. context.Categories.Add(cat2);
  10. context.Categories.Add(cat3);
  11. context.SaveChanges();
  12. }
  13. }
Here, you created a custom database initializer by inheriting DropCreateDatabaseAlways class. Further, you need to override the Seed() method. The Seed() method receives the context object as a parameter. You then create three categories and add them to the context. Finally SaveChanges() method saves the data to the database that was created during the initialization process.
To see the Seed() method in action, you need to use BlogContextSeedInitializer in the Main() method. Adding the following line of code will do that job:
  1. Database.SetInitializer(new BlogContextSeedInitializer());
If you run the application again and check the Categories table, you should see sample data added to it.
Sample data added
Figure 3: Sample data added

Creating a Custom Database Initializer

In the preceding examples you used inbuilt database initializers. You can also create a custom database initializer by implementing the IDatabaseInitializer interface. You need to implement the InitializeDatabase() method of IDatabaseInitializer interface and write your own logic of database creation. The following code shows a sample implementation of the InitializeDatabase() method:
  1. public class BlogContextCustomInitializer : IDatabaseInitializer<BlogContext>
  2. {
  3. public void InitializeDatabase(BlogContext context)
  4. {
  5. if (context.Database.Exists())
  6. {
  7. if (!context.Database.CompatibleWithModel(true))
  8. {
  9. context.Database.Delete();
  10. }
  11. }
  12. context.Database.Create();
  13. context.Database.ExecuteSqlCommand("CREATE TABLE GLOBAL_DATA([KEY] VARCHAR(50), [VALUE] VARCHAR(250))");
  14. }
  15. }
The InitializeDatabase() method receives an instance of a content class. You can then use the Exists() method to determine whether a database is already present. The CompatibleWithModel() method tells you (true / false) whether the database schema is compatible with the model. If the database is not compatible you delete and recreate it using Delete() and Create() methods respectively. If no database exists then you create a new one using the Create() method. Notice how the code is using the ExecuteSqlCommand() method to create the GLOBAL_DATA table that is not part of the model. Though we don't use that table in our example it illustrates how custom initializers can be used to perform custom tasks.
Now, set the BlogContextCustomInitializer class as the initializer using the SetInitializer() method and run the application. You will find that in addition to model tables, the GLOBAL_DATA table is also created.
The GLOBAL_DATA table is created
Figure 4: The GLOBAL_DATA table is created

Specifying Database Initializer in Configuration File

In all of the preceding examples you specified a database initializer in the code itself. You can also specify it in the application configuration file by adding a key in the section. This technique can be useful if you are switching between database initializers often. The key and value must be in a specific format as shown in the following markup:
  1. key="DatabaseInitializerForType CodeFirstDbInitializerDemo.BlogContext,CodeFirstDbInitializerDemo"
  2.  
  3. value="CodeFirstDbInitializerDemo.BlogContextCustomInitializer, CodeFirstDbInitializerDemo" />
Notice the key carefully. It must begin with a predefined value DatabaseInitializerForType followed by a white space and then followed by the assembly qualified name of the context class. The first part of the assembly qualified name is of the form MyNamespace.MyContextClass and the second part is the name of the assembly that contains the context class (CodeFirstDbInitializerDemo). The value is an assembly qualified name of custom database initializer class.
To see the above setting in action, comment out the SetInitializer() call from the Main() method and run the application again. You will find that the application picks up the database initializer details from the configuration file and creates the database as per the logic specified therein.

Summary

Database initialization in Code First refers to creating database and tables based on a model. Code First provides three inbuilt database initializers, viz. CreateDatabaseIfNotExists, DropCreateDatabaseWhenModelChanges and DropCreateDatabaseAlways. You can also create your own database initializer either by inheriting from existing initializers or by implementing the IDatabaseInitializer interface. The SetInitializer() method allows you to specify a database initializer to use for your application. In case your application needs to seed data you can override the Seed() method of the initializer class.