नमस्कार!

बरेच वेळा मनात विचार येतात पण लिहिण्याचा प्रयत्न पहिल्यांदाच करत आहे. तरी चूक भूल माफी असावी.

आजकाल Whatsapp आणि Facebook यांच्यामुळे जग जवळ आले आहे, पण सगळ्याच गोष्टी share करण्याचा जणु छंदच लोकांना जडला आहे. अर्थात थोड्याफार प्रमाणात मी पण share करत असतो पण अगदी थोडक्या प्रमाणात.

आता कोणी दानधर्म करत असेल तर तो पण यावर सर्रास Share केला जातो, मुळात दान याची वाख्याच लोक विसरत चालले आहे. याचीसुद्धा मार्केटिंग होऊ लागली आहे.

मुळात दान हे निस्वार्थ भावनेने केले पाहिजे (असे दान ज्याला परताव्याची इच्छा नसते), जेव्हा लोक आपण दान करतो असा दाखवायचा प्रयत्न करतात मग ते facebook share असो किवां whatsapp status,post किवां इतर कोणतेही माध्यम याचा अर्थ असा कि दान करताना या लोकांनी मला प्रसिद्धी मिळेल किवां मी किती दानशुर आहे हे दाखवण्याची भावना मनात ठेवून केलेले दान होय.

अशी परताव्याची भावना मनात ठेवून केलेले दान हे दान नसून व्यवहाराच नाही का? व्यवहारात जस आपण पैसे देऊन त्या बदल्यात वस्तू,सेवा खरेदी करतो, तसेच परताव्याचा विचार करून केलेले दान म्हणजे व्यवहाराच.

असो माझे विचार मी digitally उतरवले, आपल्या प्रतिक्रियांची प्रतीक्षा राहील.

धन्यवाद!





Create a new class with name CookieHelper.cs In your project and paste the following code.

public class CookieHelper
    {
        #region Constants

        /// <summary>
        /// The cookie name
        /// </summary>
        public const string cookieName = "UserName";

        #endregion

        #region Enums

        public enum EnumCookieInterval
        {
            SECOND = 0,
            MINUTE = 1,
            DAY = 2,
            MONTH = 3,
            YEAR = 4
        };

        #endregion

        #region Utilities

        /// <summary>
        /// Calculates the cookie lifetime.
        /// </summary>
        /// <param name="duration">The duration.</param>
        /// <param name="durationType">Type of the duration.Use enum to specify</param>
        /// <returns>Expire date for cookie</returns>
        private static DateTime CalculateCookieLifetime(int duration, Enum durationType)
        {
            DateTime cookieExpire = DateTime.Now;

            switch (Convert.ToInt32(durationType))
            {
                case 0:
                    cookieExpire = DateTime.Now.AddSeconds(duration);
                    break;

                case 1:
                    cookieExpire = DateTime.Now.AddMinutes(duration);
                    break;

                case 2:
                    cookieExpire = DateTime.Now.AddDays(duration);
                    break;

                case 3:
                    cookieExpire = DateTime.Now.AddMonths(duration);
                    break;

                case 4:
                    cookieExpire = DateTime.Now.AddYears(duration);
                    break;

                default:
                    cookieExpire = DateTime.Now.AddDays(duration);
                    break;
            }
            return cookieExpire;
        }
        
        #endregion

        #region Methods

        /// <summary>
        /// Creates the cookie.
        /// </summary>
        /// <param name="cookieName">Name of the cookie.</param>
        /// <param name="cookieValue">The cookie value.</param>
        /// <param name="durationType">Type of the duration.Use enum to specify</param>
        /// <param name="duration">The duration.</param>
        /// <returns></returns>
        public static string CreateCookie(string cookieName, string cookieValue, Enum durationType, int duration)
        {

            HttpCookie myCookie = new HttpCookie(cookieName);

            // Set the cookie value.
            myCookie.Value = cookieValue;

            // Set the cookie expiration date.
            myCookie.Expires = CalculateCookieLifetime(duration, durationType);

            // Add the cookie.
            //Response.Cookies.Add(myCookie);
            HttpContext.Current.Response.Cookies.Add(myCookie);

            return cookieValue;

        }

        /// <summary>
        /// Reads the cookie.
        /// </summary>
        /// <param name="cookieName">Name of the cookie.</param>
        /// <returns></returns>
        public static string ReadCookie(string cookieName)
        {

            string cookieValue = string.Empty;

            HttpCookie myCookie = new HttpCookie(cookieName);
            myCookie = HttpContext.Current.Request.Cookies[cookieName];

            // Read the cookie information and display it.
            if (myCookie != null)
                cookieValue = myCookie.Value;


            return cookieValue;
        }

        /// <summary>
        /// Updates the cookie.
        /// </summary>
        /// <param name="cookieName">Name of the cookie.</param>
        /// <param name="cookieValue">The cookie value.</param>
        /// <param name="durationType">Type of the duration.Use enum to specify</param>
        /// <param name="duration">The duration.</param>
        /// <returns></returns>
        public static string UpdateCookie(string cookieName, string cookieValue, Enum durationType, int duration)
        {

            HttpCookie myCookie = new HttpCookie(cookieName);
            myCookie = HttpContext.Current.Request.Cookies[cookieName];

            // Set the cookie value.
            myCookie.Value = cookieValue;

            // Set the cookie expiration date.
            myCookie.Expires = CalculateCookieLifetime(duration, durationType);

            // Add the cookie.
            //Response.Cookies.Add(myCookie);
            HttpContext.Current.Response.Cookies.Add(myCookie);

            return cookieValue;

        }

        /// <summary>
        /// Deletes the cookie.
        /// </summary>
        /// <param name="cookieName">Name of the cookie.</param>
        public static void DeleteCookie(string cookieName)
        {
            HttpCookie myCookie = new HttpCookie(cookieName);

            DateTime cookieExpire = DateTime.Now;

            // Set the cookie expiration date.
            myCookie.Expires = cookieExpire.AddDays(-1);
            HttpContext.Current.Response.Cookies.Add(myCookie);

        }

        #endregion
    }



How to use?


1. Create cookie 

string cookie = CookieHelper.CreateCookie(CookieHelper.cookieName, "Here is cookie value", CookieHelper.EnumCookieInterval.DAY, 7);

string cookie = CookieHelper.CreateCookie(CookieHelper.cookieName, "Here is cookie value", CookieHelper.EnumCookieInterval.MONTH, 1);

2. Read Cookie

string cookie = CookieHelper.ReadCookie(CookieHelper.cookieName);

3. Update Cookie

string newCookie = CookieHelper.UpdateCookie(CookieHelper.cookieName, "Updated cookie value", CookieHelper.EnumCookieInterval.DAY, 14);

4. Delete Cookie

CookieHelper.DeleteCookie(CookieHelper.cookieName);

Hope it will helps you. Let me know your thoughts!



In almost 90% of projects, we need to upload images to server and store them. In most cases, hackers try to exploit an image upload system and try to upload exploitable materials like webshells, some harmful scripts, table deletions scripts, etc.

