.NET 4.5 to Support Zip File Manipulation Out of the Box
On 5/17/2012 6:19 PM by Tugberk
One of the missing feature of .NET framework was a support for Zip file manipulation. In .NET 4.5, we have an extensive support for manipulating zip archives.
One of the missing feature of .NET framework was a support for Zip file manipulation such as reading the zip archive, adding files, extracting files, etc. and we were using some third party libraries such as excellent DotNetZip. In .NET 4.5, we have an extensive support for manipulating .zip files. First thing that you should do is to add System.IO.Compression assembly as reference to your project. You may also want to reference System.IO.Compression.FileSystem assembly to access three extension methods (from the ZipFileExtensions class) for the ZipArchive class: CreateEntryFromFile, CreateEntryFromFile, and ExtractToDirectory. These extension methods enable you to compress and decompress the contents of the entry to a file. Let’s cover the bits and pieces that we get from System.IO.Compression assembly at first. The below sample shows how to read a zip archive easily with ZipArchive class: static void Main(string[] args) { const string zipFilePath = @"C:\apps\Sample Pictures.zip"; using (FileStream zipFileToOpen = new FileStream(zipFilePath, FileMode.Open)) using (ZipArchive archive = new ZipArchive(zipFileToOpen, ZipArchiveMode.Read)) { foreach (var zipArchiveEntry in archive.Entries) Console.WriteLine( "FullName of the Zip Archive Entry: {0}", zipArchiveEntry.FullName ); } } In this sample, we are opening the zip archive and iterate through the collection of entries. When we run the application, we should see the list of files inside the zip archive: It’s also so easy to add a new file to the zip archive: static void Main(string[] args) { const string zipFilePath = @"C:\apps\Sample Pictures.zip"; using (FileStream zipFileToOpen = new FileStream(zipFilePath, FileMode.Open)) using (ZipArchive archive = new ZipArchive(zipFileToOpen, ZipArchiveMode.Update)) { ZipArchiveEntry readMeEntry = archive.CreateEntry("ReadMe.txt"); using (StreamWriter writer = new StreamWriter(readMeEntry.Open())) { writer.WriteLine("Lorem ipsum dolor sit amet..."); writer.Write("Proin rutrum, massa sed molestie porta, urna..."); } foreach (var zipArchiveEntry in archive.Entries) Console.WriteLine( "FullName of the Zip Archive Entry: {0}", zipArchiveEntry.FullName ); } } In this sample, we are adding a file named ReadMe.txt at the root of archive and then we are writing some text into that file. Extracting files is into a folder is so easy as well. You need reference the System.IO.Compression.FileSystem assembly along with System.IO.Compression assembly as mentioned before for this sample: static void Main(string[] args) { const string zipFilePath = @"C:\apps\Sample Pictures.zip"; const string dirToExtract = @"C:\apps\Sample Pictures\"; using (FileStream zipFileToOpen = new FileStream(zipFilePath, FileMode.Open)) using (ZipArchive archive = new ZipArchive(zipFileToOpen, ZipArchiveMode.Update)) archive.ExtractToDirectory(dirToExtract); } There are some other handy APIs as well but it is so easy to discover them by yourself. Enjoy ResourcesAsynchronous Database Calls With Task-based Asynchronous Programming Model (TAP) in ASP.NET MVC 4
2
Comments
On 4/9/2012 2:23 PM by Tugberk
Asynchronous Database Calls With Task-based Asynchronous Programming Model (TAP) in ASP.NET MVC 4 and its performance impacts.
You have probably seen some people who are against asynchronous database calls in ASP.NET web applications so far. They mostly right but there are still some cases that processing database queries asynchronous has very important impact on.
One of the reasons why asynchronous programming is not recommended for database calls is that it is extremely hard to get it right, even if we adopt Task-based Asynchronous Programming in .NET 4.0. But, with the new async / await features of C# 5.0, it is easier and still complex at the same time. When you call a method which returns Task or Task<T> for some T and await on that, the compiler does the heavy lifting by assigning continuations, handling exceptions and so on. Because of this fact, it adds a little overhead and you might notice this when you are dealing with short running operations. At that point, asynchrony will do more harm than good to your application. Let’s assume we have a SQL Server database out there somewhere and we want to query against that database in order to get the cars list that we have. I have created a class which will do the query operations and hand us the results as C# CLR objects. public class GalleryContext : IGalleryContext { private readonly string selectStatement = "SELECT * FROM Cars"; public IEnumerable<Car> GetCars() { var connectionString = ConfigurationManager.ConnectionStrings["CarGalleryConnStr"].ConnectionString; using (var conn = new SqlConnection(connectionString)) { using (var cmd = new SqlCommand()) { cmd.Connection = conn; cmd.CommandText = selectStatement; cmd.CommandType = CommandType.Text; conn.Open(); using (var reader = cmd.ExecuteReader()) { return reader.Select(r => carBuilder(r)).ToList(); } } } } public async Task<IEnumerable<Car>> GetCarsAsync() { var connectionString = ConfigurationManager.ConnectionStrings["CarGalleryConnStr"].ConnectionString; var asyncConnectionString = new SqlConnectionStringBuilder(connectionString) { AsynchronousProcessing = true }.ToString(); using (var conn = new SqlConnection(asyncConnectionString)) { using (var cmd = new SqlCommand()) { cmd.Connection = conn; cmd.CommandText = selectStatement; cmd.CommandType = CommandType.Text; conn.Open(); using (var reader = await cmd.ExecuteReaderAsync()) { return reader.Select(r => carBuilder(r)).ToList(); } } } } //private helpers private Car carBuilder(SqlDataReader reader) { return new Car { Id = int.Parse(reader["Id"].ToString()), Make = reader["Make"] is DBNull ? null : reader["Make"].ToString(), Model = reader["Model"] is DBNull ? null : reader["Model"].ToString(), Year = int.Parse(reader["Year"].ToString()), Doors = int.Parse(reader["Doors"].ToString()), Colour = reader["Colour"] is DBNull ? null : reader["Colour"].ToString(), Price = float.Parse(reader["Price"].ToString()), Mileage = int.Parse(reader["Mileage"].ToString()) }; } }
As you can see, it has two public methods to query the database which does the same thing but one of them doing it as synchronously and the other one as asynchronously. Inside the GetCarsAsync method, you can see that we append the AsynchronousProcessing property and set it to true in order to run the operation asynchronously. Otherwise, no matter how you implement it, your query will be processed synchronously.
When we try to consume these methods inside our controller, we will have the following implementation. public class HomeController : Controller { private readonly GalleryContext ctx = new GalleryContext(); public ViewResult Index() { return View(ctx.GetCars()); } public async Task<ViewResult> IndexAsync() { //workaround: http://aspnetwebstack.codeplex.com/workitem/22 await TaskEx.Yield(); return View("Index", await ctx.GetCarsAsync()); } } Now, when we hit /home/Index, we will be querying our database as synchronously. If we navigate to /home/IndexAsync, we will be doing the same thing but asynchronously this time. Let’s do a little benchmarking with Apache HTTP server benchmarking tool. First, we will simulate 50 concurrent requests on synchronously running wev page: Let’s do the same thing for asynchronous one: Did you notice? We have nearly got the same result. In fact, you will see that synchronous version of the operation completes faster than the asynchronous one at some points. The reason is that the SQL query takes small amount of time (approx. 8ms) here to complete. Let’s take another scenario. Now, we will try to get the same data through a Stored Procedure but this time, the database call will be slow (approx. 1 second). Here are two methods which will nearly the same as others: private readonly string spName = "sp$GetCars"; public IEnumerable<Car> GetCarsViaSP() { var connectionString = ConfigurationManager.ConnectionStrings["CarGalleryConnStr"].ConnectionString; using (var conn = new SqlConnection(connectionString)) { using (var cmd = new SqlCommand()) { cmd.Connection = conn; cmd.CommandText = spName; cmd.CommandType = CommandType.StoredProcedure; conn.Open(); using (var reader = cmd.ExecuteReader()) { return reader.Select(r => carBuilder(r)).ToList(); } } } } public async Task<IEnumerable<Car>> GetCarsViaSPAsync() { var connectionString = ConfigurationManager.ConnectionStrings["CarGalleryConnStr"].ConnectionString; var asyncConnectionString = new SqlConnectionStringBuilder(connectionString) { AsynchronousProcessing = true }.ToString(); using (var conn = new SqlConnection(asyncConnectionString)) { using (var cmd = new SqlCommand()) { cmd.Connection = conn; cmd.CommandText = spName; cmd.CommandType = CommandType.StoredProcedure; conn.Open(); using (var reader = await cmd.ExecuteReaderAsync()) { return reader.Select(r => carBuilder(r)).ToList(); } } } }
Controller actions are nearly the same as before: public class HomeController : Controller { private readonly GalleryContext ctx = new GalleryContext(); public ViewResult IndexSP() { return View("Index", ctx.GetCarsViaSP()); } public async Task<ViewResult> IndexSPAsync() { //workaround: http://aspnetwebstack.codeplex.com/workitem/22 await TaskEx.Yield(); return View("Index", await ctx.GetCarsViaSPAsync()); } } Let’s simulate 50 concurrent requests on synchronously running web page first: Ok, that’s apparently not good. As you might see, some requests take more than 8 seconds to complete which is very bad for a web page. Remember, the database call takes approx. 1 second to complete and under a particular number of concurrent requests, we experience a very serious bottleneck here. Let’s have a look at the asynchronous implementation and see the difference: Approximately 1 second to complete for each request, pretty impressive compared to synchronous implementation. Asynchronous database calls are not as straight forward as other types of asynchronous operations but sometimes it will gain so much more responsiveness to our applications. We just need to get it right and implement them properly. Visual Studio 11 Beta Code-Named "Juneau" SQL Server Database Project - Quick Overview
0
Comments
On 4/7/2012 1:26 PM by Tugberk
Quick Overview of Code-Named "Juneau" SQL Server Database Project which is one of the most awesome features of Visual Studio 11 beta
I think one of the most awesome features of Visual Studio 11 beta is SQL Server Database Project (code-named "Juneau"). It is simple, robust and makes it really easy for us to check the database code into our source control system.
This project template carries lots of features inside it and despite the fact that it is so easy to get started with it, you might drown inside its options very quickly. Honest to say, I am not so experienced with this feature but I try to use this on some personal projects for now as much as I can. Let’s first have a look at Visual Studio 2010 because if you play with SQL Server project templates with VS 2010, you will be in panic because lots of them are now gone. Ok, then. What do we do now? Well, it is simple: they are now all in one project template. From database projects to SQL Server CLR assembly projects, SQL Server Database Project template can do all of them (I have never tired creating a SQL Server CLR project with VS 11 Database Project template so far. So, I might not be entirely correct here). Let’s come back to VS 11 beta. Creating a SQL Server Database Project is very straight forward. File > New > Project and navigate to SQL Server language tab or search against "SQL Server". SQL Server Database Project option will be available. When we create the project, we get not many things out of the box which is nice. From this point, you can either start a brand new project or import your existing database. When you double-click on the Properties, we will get properties window which we can set lots of configuration about the database, build process and so on. When you are working on a project, make sure you set the target properly as shown below. While we are working on our database project, we will be creating files for Tables, User Defined Functions, Stored Procedures, etc. Don’t worry about where you put them. VS is smart about your files and it orders them properly on your deployment. This is the experience I have had so far. As usual, we can add new items via Add New Item dialog box and Database Project ships with several item templates. User experience is also incredibly high. For example, you can create your tables through design surface or directly with T-SQL code. No matter which one you pick, VS will always keep those in sync. As you can see below, we have a file named Products.sql for Products table. Let’s create a foreign key constraint for CategoryId column by referencing a table which does not exist yet. Save the file and build the solution. Now, we are getting errors since the Categories table does not exist. When we add the necessary Categories table and its columns, the build process should run smoothly without any errors. Let’s now open up the Products.sql table file again. Did you notice the right side of the design surface? Yes, it really knows what is going on outside of this file and it keeps the information in sync. As soon as you make a chance anywhere inside your project, proper places get updated. You can also create script files which will be executed at particular point of your deployment. When you go Add New Item dialog box and navigate to User Scripts tab, you will see some options there. Let’s add Post-Deployment Script file to our project. This file is nothing but a regular file except for the fact that its build action has been set to PostDeploy. What about IntelliSense? Well, it is quite nice as you can see from the below screenshots.
One more thing to mention in this post would be the deployment process but I thought it would be too much for a blog post. So, I will (hopefully) try to blog about that separately by demonstrating different scenarios. I am very excited about this feature and I am sure you have something to benefit from it as well. Useful ReferencesGitHub Offers Free Micro Plan For Students For Two Years
1
Comments
On 4/7/2012 8:07 AM by Tugberk
Couple of days ago I came across that GitHub offers Educational Accounts for academic people (student, teacher, etc.) and that covers free micro plan for students for 2 years.
As you already probably know, GitHub is amazingly awesome and keeps beating crap out of others (cough, Codeplex, cough). As a company, they have a very unique organization and that amazes me as well. And I am also going to tell this: GitHub is not #1 because of the fact that they support Git. They are #1 because they know what we want and how important UX is for the overall quality. Anyway, couple of days ago I came across that GitHub offers Educational Accounts for academic people (student, teacher, etc.) and that covers free micro plan for students for 2 years. As I am (still!) a collage student, I filled up the form and sent it. I was expecting to be rejected since I thought they wouldn't accept students outside of the USA for this plan but they were very positive about it and set my account in a short time. If you are student, go to https://github.com/edu, fill up the form indicating that you are a student, want to benefit from the free edu plan and get the micro plan as free of charge for two years. God bless Octocats |
Connect With MeTagsArchive
Blogroll |





Comments