Uncategorized

Three pits on your way to setting up your business

I see lots of startups showing off their thoughts and sentiment, different style in quite significant way. some are heroic, some are coziness, some mooching, some solemn and stirring, and some are desperate. starting up a business is like marriage, looks great by stranger, but only the startups know what they have been through.

It’s been three years since my second startup, and I would like to talk about the starting up from my point of view. I divided the startup to three phases: the first phase is the first three month, and the second phase is the first year, and the third phase is the first three years. Normally if startup is still alive after three years, and have some reputation in the market, then this business has pass it’s critical stage, and start its next stage: growing stage. At this stage the business is not easy to die, but whether it can grow big, all depends on the industry and this business’ characteristic.

This first phase, i.e. the first three months, at this phase the startup only have an idea, no products have been formed yet, not even going though the market test out. The startup is just like a new solider, all day excited and vigorous. The startup either focus on products, contacting potential customer, or writing business plan, contacting investors. but all in all, the startup is very active and efficiency.

If thing goes well, after three months, the product should beginning to take shape, and got some investment if lucky. Now it’s time to start testing the product, and normally come with two outcomes: one is the product is very popular, although the probability is very small; another one is common situation, which it’s realized that it’s not as good as expected. the startup will experience their first strike, and part of startup will chose to quit, the others will chose to uphold their faith, and continuing to improve their products, or pick another direction to try again.

After the first three months, very few startup begin their fast growing phase, and these startup feel coziness and start feel it’s easy like piece of cake! but unfortunately most startup not that lucky, they start facing difficulty, and start realize that starting up a business is not as easy as they imagined. They must keeping amend and revise their products or business model, before they can survive in the market.

Keeping doing that for one year, few luckier become the rising star. They start the first round investment, and joining all sort of presentation, doing marketing through all different channels. However a majority of startups start fall in to mooching. It seems they are always one step behind after they have tried a few products and business models, and they don’t have too much room for any further improvement after the cash flow is tighter and team is under higher pressure. At this time, another wave of startups choose to quit, and the rest choose to keep fighting and searching for new direction.

From the first year to the third year, there is no big changes for these two years compared with the first year. If the business is still alive, it means the business has found it’s direction. They have successfully pull through infancy stage, and begin their preschool period. The products is in an early form, and have some reputation in the market, but the team begin to having problems. Because the rapid growth didn’t come together with management prompt, most startups don’t have management experience, or even despise the important of management and think management is equal to bureaucracy, the business start growing pain.

Statistically speaking, the average life of a business is 2.5 years, which means at least 50% of business can’t survive more than 2 years. It is hard to believe but it’s brutal truth. Before these business die, they will experience the most difficult phase –  solemn and stirring, and then becoming desperate. Some co-founders choose to quit and go back to big companies, or choose to pick next project. Only these startups insist can survive and growing, with lower profile.

I would like to say congratulation after three years, but don’t get excited too early, another three big challenges is awaiting: startups feel powerless in management, the co-founders are falling behind. Even through the business strategy is clear, but it’s always hard to carry out because lots of details issues start emerging. the organisation start facing problems from different facet, and always short on skilled resources, recruitment and keeping people is getting harder and harder. Organisation regulation become falling behind the business growth. Now the business face another transition.

If you think your business having lots of issues, don’t be depression, because lots of business having the same amount of issues. Keep in mind identifying and focusing on the few fatal issues, which can make your business survive. and then you can resolve other issues slowly during your development. The process of business growing is the process of solving problem, and it’s also the process of startups self-improvement and self-growth.

If you always have growth pain, it’s not a bad thing, because only live people can having the pain.

Uncategorized

The Top 10 Mistakes That KnockoutJS Developers Make

1 Modules

Unlike other UI frameworks, Knockout does not come with a built in way to modularize your application. It’s possible to write an entire Knockout app in a single HTML file:

kojs_full