To prevent this, I have written one helper function which validates file in many conditions and makes sure the file is in correct image format. The code is not fully written by me, I researched many articles and filtered the conditions which helps us to validate the required output.
        /// <summary>
        /// Verifies that a uploading file is in valid Image format
        /// </summary>
        /// <author>
        /// Mayur Lohite
        /// </author>
        /// <param name="postedFile">File which is selected for upload</param>
        /// <param name="imageMinBytes">Minimum file size in byte</param>
        /// <param name="imageMaxBytes">Maximum file size in byte</param>
        /// <returns>true if the file is a valid image format and false if it's not</returns>
        public static bool IsValidImageFormat(HttpPostedFileBase postedFile, int imageMinBytes, long imageMaxBytes)
        {

            //-------------------------------------------
            //  Check the image extension
            //-------------------------------------------
            if (Path.GetExtension(postedFile.FileName).ToLower() != ".jpg"
                && Path.GetExtension(postedFile.FileName).ToLower() != ".png"
                && Path.GetExtension(postedFile.FileName).ToLower() != ".gif"
                && Path.GetExtension(postedFile.FileName).ToLower() != ".jpeg")
            {
                return false;
            }

            //-------------------------------------------
            //  Check the image MIME types
            //-------------------------------------------
            if (postedFile.ContentType.ToLower() != "image/jpg" &&
                        postedFile.ContentType.ToLower() != "image/jpeg" &&
                        postedFile.ContentType.ToLower() != "image/pjpeg" &&
                        postedFile.ContentType.ToLower() != "image/gif" &&
                        postedFile.ContentType.ToLower() != "image/x-png" &&
                        postedFile.ContentType.ToLower() != "image/png")
            {
                return false;
            }



            //-------------------------------------------
            //  Attempt to read the file and check the first bytes
            //-------------------------------------------
            try
            {
                if (!postedFile.InputStream.CanRead)
                {
                    return false;
                }

                if (postedFile.ContentLength < imageMinBytes)
                {
                    return false;
                }

                if (postedFile.ContentLength < imageMinBytes)
                {
                    return false;
                }

                byte[] buffer = new byte[512];
                postedFile.InputStream.Read(buffer, 0, 512);
                string content = System.Text.Encoding.UTF8.GetString(buffer);
                if (Regex.IsMatch(content, @"<script|<html|<head|<title|<body|<pre|<table|<a\s+href|<img|<plaintext|<cross\-domain\-policy",
                    RegexOptions.IgnoreCase | RegexOptions.CultureInvariant | RegexOptions.Multiline))
                {
                    return false;
                }
            }
            catch (Exception)
            {
                return false;
            }

            //-------------------------------------------
            //  Try to instantiate new Bitmap, if .NET will throw exception
            //  we can assume that it's not a valid image
            //-------------------------------------------

            try
            {
                using (var bitmap = new System.Drawing.Bitmap(postedFile.InputStream))
                {
                }
            }
            catch (Exception)
            {
                return false;
            }

            return true;
        }


Hope it will help you. Let me know your thoughts!

An Interface

At first, interfaces came into focus because there was no multiple inheritance supported by C#, meaning you could not inherit from multiple classes, but you could implement multiple interfaces. The interfaces are grouping of object in terms of behavior.

An interface contains only signatures. There is no implementation, only the signatures of the functionality the interface provides. An interface can contain signatures of methods, properties, indexers & events.

Interface doesn't do anything like classes and abstract classes, it just defines what the class will perform if some class inherits it. An interface can also be inherited from another interface.

If we take an example of USB (Universal Serial Bus), it's an interface which has signature of Connection functionality. The USB interface only knows I have to connect with Desktop Computer or laptop or anything, but it does not know what implementation will come to connection. It may be Pen drive (mass storage), it may be Printer(COM Ports).

Let's see the concept in a programmatic way.

Using the Code

An USB Interface

public interface IUSB
{
    public void MakeConnection();
}

The Pendrive Class

public class Pendrive: IUSB
{
    public void MakeConnection()
    {
        //The code for connecting pen drive to desktop, laptop or other
        throw new NotImplementedException();
    }
}

The Printer Class

public class Printer: IUSB
{
    public void MakeConnection()
    {
        //The code for connecting printer to desktop, laptop or other
        throw new NotImplementedException();
    }
}

Decoupled System

Now the decoupled system means the way of defining the architecture of project that one module cannot depend on another module. The system should depend on abstraction rather than implementation.

In a realistic way, suppose I am currently designing the MVC project with Microsoft SQL Server but if in future I have to change the database to MySQL. In this case, I just need to change the Repository Implementation not a Controller.

So my Controller should be implementing the abstraction/interfaces of Repository. When I change the implementation of Repository, I just have to change it to new implementation, rest nothing will be changed.
private readonly IRepository _repository;
public ActionResult Index()
{
    _repository = new MSSQLRepository();
    //or
    //_repository = new MySQLRepository();
}

Decoupled System Using Interface By Realistic Example

As I am a developer, I got one requirement from client. The requirement is that I have to get current exchange rate by currency. So I have to Pass USD and Get current INR Rate or Current EURO rate. There are various web services that offer this functionality.

So consider providers ABC, DEF & PQR provide these web services, but they charge different rates. So my client said to me at first we will try ABC's Service, but if we find it's not reliable, then we have to change it at a later stage.

So let's consider the dirty code first:
public class ProductController : Controller
{
    public async Task<ActionResult> DisplayProduct()
    {
        Product p = new Product();
        p.Name = "Test Product";
        p.Type = "USD";
        p.Price = 5;
        
        //All ABC Service code which returns USD to INR 
        double INR = 
        p.Price = p.Price * INR;
        return View(p);
    }
}

Now let's assume that I am going to use this dirty code implementation directly in the controller. It has some disadvantages.
  1. If I implement service code directly to controller, I have to change it in all controllers which need currency conversion functionality. For this demo, I have only 1 Controller and 1 Action, but in a real world application, we may have lots of Controllers and Actions.
  2. To change the code in each and very controller which needs conversion functionality, it's very frustrating, and it's the opposite of Good Programming Standard. As per Programming Standard, we have to reduce repetitive efforts.
Now, I have to design some logic in a decoupled way, So when client says we have to go with another service provider, I don't have to change much in my Controller. But the problem is how to design the decoupled logic and then Interface comes in focus.
The design is as follows:
  • What is important here is, I have to get current exchange rate by passing currency.
  • So I created one ICurrencyExchangeService Interface.
  • Then, I just defined the function signatures in interface, e.g., GetCurrentINR(string currency); GetCurrentEURO(string currency);

ICurrencyExchangeService Interface

public interface ICurrencyExchangeService
{
    double GetCurrentINR(string type);
    double GetCurrentEURO(string type);
} 
  • Now I created ABCCurrencyExchangeService class which inherited from ICurrencyExchangeService
  • All functions [defined in interface] will be implemented here as per the ABC Service documentation

ABCCurrencyExchangeService Class

public class ABCCurrencyExchangeService : ICurrencyExchangeService
{
    public double GetCurrentINR(string type)
    {
        double exchangeRate = 0.0;

        //Call the ABC web service with appropriate parameters as per the  documentation. 
        //Assign converted rate to exchangeRate variable

        return exchangeRate;
    }