While this runs, it definitely won’t scale to applications of any significant complexity. The official Knockout docs suggest using RequireJS for Asynchronous Module Definition (AMD), and I wholeheartedly second this recommendation. Using RequireJS and the domReady module, the above code refactors into three separate files.

Good.html:

goodhtml

main.js

mainjs

viewModel.js

viewmodeljs

2 var self = this;

Keeping track of this in Knockout can be tough. Setting var self = this; at the top of every view model makes it easy.

For example, if var self = this; is not set then this must be passed into every computed observable:

viewmodeobj

Forgetting to pass in this is easy to do and can result in hard to track down bugs. Ifvar self = this; is set then passing this is not necessary:

viewmodelself

var self = this; can also help avoid bugs when one binding context refers to another. Consider the following code that displays a list of names. When a user clicks on an name in the list, that name is displayed in the <span> below.

HTML:

html

Javascript:

js

When selectPerson is called its scope is set to the object in person corresponding to the name clicked. However, because var self = this; is set the view model object is still accessible within the event callback. This would not be the case otherwise.

In production code I almost always define var self = this;. However, for the sake of brevity, I won’t use it in some examples in this article.

3 Logic in templates

Knockout makes it easy to write complicated logic in HTML templates. Avoid doing this at all costs! It results in difficult to test and maintain code. Instead of using logic in templates…

computedlogic

4 Testing

Speaking of testing, by default Knockout offers no tools to help you. This does not mean you shouldn’t write tests! There are ample JS testing frameworks, and you should be able to pick up and drop any of them into your Knockout application. As with anything, the earlier you start writing tests the better. I usually don’t start a new Knockout project without also including a testing framework.

5 ko.mapping

ko.mapping is a plugin for Knockout that makes working with data fetched from REST endpoints much more enjoyable.

Without ko.mapping, a view model that consumes objects from a REST API might look like this:

    function viewModel() {
        /*
        * Gets data about a person from the server:
        * person = {
        *   firstName: "John",
        *   lastName: "Stewart"
        * }
        */
        var person = getPersonFromServer();

        this.person = {};
        this.person.firstName = ko.observable(person.firstName);
        this.person.lastName = ko.observable(person.lastName);
    }

With ko.mapping the view model is much simpler:

    function viewModel() {
        var person = getPersonFromServer();
        this.person = ko.mapping.fromJS(person);
    }

Want to convert part of the view model back to plain JSON so that you can POST it back to the API? That’s a one-liner too:

    var json = ko.mapping.toJS(this.person);

While ko.mapping is to some degree officially part of Knockout (it’s in the official documentation), it is a separate project that you’ll have to download and include.

It’s also worth nothing that some people prefer the functionally analogousko.viewModel plugin to ko.mapping. ko.mapping has always worked fine for me, but it only seemed fair to link to both. Use one or the other, but don’t use neither!

6 textInput and valueUpdate

This may seem minor, but it’s caused me so many headaches that it’s worth including. Knockout binds the value of input elements a somewhat strange way. To illustrate, let’s say we have an input element and want to update some text on the page in real time as the input’s value changes:

    <input type="text" data-bind="value: myValue">
    Value: <span data-bind="text: myValue"></span>
    function viewModel() {
        this.myValue = ko.observable();
    }

Surprisingly, the above won’t work. The myValue observable (and thus our text in the span) updates whenever the input loses or gains focus, not as it’s value changes. Why? For performance reasons this is how Knockout behaves by default.

To fix this in Knockout 3.2 (current at the time of writing) or newer, use the textInput binding instead of the value binding.

    <input type="text" data-bind="textInput: myValue">

This will provide immediate updates to myValue with the minor caveat that it won’t guarantee that the value attribute of the input is always synced with myValue.

If you are using an older version of Knockout or if you are dead set on using the value binding, then you must use the valueUpdate flag.

    <input type="text" data-bind="value: myValue, valueUpdate='afterkeydown'">