    public double GetCurrentEURO(string type)
    {
        double exchangeRate = 0.0;

        //Call the ABC web service with appropriate parameters as per the  documentation. 
        //Assign converted rate to exchangeRate variable

        return exchangeRate;
    }    
}
  • Now I am using ICurrencyExchangeService in my Controller.

ProductController Controller [MVC]

public class ProductController : Controller
{
    ICurrencyExchangeService  _currencyService = new ABCCurrencyExchangeService();

    public async Task<ActionResult> DisplayProduct()
    {
        Product p = new Product();
        p.Name = "Test Product";
        p.Type = "USD";
        p.Price = 5;
        //But we have to show INR prices
        double INR = _currencyService.GetCurrentINR(p.Type);
        p.Price = p.Price * INR;
        return View(p);
    }
}
  • All my code is going well but after few days, client says the service is not reliable. We have to migrate it to another service, i.e., DEF Service.
  • Now what to do? I have 2 options:
    1. Change the ABCCurrencyExchangeService Class implementation as per the DEF Service documentation. But it's against the name standard because we are implementing the DEF service under the class name ABCCurrencyExchangeService.
    2. Also one more disadvantage is suppose after some days, if client says we have to revert our old service that is ABC, then we have to again implement ABC service.
  • The second and good option is we will create new class DEFCurrencyExchangeService which inherited from ICurrencyExchangeService Interface and I implement all the methods as per the DEF Service.
public class DEFCurrencyExchangeService : ICurrencyExchangeService
{
    public double GetCurrentINR(string type)
    {
        double exchangeRate = 0.0;

        //Call the DEF web service with appropriate parameters as per the  documentation. 
        //Assign converted rate to exchangeRate variable

        return exchangeRate;
    }

    public double GetCurrentEURO(string type)
    {
        double exchangeRate = 0.0;

        //Call the DEF web service with appropriate parameters as per the  documentation. 
        //Assign converted rate to exchangeRate variable

        return exchangeRate;
    }
    
}
  • Now I just have to change the one line in my controller. The repository is now pointing to DEFCurrencyExchangeService Class. So my new Product Controller looks like:
public class ProductController : Controller
{
    //ICurrencyExchangeService  _currencyService = new ABCCurrencyExchangeService();

    ICurrencyExchangeService  _currencyService = new DEFCurrencyExchangeService();

    public async Task<ActionResult> DisplayProduct()
    {
        Product p = new Product();
        p.Name = "Test Product";
        p.Type = "USD";
        p.Price = 5;
        //But we have to show INR prices
        double INR = _currencyService.GetCurrentINR(p.Type);
        p.Price = p.Price * INR;
        return View(p);
    }
}
  • I just change one line and our new service is started. Also, after some days, if my client asks me to revert back to ABC service again, I have to change only 1 line.
  • If you are plan to use it with Dependency Injection container so it gives us flexibility at whole new level. You don't have to change anything in Controller. We have to just change in dependency injection container and it's done.

Using Unity as Dependency Injection Container


If you don't know about DI or how to use it, please check the following links:

http://www.codeproject.com/Articles/786332/ASP-NET-MVC-with-Unity-Dependency-Injection
http://www.asp.net/mvc/overview/older-versions/hands-on-labs/aspnet-mvc-4-dependency-injection

Using the Code

UnityConfig.cs Class Configuration (Located in App_Start\UnityConfig.cs)

public static class UnityConfig
    {
        public static void RegisterComponents()
        {
            var container = new UnityContainer();

            // register all your components with the container here
            // it is NOT necessary to register your controllers

            // e.g. container.RegisterType< ITestService, TestService >();
            //container.RegisterType< ICurrencyExchangeService , ABCCurrencyExchangeService >();
            container.RegisterType< ICurrencyExchangeService , DEFCurrencyExchangeService >();

            DependencyResolver.SetResolver(new UnityDependencyResolver(container));
        }
    }
  • The above code uses unity DI container and we have just changed mapping. Previously, ICurrencyExchangeService Interface was pointing to ABCCurrencyExchangeService Class and now it's pointing to DEFCurrencyExchangeService Class. The dynamic object creation is done by UNITY DI.
  • Now our new Product Controller will look like:

ProductController Class:

public class ProductController : Controller
{
    private readonly ICurrencyExchangeService  _currencyService;

    public ProductController(ICurrencyExchangeService  currencyService)
    {
        _currencyService = currencyService;
    }

    public async Task DisplayProduct()
    {
        Product p = new Product();
        p.Name = "Test Product";
        p.Type = "USD";
        p.Price = 5;
        //But we have to show INR prices
        double INR = _currencyService.GetCurrentINR(p.Type);
        p.Price = p.Price * INR;
        return View(p);
    }
}
The good architecture is at the heart of any project. The developer is always looking for great architecture that reduces repetitive code and separates the Data Access and Business Logic. So we will be creating our generic repository using ASP.NET MVC and Entity Framework. If you don’t know about Entity Framework, please click here to get started with Entity Framework. So before getting started with repository pattern, firstly we have to understand what is the repository pattern? and why we want it?

Repository and Unit of Work Pattern


In simple words, repository means, the abstraction between your Data Access and Business Logic layers which will very useful for unit testing or test-driven development (TDD). By using repository, your system will be more loosely coupled.

In programming terms, we have to create one interface for each repository or entity. e.g. Student entity has One interface (IStudentInterface) in which all methods are declared like Insert, Update, Delete, Get and another is class (StudentRepository) which is inherited from IStudentInterface and StudentRepository will implement all the methods which are declared in Interface. When we instantiate the repository in our controller, we will use the interface so that the controller will accept a reference to any object that implements the repository interface. When the controller runs under a web server, it receives a repository that works with the Entity Framework.

When the controller runs under a unit test class, it receives a repository that works with data stored in a way that you can easily manipulate for testing, such as an in-memory collection. So we can supply fake repository in unit testing.

If you want to see the complete implementation, please refer to the following link:


Disadvantage


Each time we have to create Repository for each entity, it results in redundant code.

Using the Code


Now we need only a data access class which accepts any entity and performs required operation, e.g. CRUD. After studying lots of articles, theories and sample code, I got one very good reference of Generic Repository Pattern.

My code is heavily based on the Huy Nguyen’s Blog. Please refer to the following links:


I have changed a bit of code and added to new class library project as well as I added some common function which required to each project. Now I can use this library in any project. Following is the folder structure.

Mayur.DAL – Class library project with generic repository and common functions.

  • Core – Folder

    • GlobalCommonHelper.cs – An abstract class which contents all common function required to each project
  • Repository – Folder
    • IRepository.cs – Interface for generic repository
    • Repository.cs – Generic repository class inherited from IRepository. All methods are implemented in it.
    • IUnitOfWork.cs – Interface for unit of work class.
    • UnitOfWork.cs – Implemented SaveChanges() methods for Entity Framework . The unit of work class is very important when we execute any transitional command to the database like Insert, Update, Delete the entity framework not commit to database until Savechanges() method calls.

Mayur.Web – MVC project

  • Controller – Folder

    • HomeController.cs – Home controller with Index, Create, Edit, Delete ActionResult
  • Core – Folder
    • CommonHelper.cs – Inherited from Mayur.DAL.Core.GlobalCommonHelper.cs which contents all common methods related to MVC project
  • Model – Folder
    • Student.csStudent Model representing studnet table
  • Views – Folder
    • Index.chtml – Display All student html
    • Create.chtml – Create new student html
    • Edit.cshtml – Update student info html
    • Delete.cshtml – Delete student info html

Lets understand briefly each file in Mayur.DAL:

Repository Folder: In this folder, all the Data Access logic is present. There are 4 files, 2 are Interfaces and 2 are classes which inherited from respective Interface.

1. IRepository Interface

public interface IRepository : IDisposable
    {
        /// <summary>
        ///     Gets the unit of work.
        /// </summary>
        /// <value>The unit of work.</value>
        IUnitOfWork UnitOfWork { get; }
 
        /// <summary>
        ///     Gets entity by key.
        /// </summary>
        /// <typeparam name="TEntity">The type of the entity.</typeparam>
        /// <param name="keyValue">The key value.</param>
        /// <returns></returns>
        TEntity GetByKey<TEntity>(object keyValue) where TEntity : class;
 
        /// <summary>
        ///     Gets the query.
        /// </summary>
        /// <typeparam name="TEntity">The type of the entity.</typeparam>
        /// <returns></returns>
        IQueryable<TEntity> GetQuery<TEntity>() where TEntity : class;
 
        /// <summary>
        ///     Gets the query.
        /// </summary>
        /// <typeparam name="TEntity">The type of the entity.</typeparam>
        /// <param name="predicate">The predicate.</param>
        /// <returns></returns>
        IQueryable<TEntity> GetQuery<TEntity>
        (Expression<Func<TEntity, bool>> predicate) where TEntity : class;
 
 
        /// <summary>
        ///     Gets all.
        /// </summary>
        /// <typeparam name="TEntity">The type of the entity.</typeparam>
        /// <returns></returns>
        IEnumerable<TEntity> GetAll<TEntity>() where TEntity : class;
 
        /// <summary>
        ///     Gets the specified order by.
        /// </summary>
        /// <typeparam name="TEntity">The type of the entity.</typeparam>
        /// <typeparam name="TOrderBy">The type of the order by.</typeparam>
        /// <param name="orderBy">The order by.</param>
        /// <param name="pageIndex">Index of the page.</param>
        /// <param name="pageSize">Size of the page.</param>
        /// <param name="sortOrder">The sort order.</param>
        /// <returns></returns>
        IEnumerable<TEntity> Get<TEntity, 
        TOrderBy>(Expression<Func<TEntity, TOrderBy>> orderBy, int pageIndex,
            int pageSize, SortOrder sortOrder = SortOrder.Ascending) where TEntity : class;
 
        /// <summary>
        ///     Gets the specified criteria.
        /// </summary>
        /// <typeparam name="TEntity">The type of the entity.</typeparam>
        /// <typeparam name="TOrderBy">The type of the order by.</typeparam>
        /// <param name="criteria">The criteria.</param>
        /// <param name="orderBy">The order by.</param>
        /// <param name="pageIndex">Index of the page.</param>
        /// <param name="pageSize">Size of the page.</param>
        /// <param name="sortOrder">The sort order.</param>
        /// <returns></returns>
        IEnumerable<TEntity> Get<TEntity, 
        TOrderBy>(Expression<Func<TEntity, bool>> criteria,
            Expression<Func<TEntity, TOrderBy>> orderBy, int pageIndex, int pageSize,
            SortOrder sortOrder = SortOrder.Ascending) where TEntity : class;
 
 
        /// <summary>
        ///     Gets one entity based on matching criteria
        /// </summary>
        /// <typeparam name="TEntity">The type of the entity.</typeparam>
        /// <param name="criteria">The criteria.</param>
        /// <returns></returns>
        TEntity Single<TEntity>(Expression<Func<TEntity, 
        bool>> criteria) where TEntity : class;
 
 
 
        /// <summary>
        ///     Firsts the specified predicate.
        /// </summary>
        /// <typeparam name="TEntity">The type of the entity.</typeparam>
        /// <param name="predicate">The predicate.</param>
        /// <returns></returns>
        TEntity First<TEntity>(Expression<Func<TEntity, 
        bool>> predicate) where TEntity : class;
 
        /// <summary>
        ///     Finds entities based on provided criteria.
        /// </summary>
        /// <typeparam name="TEntity">The type of the entity.</typeparam>
        /// <param name="criteria">The criteria.</param>
        /// <returns></returns>
        IEnumerable<TEntity> Find<TEntity>
        (Expression<Func<TEntity, bool>> criteria) where TEntity : class;
 
 
 
        /// <summary>
        ///     Finds one entity based on provided criteria.
        /// </summary>
        /// <typeparam name="TEntity">The type of the entity.</typeparam>
        /// <param name="criteria">The criteria.</param>
        /// <returns></returns>
        TEntity FindOne<TEntity>(Expression<Func<TEntity, 
        bool>> criteria) where TEntity : class;
 
 
 
        /// <summary>
        ///     Counts the specified entities.
        /// </summary>
        /// <typeparam name="TEntity">The type of the entity.</typeparam>
        /// <returns></returns>
        int Count<TEntity>() where TEntity : class;
 
        /// <summary>
        ///     Counts entities with the specified criteria.
        /// </summary>
        /// <typeparam name="TEntity">The type of the entity.</typeparam>
        /// <param name="criteria">The criteria.</param>
        /// <returns></returns>
        int Count<TEntity>(Expression<Func<TEntity, 
        bool>> criteria) where TEntity : class;
 
 
 
        /// <summary>
        ///     Adds the specified entity.
        /// </summary>
        /// <typeparam name="TEntity">The type of the entity.</typeparam>
        /// <param name="entity">The entity.</param>
        void Add<TEntity>(TEntity entity) where TEntity : class;
 
        /// <summary>
        ///     Attaches the specified entity.
        /// </summary>
        /// <typeparam name="TEntity">The type of the entity.</typeparam>
        /// <param name="entity">The entity.</param>
        void Attach<TEntity>(TEntity entity) where TEntity : class;
 
        /// <summary>
        ///     Updates changes of the existing entity.
        ///     The caller must later call SaveChanges() 
        ///     on the repository explicitly to save the entity to database
        /// </summary>
        /// <typeparam name="TEntity">The type of the entity.</typeparam>
        /// <param name="entity">The entity.</param>
        void Update<TEntity>(TEntity entity) where TEntity : class;
 
        /// <summary>
        ///     Deletes the specified entity.
        /// </summary>
        /// <typeparam name="TEntity">The type of the entity.</typeparam>
        /// <param name="entity">The entity.</param>
        void Delete<TEntity>(TEntity entity) where TEntity : class;
 
        /// <summary>
        ///     Deletes one or many entities matching the specified criteria
        /// </summary>
        /// <typeparam name="TEntity">The type of the entity.</typeparam>
        /// <param name="criteria">The criteria.</param>
        void Delete<TEntity>(Expression<Func<TEntity, 
        bool>> criteria) where TEntity : class;
 
        /// <summary>
        ///     Deletes entities which satisfy specificatiion
        /// </summary>
        /// <typeparam name="TEntity">The type of the entity.</typeparam>
        /// <param name="criteria">The criteria.</param>
        //void Delete<TEntity>
        (ISpecification<TEntity> criteria) where TEntity : class;
    }