In Knockout 3.2 there are 4 possible values for valueUpdate, each with its own idiosyncrasies:

  • + input – Updates when the value of the element changes. Doesn’t work in IE8-.
  • + keyup – Updates when a keyup event is fired
  • + keypress – Updates when a keypress event is fired.
  • + afterkeydown – Updates as soon as the user starts typing a character. Does not work on all mobile browsers — notably Safari on IOS7.

Using the textInput binding is strongly recommended over using the valueUpdateflag.

7 Don’t repeatedly push into observable arrays

Pushing multiple times into observable arrays can cause significant performance issues with your application:

    function viewModel() {
        var arr = [0, 1, ..., 999];

        this.numbers = ko.observableArray();

        for (var i = 0; i < arr.length; i++) {
            this.numbers.push(arr[i]);
        }
    }

Running the for loop above will cause Knockout to redraw the page 1000 times — one for each push. To avoid this, simply overwrite the old value of our entire array:

    function viewModel() {
        var arr = [0, 1, ..., 999];
        this.numbers = ko.observableArray(arr);
    }

To transform data before putting it into our new array, use ko.utils.arrayMap.

    function Number(number) {
        this.number = number;
    }

    function viewModel() {
        var arr = [0,1, ..., 999];

        // creates an array of Number objects
        this.numbers = ko.observableArray(ko.utils.arrayMap(arr, function(number) {
            return new Number(number)
        }));

    }

To append many items to an existing observable array, exploit the fact that pushaccepts a variable number of arguments and use apply to push them in all at once.

    function viewModel() {
        var arr = [500, 501, ... 999];

        this.numbers = ko.observableArray([0, 1, ..., 499]);
        this.numbers.push.apply(self.numbers, arr);
    }

8 Observable arrays don’t automatically have observable members

Observable arrays track changes to which objects are in the array. They do not track changes to the state of those objects.

    <ul data-bind="foreach: people">
        <li data-bind="text: name"></li>
    </ul>
    <button data-bind="click: makeDerekMike">Make Derek Mike</button>
    function viewModel() {
        var self = this;

        self.people = ko.observableArray([
            {
                name: 'Derek',
            },
            {
                name: 'Sara'
            },
            ...
        ]);

        self.makeDerekMike = function() {
            for (var i = 0; i < self.people().length; i++) {
                if (self.people()[i].name === 'Derek') {
                    self.people()[i].name = 'Mike';
                }
            }
        };
    }

Clicking the button in the first example will not trigger a page refresh despite the fact that it will modify an object in the array underlying people. This is because the same objects still belong topeople. To trigger a page refresh, we need to explicitly make the fields of the elements in people observable:

    function viewModel() {
        var self = this;

        self.people = ko.observableArray([
            {
                name: ko.observable('Derek')
            },
            {
                name: ko.observable('Sara')
            },
            ...
        ]);

        self.makeDerekMike = function() {
            for (var i = 0; i < self.people().length; i++) {
                if (self.people()[i].name() === 'Derek') {
                    self.people()[i].name('Mike');
                }
            }
        };
    }

9 Components

Because Knockout makes building interactive widgets so simple, it’s easy to write similar code in different parts of your application. Use Knockout components to abstract common UI widgets and promote code reuse.

Using components, we can build a simple reusable list builder as follows:

    <span>This is a list with no initial values</span>
    <div data-bind="component: 'list-builder'"></div>

    <span>This is a list with some initial values</span>
    <div data-bind="component: {
        name: 'list-builder',
        params: { list: ['item', 'another item'] }
    }"></div>
    function Item(text) {
        this.text = text;
    }

    ko.components.register('list-builder', {
        viewModel: function(params) {
            var self = this;

            self.list = ko.observableArray([]);

            if (params && params.list) {
                self.list(ko.utils.arrayMap(params.list, function(item) {
                    return new Item(text);
                }));
            }

            self.newText = ko.observable();
            self.add = function() {
                self.list.push(new Item(text));
                self.newText('');
            };
        },
        template:
            '<ul data-bind="foreach: list">' +
                '<li data-bind="text: text"></li>' +
            '</ul>' +
            '<input type="text" data-bind="textInput: newText" />' +
            '<button data-bind="click: add">Add</button>'
    });