2. Repository Class

/// <summary>
    ///     Generic repository Class
    /// </summary>
    public partial class Repository : IRepository, IDisposable
    {
        //Private Variables
        private bool bDisposed;
        private DbContext context;
        private IUnitOfWork unitOfWork;
         
        #region Contructor Logic
 
        /// <summary>
        /// Initializes a new instance of the 
        /// <see cref="Repository<TEntity>"/> class.
        /// </summary>
        public Repository()
        {
 
        }
 
        /// <summary>
        ///     Initializes a new instance of the 
        /// <see cref="Repository<TEntity>" /> class.
        /// </summary>
        /// <param name="context">The context.</param>
        public Repository(DbContext contextObj)
        {
            if (contextObj == null)
                throw new ArgumentNullException("context");
            this.context = contextObj;
        }
 
        public Repository(ObjectContext contextObj)
        {
            if (contextObj == null)
                throw new ArgumentNullException("context");
            context = new DbContext(contextObj, true);
        }
 
        public void Dispose()
        {
            Close();
        }
 
        #endregion
 
        #region Properties
 
        //DbContext Property
        protected DbContext DbContext
        {
            get
            {
                if (context == null)
                    throw new ArgumentNullException("context");
 
                return context;
            }
        }
 
        //Unit of Work Property
        public IUnitOfWork UnitOfWork
        {
            get
            {
                if (unitOfWork == null)
                {
                    unitOfWork = new UnitOfWork(DbContext);
                }
                return unitOfWork;
            }
        }
 
        #endregion
         
        #region Data Display Methods
 
        //Helper Method tp create Query [IQuerable]
 
        public TEntity GetByKey<TEntity>(object keyValue) where TEntity : class
        {
            EntityKey key = GetEntityKey<TEntity>(keyValue);
 
            object originalItem;
            if (((IObjectContextAdapter)DbContext).
            ObjectContext.TryGetObjectByKey(key, out originalItem))
            {
                return (TEntity)originalItem;
            }
 
            return default(TEntity);
        }
 
        public IQueryable<TEntity> GetQuery<TEntity>() where TEntity : class
        {
            string entityName = GetEntityName<TEntity>();
            return ((IObjectContextAdapter)DbContext).
            ObjectContext.CreateQuery<TEntity>(entityName);
        }
 
        public IQueryable<TEntity> GetQuery<TEntity>
        (Expression<Func<TEntity, bool>> predicate) where TEntity : class
        {
            return GetQuery<TEntity>().Where(predicate);
        }
 
 
        //All Readonly Display or fetch data methods.
        public IEnumerable<TEntity> GetAll<TEntity>() where TEntity : class
        {
            return GetQuery<TEntity>().AsEnumerable();
        }
 
        public IEnumerable<TEntity> Get<TEntity, TOrderBy>
        (Expression<Func<TEntity, TOrderBy>> orderBy, int pageIndex,
            int pageSize, SortOrder sortOrder = SortOrder.Ascending) where TEntity : class
        {
            if (sortOrder == SortOrder.Ascending)
            {
                return GetQuery<TEntity>()
                    .OrderBy(orderBy)
                    .Skip((pageIndex - 1) * pageSize)
                    .Take(pageSize)
                    .AsEnumerable();
            }
            return
                GetQuery<TEntity>()
                    .OrderByDescending(orderBy)
                    .Skip((pageIndex - 1) * pageSize)
                    .Take(pageSize)
                    .AsEnumerable();
        }
 
        public IEnumerable<TEntity> Get<TEntity, 
        TOrderBy>(Expression<Func<TEntity, bool>> criteria,
            Expression<Func<TEntity, TOrderBy>> orderBy, int pageIndex, int pageSize,
            SortOrder sortOrder = SortOrder.Ascending) where TEntity : class
        {
            if (sortOrder == SortOrder.Ascending)
            {
                return GetQuery(criteria).
                    OrderBy(orderBy).
                    Skip((pageIndex - 1) * pageSize).
                    Take(pageSize)
                    .AsEnumerable();
            }
            return
                GetQuery(criteria)
                    .OrderByDescending(orderBy)
                    .Skip((pageIndex - 1) * pageSize)
                    .Take(pageSize)
                    .AsEnumerable();
        }
 
        public TEntity Single<TEntity>
        (Expression<Func<TEntity, bool>> criteria) where TEntity : class
        {
            return GetQuery<TEntity>().Single<TEntity>(criteria);
        }
 
        public TEntity First<TEntity>
        (Expression<Func<TEntity, bool>> predicate) where TEntity : class
        {
            return GetQuery<TEntity>().First(predicate);
        }
 
        public IEnumerable<TEntity> Find<TEntity>
        (Expression<Func<TEntity, bool>> criteria) where TEntity : class
        {
            return GetQuery<TEntity>().Where(criteria);
        }
 
        public TEntity FindOne<TEntity>
        (Expression<Func<TEntity, bool>> criteria) where TEntity : class
        {
            return GetQuery<TEntity>().Where(criteria).FirstOrDefault();
        }
 
        public int Count<TEntity>() where TEntity : class
        {
            return GetQuery<TEntity>().Count();
        }
 
        public int Count<TEntity>
        (Expression<Func<TEntity, bool>> criteria) where TEntity : class
        {
            return GetQuery<TEntity>().Count(criteria);
        }
 
        #endregion
         
        #region Data Transactional Methods
 
        public void Add<TEntity>(TEntity entity) where TEntity : class
        {
            if (entity == null)
            {
                throw new ArgumentNullException("entity");
            }
            DbContext.Set<TEntity>().Add(entity);
        }
 
        public void Attach<TEntity>(TEntity entity) where TEntity : class
        {
            if (entity == null)
            {
                throw new ArgumentNullException("entity");
            }
 
            DbContext.Set<TEntity>().Attach(entity);
        }
 
        public void Update<TEntity>(TEntity entity) where TEntity : class
        {
            string fqen = GetEntityName<TEntity>();
 
            object originalItem;
            EntityKey key = 
            ((IObjectContextAdapter)DbContext).ObjectContext.CreateEntityKey(fqen, entity);
            if (((IObjectContextAdapter)DbContext).ObjectContext.TryGetObjectByKey
            (key, out originalItem))
            {
                ((IObjectContextAdapter)DbContext).ObjectContext.ApplyCurrentValues
                (key.EntitySetName, entity);
            }
        }
 
        public void Delete<TEntity>(TEntity entity) where TEntity : class
        {
            if (entity == null)
            {
                throw new ArgumentNullException("entity");
            }
            DbContext.Set<TEntity>().Remove(entity);
        }
 
        public void Delete<TEntity>(Expression<Func<TEntity, 
        bool>> criteria) where TEntity : class
        {
            IEnumerable<TEntity> records = Find(criteria);
 
            foreach (TEntity record in records)
            {
                Delete(record);
            }
        }
 
        #endregion
 
        #region Internal Processing Private Methods
 
        private EntityKey GetEntityKey<TEntity>(object keyValue) where TEntity : class
        {
            string entitySetName = GetEntityName<TEntity>();
            ObjectSet<TEntity> objectSet = 
            ((IObjectContextAdapter)DbContext).ObjectContext.CreateObjectSet<TEntity>();
            string keyPropertyName = objectSet.EntitySet.ElementType.KeyMembers[0].ToString();
            var entityKey = new EntityKey
            (entitySetName, new[] { new EntityKeyMember(keyPropertyName, keyValue) });
            return entityKey;
        }
 
        private string GetEntityName<TEntity>() where TEntity : class
        {
            // Thanks to Kamyar Paykhan -  
            // http://huyrua.wordpress.com/2011/04/13/
            // entity-framework-4-poco-repository-and-specification-pattern-upgraded-to-ef-4-1/
            // #comment-688
            string entitySetName = ((IObjectContextAdapter)DbContext).ObjectContext
                .MetadataWorkspace
                .GetEntityContainer(((IObjectContextAdapter)DbContext).
                    ObjectContext.DefaultContainerName,
                    DataSpace.CSpace)
                .BaseEntitySets.Where(bes => bes.ElementType.Name == typeof(TEntity).Name).First().Name;
            return string.Format("{0}.{1}", 
            ((IObjectContextAdapter)DbContext).ObjectContext.DefaultContainerName,
                entitySetName);
        }
 
        private string RemoveAccent(string txt)
        {
            byte[] bytes = System.Text.Encoding.GetEncoding("Cyrillic").GetBytes(txt);
            return System.Text.Encoding.ASCII.GetString(bytes);
        }
 
        private bool IsValidTag(string tag, string tags)
        {
            string[] allowedTags = tags.Split(',');
            if (tag.IndexOf("javascript") >= 0) return false;
            if (tag.IndexOf("vbscript") >= 0) return false;
            if (tag.IndexOf("onclick") >= 0) return false;
 
            var endchars = new char[] { ' ', '>', '/', '\t' };
 
            int pos = tag.IndexOfAny(endchars, 1);
            if (pos > 0) tag = tag.Substring(0, pos);
            if (tag[0] == '/') tag = tag.Substring(1);
 
            foreach (string aTag in allowedTags)
            {
                if (tag == aTag) return true;
            }
 
            return false;
        }
 
        #endregion          
 
        #region Disposing Methods
 
        protected void Dispose(bool bDisposing)
        {
            if (!bDisposed)
            {
                if (bDisposing)
                {
                    if (null != context)
                    {
                        context.Dispose();
                    }
                }
                bDisposed = true;
            }
        }
 
        public void Close()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }
 
        #endregion
    }
 }

3. IUnitOfWork Interface

public interface IUnitOfWork : IDisposable
{
    void SaveChanges();
}

4. UnitOfWork Class

internal class UnitOfWork : IUnitOfWork
    {
        private readonly DbContext _dbContext;
 
        public UnitOfWork(DbContext context)
        {
            _dbContext = context;
        }  
 
        public void SaveChanges()
        {
            ((IObjectContextAdapter)_dbContext).ObjectContext.SaveChanges();
        } 
 
        #region Implementation of IDisposable
 
        private bool _disposed;
 
        /// <summary>
        ///     Performs application-defined tasks associated with freeing, 
        ///     releasing, or resetting unmanaged resources.
        /// </summary>
        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }
 
        /// <summary>
        ///     Disposes off the managed and unmanaged resources used.
        /// </summary>
        /// <param name="disposing"></param>
        private void Dispose(bool disposing)
        {
            if (!disposing)
                return;
 
            if (_disposed)
                return;
 
            _disposed = true;
        }
 
        #endregion        
    }

Now in Mayur.DAL.Core folder, there is one abstract class with all common functions required for each project. If you have any new functions which we required in each project, please suggest in the comments.

5. Mayur.DAL.Core.GlobalCommonHelper.cs Class

abstract public class GlobalCommonHelper
    {
        #region General Methods
 
        /// <summary>
        /// Take any string and encrypt it using SHA1 then
        /// return the encrypted data
        /// </summary>
        /// <param name="data">input text you will enterd to encrypt it</param>
        /// <returns>return the encrypted text as hexadecimal string</returns>
        public string GetSHA1HashData(string data)
        {
            //create new instance of md5
            SHA1 sha1 = SHA1.Create();
 
            //convert the input text to array of bytes
            byte[] hashData = sha1.ComputeHash(Encoding.Default.GetBytes(data));
 
            //create new instance of StringBuilder to save hashed data
            StringBuilder returnValue = new StringBuilder();
 
            //loop for each byte and add it to StringBuilder
            for (int i = 0; i < hashData.Length; i++)
            {
                returnValue.Append(hashData[i].ToString());
            }
 
            // return hexadecimal string
            return returnValue.ToString();
        }
 
        /// <summary>
        /// Creates a slug url from string .
        /// </summary>
        /// <param name="phrase"></param>
        /// <returns></returns>
        public string GetSlugURLFromString(string phrase)
        {
            string str = RemoveAccent(phrase).ToLower();
            // invalid chars          
            str = Regex.Replace(str, @"[^a-z0-9\s-]", "");
            // convert multiple spaces into one space  
            str = Regex.Replace(str, @"\s+", " ").Trim();
            // cut and trim
            str = str.Substring(0, str.Length <= 45 ? str.Length : 45).Trim();
            str = Regex.Replace(str, @"\s", "-"); // hyphens  
            return str;
        }
 
        /// <summary>
        /// Delete file by specified path.
        /// </summary>
        /// <param name="path">path of file.</param>
        public void DeleteTargetFile(string path)
        {
            if (File.Exists(path))
            {
                File.SetAttributes(path, FileAttributes.Normal);
                File.Delete(path);
            }
        }
 
        /// <summary>
        /// Sent email to target email address with attachment.
        /// </summary>
        /// <param name="toEmail">Email addresses of 
        /// one or multiple receipients semi colon (;) separated values.</param>
        /// <param name="subject">Email subject</param>
        /// <param name="body">Email body</param>
        /// <returns>True | False</returns>
        public bool SendEmailToTarget(string toEmail, string subject, string body)
        {
 
            bool success = false;
            try
            {
                SmtpClient SmtpServer = new SmtpClient();
                MailMessage mail = new MailMessage();
 
                SmtpServer.Credentials = new NetworkCredential(
                    Convert.ToString(ConfigurationManager.AppSettings["fromEmail"]),
                    Convert.ToString(ConfigurationManager.AppSettings["fromPassword"]));
 
                SmtpServer.Host = Convert.ToString
                (ConfigurationManager.AppSettings["hostName"]);
                SmtpServer.Port = Convert.ToInt32
                (ConfigurationManager.AppSettings["portNumber"]);
 
                if (Convert.ToBoolean
                (ConfigurationManager.AppSettings["isEnableSSL"]) == true)
                    SmtpServer.EnableSsl = true;
 
                mail.From = new MailAddress(Convert.ToString
                (ConfigurationManager.AppSettings["senderName"]));
 
                string[] multiEmails = toEmail.Split(';');
                foreach (string email in multiEmails)
                {
                    mail.To.Add(email);
                }
 
                mail.Subject = subject;
                mail.IsBodyHtml = true;
                mail.Body = body;
                SmtpServer.Send(mail);
                mail.Dispose();
                success = true;
            }
            catch (Exception)
            {
                success = false;
            }
            return success;
        }
 
        /// <summary>
        /// Sent email to target email address with attachment.
        /// </summary>
        /// <param name="toEmail">Email addresses of 
        /// one or multiple receipients semi colon (;) separated values.</param>
        /// <param name="subject">Email subject</param>
        /// <param name="body">Email body</param>
        /// <param name="body">Email attachment file path</param>
        /// <returns>True | False</returns>
        public bool SendEmailToTarget(string toEmail, string subject, string body, string attachmentPath)
        {
 
            bool success = false;
            try
            {
                SmtpClient SmtpServer = new SmtpClient();
                MailMessage mail = new MailMessage();
 
                SmtpServer.Credentials = new NetworkCredential(
                    Convert.ToString(ConfigurationManager.AppSettings["fromEmail"]),
                    Convert.ToString(ConfigurationManager.AppSettings["fromPassword"]));
 
                SmtpServer.Host = Convert.ToString
                (ConfigurationManager.AppSettings["hostName"]);
                SmtpServer.Port = Convert.ToInt32
                (ConfigurationManager.AppSettings["portNumber"]);
 
                if (Convert.ToBoolean(ConfigurationManager.AppSettings["isEnableSSL"]) == true)
                    SmtpServer.EnableSsl = true;
 
                mail.From = new MailAddress(Convert.ToString
                (ConfigurationManager.AppSettings["senderName"]));
 
                string[] multiEmails = toEmail.Split(';');
                foreach (string email in multiEmails)
                {
                    mail.To.Add(email);
                }
 
                Attachment attachment;
                attachment = new System.Net.Mail.Attachment(attachmentPath);
                mail.Attachments.Add(attachment);
 
                mail.Subject = subject;
                mail.IsBodyHtml = true;
                mail.Body = body;
                SmtpServer.Send(mail);
                mail.Dispose();
                success = true;
            }
            catch (Exception)
            {
                success = false;
            }
            return success;
        }
 
        /// <summary>
        /// Strips tags
        /// </summary>
        /// <param name="text">Text</param>
        /// <returns>Formatted text</returns>
        public string RemoveHtmlFromString(string text)
        {
            if (String.IsNullOrEmpty(text))
                return string.Empty;
 
            text = Regex.Replace(text, @"(>)(\r|\n)*(<)", "><");
            text = Regex.Replace(text, "(<[^>]*>)([^<]*)", "$2");
            text = Regex.Replace(text, "(&#x?[0-9]{2,4};|"|&| 
            |<|>|€|©|®|‰|‡|†|‹|
            ›|„|”|“|‚|’|‘|—|
            –|‏|‎|‍|‌| | | |˜|
            ˆ|Ÿ|š|Š)", "@");
 
            return text;
        }
 
        /// <summary>
        /// Verifies that a string is in valid e-mail format
        /// </summary>
        /// <param name="email">Email to verify</param>
        /// <returns>true if the string is a valid e-mail address and false if it's not</returns>
        public bool IsValidEmail(string email)
        {
            if (String.IsNullOrEmpty(email))
                return false;
 
            email = email.Trim();
            var result = Regex.IsMatch(email, "^(?:[\\w\\!\\#\\$\\%\\&\\
            '\\*\\+\\-\\/\\=\\?\\^\\`\\{\\|\\}\\~]+\\.)*[\\w\\!\\#\\$\\%\\&\\
            '\\*\\+\\-\\/\\=\\?\\^\\`\\{\\|\\}\\~]+@(?:(?:(?:[a-zA-Z0-9]
            (?:[a-zA-Z0-9\\-](?!\\.)){0,61}[a-zA-Z0-9]?\\.)+[a-zA-Z0-9]
            (?:[a-zA-Z0-9\\-](?!$)){0,61}[a-zA-Z0-9]?)|(?:\\[(?:(?:[01]?\\d{1,2}|2[0-4]
            \\d|25[0-5])\\.){3}(?:[01]?\\d{1,2}|2[0-4]\\d|25[0-5])\\]))$", RegexOptions.IgnoreCase);
            return result;
        }
 
        /// <summary>
        /// Returns Allowed HTML only.
        /// </summary>
        /// <param name="text">Text</param>
        /// <returns>Allowed HTML</returns>
        public string EnsureOnlyAllowedHtml(string text)
        {
            if (String.IsNullOrEmpty(text))
                return string.Empty;
 
            const string allowedTags = "br,hr,b,i,u,a,div,ol,ul,li,blockquote,img,span,p,em," +
                                        "strong,font,pre,h1,h2,h3,h4,h5,h6,address,cite";
 
            var m = Regex.Matches(text, "<.*?>", RegexOptions.IgnoreCase);
            for (int i = m.Count - 1; i >= 0; i--)
            {
                string tag = text.Substring(m[i].Index + 1, m[i].Length - 1).Trim().ToLower();
 
                if (!IsValidTag(tag, allowedTags))
                {
                    text = text.Remove(m[i].Index, m[i].Length);
                }
            }
 
            return text;
        }
 
        #endregion
 
        #region Internal Processing Private Methods
 
        private string RemoveAccent(string txt)
        {
            byte[] bytes = System.Text.Encoding.GetEncoding("Cyrillic").GetBytes(txt);
            return System.Text.Encoding.ASCII.GetString(bytes);
        }
 
        private bool IsValidTag(string tag, string tags)
        {
            string[] allowedTags = tags.Split(',');
            if (tag.IndexOf("javascript") >= 0) return false;
            if (tag.IndexOf("vbscript") >= 0) return false;
            if (tag.IndexOf("onclick") >= 0) return false;
 
            var endchars = new char[] { ' ', '>', '/', '\t' };
 
            int pos = tag.IndexOfAny(endchars, 1);
            if (pos > 0) tag = tag.Substring(0, pos);
            if (tag[0] == '/') tag = tag.Substring(1);
 
            foreach (string aTag in allowedTags)
            {
                if (tag == aTag) return true;
            }
 
            return false;
        }
 
        #endregion
 
    }