Note that you probably don’t want to inline the viewModel and template as above in any production code code. Fortunately, this can be solved using require.js (see #1). For a description of how to do this check out the official components documentation.

10 Tutorials

Knockout the official tutorials are great! They offer a interactive sandbox to play around with the framework in a guided fashion.

Uncategorized

Error on Installing Umbraco with Visual Studio

I got the error when installing Umbraco v7.2.6 to Visual Studio 2013 MVC project.

Updating ‘Microsoft.AspNet.Mvc 5.2.3’ to ‘Microsoft.AspNet.Mvc 4.0.20710.0’ failed. Unable to find a version of ‘UmbracoCms.Core’ that is compatible with ‘Microsoft.AspNet.Mvc 4.0.20710.0’.

To fix this issue, install the package “Microsoft.AspNet.Mvc.FixedDisplayModes” first, and then run Install-Package UmbracoCms

Uncategorized

Top 10 ASP.NET MVC Best Practices

In this section we will discuss 10 best practices and tips we should keep in mind when working with ASP.NET MVC applications.

Tip 1: Disable Request Validation

Request Validation is a feature that prevents potentially dangerous content from being submitted. This feature is enabled by default. However, at times you might need your application to post HTML markup tags to the server. You would then need this feature to be disabled. Here is how you can do it:

[ValidateInput(false)]
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Create([Bind(Exclude=”Id”)]Employee empObj)
{

}

Tip 2: Cache Your Data

You can improve your application’s performance to a considerable extent by caching relatively stale data. That way the network bandwidth between the client and the server is also reduced. It is great if you can also cache the rendered action of web pages that are relatively stale, i.e., don’t change much over time.

public class HomeController : Controller
{
[OutputCache(Duration=3600,
VaryByParam=”none”)]
public ActionResult Index()
{

}
}

Tip 3: Isolate Data Access Logic From the Controller

The Controller in an ASP.NET MVC application should never have the Data Access logic. The Controller in an ASP.NET MVC application is meant to render the appropriate view based on some user interface action. You should make use of Repository Pattern to isolate Data Access Logic from the Controller – you might need dependency injection to inject the appropriate Repository to your controller at runtime.

Tip 4: Using a Master View Model

We frequently use Master Pages in ASP.NET applications – the same Master Page would be extended by the Content Pages throughout the application to give a similarity as far as look and feel and functionality is concerned. How do we do that in an ASP.NET MVC application? Well, we need a MasterViewModel similar to what is shown in the code snippet below:

public class ViewModelBase
{
public ViewModelBase()
{

}
//Other methods and properties
}

Tip 5: Use Strongly Typed Models

A strongly typed view is a view that defines its data model as a CLR type instead of a weakly typed dictionary that may contain potentially anything. To create a strongly typed view, check the “Create a strongly-typed view” checkbox while you are creating the view. If you plan to create a strongly typed view manually later, ensure that your view “Inherits” System.Web.Mvc.<Your Namespace>.<YourClass>

Tip 6: Use Data Annotations for Validation

You can make use of the System.ComponentModel.DataAnnotations assembly to validate your server – side code by simply decorating your model with the necessary attributes. Here is an example:

public class Employee
{
[Required(ErrorMessage=”Employee Name Cannot be Blank”)]
public string Name { get; set; }

// …
}

Tip 7: Take Advantage of Model Binding

Consider the following code snippet:

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Create()
{
Employee employee = new Employee();
employee.Name = Request.Form[“Name”];

// …

return View();
}

You can make use of model binder to save you from having to use the Request and HttpContext properties – just use FormsCollection instead. Here is an example:

public ActionResult Create(FormCollection values)
{
Employee employee = new Employee();
employee.Name = values[“Name”];

// …

return View();
}

Tip 8: Cache Pages that Contain Shared Data or are Public and don’t Require Authorization

You should not cache pages that need authorization in ASP.NET MVC. You should not cache pages that contain private data or need authorization. Caching pages in ASP.NET MVC is simple – just specify the OutputCache directive as shown in the code snippet below:

[OutputCache(Duration = 60)]
public ActionResult Index()
{
return View(“Index”, somedata);
}

Tip 9: Use Extension Methods

You can make use of Extension Methods to simplifies use of LINQ queries that boost application performance too. This can dramatically reduce the amount of code that you would need to otherwise write when writing your LINQ queries, make your LINQ queries manageable and also improve the application’s performance.

Tip 10: Take Advantage of Model Binding

You can take advantage of Microsoft Velocity – a distributed caching engine to boost the application performance of your ASP.NET MVC applications. You can learn more on Velocity from this link:http://blogs.msdn.com/b/velocity/

Uncategorized

SharePoint 2013 – CRUD on List Items Using REST Services & jQuery

What’s New

SharePoint 2013 has greatly expanded the REST services available to developers.  With this, we have much more SharePoint functionality exposed via CSOM and Web Services. Also, all of the new REST Services use the ODATA standards (more Information on that Here). This means that we can easily test our queries using the browser, because we’ll be executing standard GET requests.

This means, that going forward, we’re going to see the old .asmx SOAP services disappear.

One of the most fundamental REST services is the set that allow us to interact with List Items in SharePoint 2013.  Before we get into performing our CRUD Operations using jQuery, let’s go over their basic use.

REST Services – High Level Overview

Let’s start out with our basic get commands in REST. Below is a list of the basic commands used to get List Items from a SharePoint List through the SharePoint 2013 REST Services.

COMMAND URL
 Get All Lists http://server/site/_api/lists
 Get All List Items From a Single List http://server/site/_api/lists/getbytitle(‘listname’)/items
 Get a Single List Item http://server/site/_api/lists/getbytitle(‘listname’)/items
 Get Back Certain Columns http://server/site/_api/lists/getbytitle(‘listname’)/items?$select=Title,Id
 Order Your Results  http://server/site/_api/lists/getbytitle(‘listname’)/items?$orderby=Title

So, how do we test our SharePoint 2013 REST GET queries?  Just paste the URL into your browser and the XML will be returned.

However, IE10 doesn’t like to display it by default so I would recommend using Chrome / FireFox with an addon that makes reading XML easier.  So, start learning by manipulating your REST urls in the browser and testing out all of the features.

Making SharePoint 2013 REST Service Calls with jQuery

WHAT YOU’LL NEED TO KNOW

Before we get to our CRUD Operations, there are a few basic functions we’ll need to use to get additional data for use later on.  The Item Type in particular is nothing crazy, just a string manipulation used to build the item type which is based on the title of the list, but it’s case sensitive so we have a function to ensure we capitalize it.

Get a Single List Item

function getListItem(url, listname, id, complete, failure) {
	// Getting our list items
	$.ajax({
		url: url + "/_api/web/lists/getbytitle('" + listname + "')/items(" + id + ")",
		method: "GET",
		headers: { "Accept": "application/json; odata=verbose" },
		success: function (data) {
			// Returning the results
			complete(data);
		},
		error: function (data) {
			failure(data);
		}
		});
	}
}

Get the Item Type (used in Updates / Creates)

// Getting the item type for the list
function getListItemType(name) {
    return"SP.Data." + name[0].toUpperCase() + name.substring(1) + "ListItem";
}

REST SERVICES – GET LIST ITEMS

Getting List Items using the SharePoint REST Services is probably the simplest operation of them all.  An example of how to do this is below:

// Getting list items based on ODATA Query
function getListItems(url, listname, query, complete, failure) {

    // Executing our items via an ajax request
    $.ajax({
        url: url + "/_api/web/lists/getbytitle('" + listname + "')/items" + query,
        method: "GET",
        headers: { "Accept": "application/json; odata=verbose" },
        success: function (data) {
            complete(data); // Returns JSON collection of the results
        },
        error: function (data) {
            failure(data);
        }
    });

}

REST SERVICES – CREATE ITEMS

Creating list items gets a little bit tricky, because you’ll need a few key pieces of information:

  • The List Item type
  • REQUESTDIGEST value to prevent replay attacks
  • An object containing your List Item Values
// Adding a list item with the metadata provided
function addListItem(url, listname, metadata, success, failure) {

    // Prepping our update
    var item = $.extend({
        "__metadata": { "type": getListItemType(listname)}
    }, metadata);

    // Executing our add
    $.ajax({
        url: url + "/_api/web/lists/getbytitle('" + listname + "')/items",
        type: "POST",
        contentType: "application/json;odata=verbose",
        data: JSON.stringify(item),
        headers: {
            "Accept": "application/json;odata=verbose",
            "X-RequestDigest": $("#__REQUESTDIGEST").val()
        },
        success: function (data) {
            success(data); // Returns the newly created list item information
        },
        error: function (data) {
            failure(data);
        }
    });

}