Now our Generic repository is ready with inbuilt common functions. Now we can see how to use them in controller. Suppose we have Students model in which studentID, name, rollNo columns. Following is the code for HomeController.

  1. Before we proceed, we are using code first approach and following is our DbContext class:

    public partial class MyFirstDbContext : DbContext
    {
        public MyFirstDbContext()
        : base("name=MyFirstDbContext")
        {
            Database.SetInitializer<MyFirstDbContext>(null);
        }
     
        public virtual DbSet<Students> Students { get; set; }
     
        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
     
        }
    }
  2. We have created an abstract class in out Data Access Layer which contains Global common function means almost in each project we required that function. The class is an abstract class so we cannot create an instance of it . So we create new CommonHelper.cs Class in Our Web project which is inherited from Abstract class and we can implement project-specific common functions here.
    public class CommonHelper : GlobalCommonHelper
    {
         public int PageSize = 25;
         //Some common functions. Only Project-specific.     
    }
  3. Now we can see how we use repository in our HomeController. The HomeController is as follows:
    //Constructor
    public HomeController()
    {
          IRepository repository = new Repository(new MyFirstDbContex);
          CommonHelper helper = new CommonHelper();
    }

    1. Index.cshtml represents the view of all Students in table format. So ActionResult is as follows:

      public ActionResult Index()
      {
            return View(repository.GetAll<Students>());
      }
    2. Create.cshtml creates new Students record means it inserts new record in db.
      public ActionResult Create()
      {
            return View();
      }
       
      [HttpPost]
      public ActionResult Create(Students studPost)
      {
           if(ModelState.IsValid)
           {
                repository.Add<Students>(studPost);
                repository.UnitOfWork.SaveChanges();
           }
      }
    3. Edit.cshtml represents the edit view in which we can modify the records.
      public ActionResult Edit(int id=0)
      {
            if(id==0)
                return HttpNotFound();
             
             Students stud = repository.FindOne<Students>(x=>x.studentID == id);
            return View(stud);
      }
       
      [HttpPost]
      public ActionResult Edit(Students studPost)
      {
           if(ModelState.IsValid)
           {
                repository.Update<Students>(studPost);
                repository.UnitOfWork.SaveChanges();
           }
      }
    4. And the last one is Delete as follows:
      [HttpPost]
      public ActionResult Delete(int id=0)
      {
                if(id==0)
                    return HttpNotFound();
       
                Students stud = repository.FindOne<Students>(x=>x.studentID == id);
                if(stud == null)
                    return HttpNotFound();
       
                repository.Delete<Students>(stud);
                repository.UnitOfWork.SaveChanges();
      }