REST SERVICES – UPDATE LIST ITEMS

Updating list items is very similar to the task of creating list items when using jQuery Ajax calls.  You’ll need the same information you used then you created your list item, with one more piece of information:

  • The List Item Type
  • REQUESTDIGEST
  • An object containing your List Item Values & Item Type
  • The REST URL to your List Item (We use our getListItem function to get this reliably, See Above)
    • Stored in: data.d.__metadata.uri
function updateListItem(url, listname, id, metadata, success, failure) {

    // Prepping our update
    var item = $.extend({
        "__metadata": { "type": getListItemType(listname) }
    }, metadata);

    getListItem(url, listname, id, function (data) {
        $.ajax({
            url: data.d.__metadata.uri,
            type: "POST",
            contentType: "application/json;odata=verbose",
            data: JSON.stringify(item),
            headers: {
                "Accept": "application/json;odata=verbose",
                "X-RequestDigest": $("#__REQUESTDIGEST").val(),
                "X-HTTP-Method": "MERGE",
                "If-Match": data.d.__metadata.etag
            },
            success: function (data) {
                success(data);
            },
            error: function (data) {
                failure(data);
            }
        });

    }, function (data) {
        failure(data);
    });

}

REST SERVICES – DELETE LIST ITEMS

Deleting a list item also requires the REST URL that leads to the List Item you would like to delete.  Again, we get this through our getListItem function (See Above).  So you’ll need:

  • The List Item Type
  • REQUESTDIGEST
  • REST URL to your List Item (via our getListItem function)
// Deleting a List Item based on the ID
function deleteListItem(url, listname, id, success, failure) {

    // getting our item to delete, then executing a delete once it's been returned
    getListItem(url, listname, id, function (data) {
        $.ajax({
            url: data.d.__metadata.uri,
            type: "POST",
            headers: {
                "Accept": "application/json;odata=verbose",
                "X-Http-Method": "DELETE",
                "X-RequestDigest": $("#__REQUESTDIGEST").val(),
                "If-Match": data.d.__metadata.etag
            },
            success: function (data) {
                success(data);
            },
            error: function (data) {
                failure(data);
            }
        });
    });

};

Practical Application

I’ve spoken with many people who are apprehensive about using JavaScript / jQuery for full applications. However, with the amount rich, client-side applications users are working with steadily growing, the average user has come to expect them.

So, I would recommend getting started creating your own JavaScript / jQuery applications as soon as possible.  SharePoint 2013 is moving that way at a rapid pace.