I need more suggestions and improvements from you. Please comment.


Revisions


  • 31/05/2015: Article published
  • 30/04/2016: Article Updated fixed some constructor error as per the "Irene Troupansky" Suggestions.


In a dynamic web application, the session is crucial to hold the information of current logged in user identity/data. So someone without authentication cannot have access to some Page or any ActionResult, to implement this kind of functionality, we need to check session exists (is not null) in every action which required authentication.

So, the general method is as follows:

[HttpGet]
public ActionResult Home()
{
    if(Session["ID"] == null)
        return RedirectToAction("Login","Home");
}

We have to check the above 2 statements each time and in each ActionResult, but it may cause 2 problems.

  1. Repeat Things: As per the good programming stranded, we don't have to repeat the things. Create a module of common code and access it multiple times/repeatedly
  2. Code missing: We have to write code multiple times so it might happen some time we forget to write code in some method or we missed it.

How To Avoid?


The ASP.NET MVC provides a very great mechanism i.e., Action Filters. An action filter is an attribute. You can apply most action filters to either an individual controller action or an entire controller.

If you want to know more about action filter, please click here.

So we will create a custom Action Filter that handles session expiration and if session is null, redirect to Login Action.

Create a new class in your project and copy the following code:

namespace Mayur.Web.Attributes
{
    public class SessionTimeoutAttribute : ActionFilterAttribute
    {
        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            HttpContext ctx = HttpContext.Current;
            if (HttpContext.Current.Session["ID"] == null)
            {
                filterContext.Result = new RedirectResult("~/Home/Login");
                return;
            }
            base.OnActionExecuting(filterContext);
        }
    }
}

Now our Action Filter is created and we are ready to use it. The following code will show you how we can apply attribute to Action or to complete controller.

1. Apply to Action


[HttpGet]
[SessionTimeout]
public ActionResult MyProfile()
{
    return View();
}

2. Apply to Controller


[SessionTimeout]
public class HomeController : Controller
{
    [HttpGet]
    public async ActionResult MyProfile()
    {
        return View();
    }

    [HttpGet]
    public async ActionResult MyQuestions()
    {
        return View();
    }

    [HttpGet]
    public async ActionResult MyArticles()
    {
        return View();
    }
}

Now all actions of Home Controller will check for session when hit with the help of Action Filter. So we have reduced the code and repetitive things. This is the benefits of Action Filters.

Happy coding !!!



In this article, I will explain how to create a custom HTML helper as per your requirement.

If you know the MVC and Helpers already, you can skip the next paragraph and if you don't know, here is an explanation about helpers.

What are HTML Helpers in MVC?


  • An HTML helper is a method that is used to render the specified html content in View. It can be implemented as an extension method.
  • If you know the ASP.NET webforms, you might know the concept of web controls. e.g. <asp:TextBox /><asp:label /> If you use these controls in web form on browsers, they will converted to their equivalent HTML controls like TextBox will be <input type="text" /> and label will be <span></span>
  • HTML helpers methods are the same as web controls it allows to render appropriate HTML in view.

Let's take an example of how HTML helper looks like:

@Html.TextBox("Myname","Mayur Lohite")

This HTML helper will render the following HTML in view.

<input type="text" name="Myname" id="Myname" value="Mayur Lohite" />

The MVC provides a rich set of HTML helpers, e.g. @html.TextBox(), @Html.TextArea(), @Html.CheckBox(), etc. but if you take a closer look in HTML Helpers, there is no helper present for Image tag i.e. <img src="" />

So in this tutorial, we will create our own custom helper for <img src="" /> tag


So we have to achieve something like:

@Html.MyImage("~/Image/mayur.jpg","Mayur Lohite" />

So, it will generate the following HTML.

<img src="/Image/mayur.jpg" alt="Mayur Lohite" />

If you take a closer look at @Html in view, it is a property of HtmlHelper class. Right click on @Html in view and click on Go to Definition. You will get the following output.



Now to create custom HTML helper, we need to create extension method of HtmlHelper class. So we can access our custom method by @Html property.

How to Create an Extension Method for HtmlHelper Class?


  • We have to create a static method in static class.
  • First parameter has to be the type to which we are adding the extension method. In our case, it is HtmlHelper Class.
  • Return type should be IHtmlString, as these strings are excluded from html encoding.
  • To create HTML tag, we have to use TagBuilder class
  • Include the namespace of the helper method in view or web.config

Here is the code:

namespace MyMVCApp.CustomHtmlHelpers
{
    public static class CustomHtmlHelpers
    {
        public static IHtmlString MyImageHelper(this HtmlHelper helper, string src, string alt)
        {
            TagBuilder tb = new TagBuilder("img");
            tb.Attributes.Add("src", VirtualPathUtility.ToAbsolute(src));
            tb.Attributes.Add("alt", alt);

            return new MvcHtmlString(tb.ToString(TagRenderMode.SelfClosing));
        }
    }
}

So we have created our Extension method. Now it's time to call it in our view. The following code will give you an idea of how we can call it on view.

Here is the view:

@using MyMVCApp.CustomHtmlHelpers;

<!DOCTYPE html>

<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>Custom Helper</title>
</head>
<body>
    <div>
        @Html.MyImage("~/Images/mayur.jpg", "Mayur Lohite")
    </div>
</body>
</html>

Conclusion


The MVC provides us the flexibility to create our own HTML helpers by using an extension method of HtmlHelper class. We can develop the custom HTML helper as per the requirement, e.g., for image, some widgets, etc.