If you’re still on SharePoint 2010, no problem!  SharePoint 2010 still has REST Services, JavaScript Client Side Object Model, and SOAP Services to work with on the client side.

SharePoint

Download files as Zip File in SharePoint

Introduction

In this post we will see how to download selected document library items as zip file. The zip file creation api is from open source code of icsharpcode.net

Skill Level – Medium

Download files as Zip

When I am working on this requirement, I happened to check icharpcode.net which was very helpful with its api to create zip file.
The next step is to get the selected document library items and just call the api to create zip file. We need to provide one button in ribbon so that users can click it to save the zip file. In the button click we will have the code to read selected items and generate zip file.

The same logic I found in this site http://www.deviantpoint.com/post/2010/05/08/SharePoint-2010-Download-as-Zip-File-Custom-Ribbon-Action.aspx. But, download zip is not working for subsites and also to the sites that does not have managed path.

As many users are using that code, I am only modifying the code and maintain the credibility to Deviantpoint.com. The feature will still have the same name ‘DeviantPoint Download Zip Feature’ and the new code will be working for subsites and also for the sites that does not have managed path.

Following are the main methods to download as zip file, other code is just to create ribbon button and call these methods when button is clicked

using(MemoryStream ms = newMemoryStream())
{
    using(ZipFileBuilder builder = newZipFileBuilder(ms))
    {
        foreach(intid initemsIDs)
        {
            SPListItem item = library.GetItemById(id);
            if(item.IsFolder())
                AddFolder(builder, item.Folder, string.Empty);
            else
                AddFile(builder, item.File, string.Empty);
        }
        builder.Finish();
        WriteStreamToResponse(ms);
    }
}
privatestaticvoidAddFile(ZipFileBuilder builder, SPFile file, stringfolder)
{
    using(Stream fileStream = file.OpenBinaryStream())
    {
        builder.Add(folder + "\\"+ file.Name, fileStream);
        fileStream.Close();
    }
}
privatevoidAddFolder(ZipFileBuilder builder, SPFolder folder, stringparentFolder)
{
    stringfolderPath = parentFolder == string.Empty ? folder.Name : parentFolder + "\\"+folder.Name;
    builder.AddDirectory(folderPath);
    foreach(SPFile file infolder.Files)
    {
        AddFile(builder, file, folderPath);
    }
    foreach(SPFolder subFolder infolder.SubFolders)
    {
        AddFolder(builder, subFolder, folderPath);
    }
}
privatevoidWriteStreamToResponse(MemoryStream ms)
{
    if(ms.Length > 0)
    {
        stringfilename = DateTime.Now.ToFileTime().ToString() + ".zip";
        Response.Clear();
        Response.ClearHeaders();
        Response.ClearContent();
        Response.AddHeader("Content-Length", ms.Length.ToString());
        Response.AddHeader("Content-Disposition", "attachment; filename="+ filename);
        Response.ContentType = "application/octet-stream";
        byte[] buffer = newbyte[65536];
        ms.Position = 0;
        intnum;
        do
        {
            num = ms.Read(buffer, 0, buffer.Length);
            Response.OutputStream.Write(buffer, 0, num);
        }
        while(num > 0);
        Response.Flush();
    }
}

ZipFileBuilder is the class file that is created to call the Zip api and it is available in the source code
‘itemsIDs’ is the array of selected items of the document library that should be filled. When Download button is clicked, it is this array we fill.

If you do not want to use Zip file code to download, then write object model code to download files in the download button click event.

To summarize,

1) Download the code
2) Deploy the wsp ( Site collection level feature ‘DeviantPoint Download Zip Feature’ will be created)
3) Activate the sitecollection feature ‘DeviantPoint Download Zip Feature’
(Tip- siteurl/_layouts/ManageFeatures.aspx?Scope=Site will show you sitecollection features)
4) ‘Download as Zip’ button will be available in the ribbon to use