Imran Baloch's Blog

  • Possible ASP.NET VNext Deployed Folder Structure(With and Without Source)

     

            Introduction:

     

                       When you work with ASP.NET VNext application then one thing that may come into your mind is how your folder structure will be look like if you deploy your application with or without source. In this article, I will tell you how your folder structure may look like if you deploy your application with packages or with source. Note that ASP.NET VNext still is in pre-release, so things might change when ASP.NET VNext will become RTM.  

     

            Description:

     

                        If you deploy your application then your application might be depend or not depend upon 3rd party packages and/or class libraries(Note ASP.NET VNext will be package dependent instead of assembly dependent). You might also want to deploy your web application as package instead of deploying the source. In any case you always have a root folder(let's say wwwroot). You will keep your bin, scripts, contents, fonts, etc. folders/files inside the wwwroot folder. Your wwwroot/bin folder should also include Microsoft.AspNet.Loader.IIS.dll(Helios) if you are deploying your app in IIS. In addition to wwwroot root folder, there will be always another root folder(let's say approot) which include packages and src folders. You need to keep the packages inside approot/packages folder and code inside approot/src. Let say you have YourSite.Web project (a web application), YourSite.Data and YourSite.Bussiness projects (class libraries) and Elmah(a third party package). Then the deployed application folder structure with source will look like,

      

            
    	wwwroot/bin/Microsoft.AspNet.Loader.IIS.dll
    	wwwroot/Contents/site.css
    	wwwroot/Contents/.......................................
    	........................................................
    	wwwroot/Scripts/jquery.js
    	wwwroot/Scripts/........................................
    	........................................................
    	........................................................
    
    	approot/src/YourSite.Web/project.json
    	approot/src/YourSite.Web/...............................
    	approot/src/YourSite.Data/project.json
    	approot/src/YourSite.Data/..............................
    	approot/src/YourSite.Bussiness/project.json
    	approot/src/YourSite.Bussiness/.........................
    	approot/packages/Elmah/{version}/.......................
    	........................................................
    

     

                        If you deploy/pack without source then the deployed folder structure will look like,

     

            
    	wwwroot/bin/Microsoft.AspNet.Loader.IIS.dll
    	wwwroot/Contents/site.css
    	wwwroot/Contents/.......................................
    	........................................................
    	wwwroot/Scripts/jquery.js
    	wwwroot/Scripts/........................................
    	........................................................
    	........................................................
    
    	approot/packages/YourSite.Web/{version}/................
    	approot/packages/YourSite.Data/{version}/...............
    	approot/packages/YourSite.Bussiness/{version}/..........
    	approot/packages/Elmah/{version}/.......................
    

                        

                                           

            Summary:

     

                        In this article I showed you how to deploy the ASP.NET VNext application using source and packages. You can check this link if you need more information.

    Read more...

  • ValidateAntiForgeryTokenAttribute and Ajax Requests

            Introduction:

                       Cross-Site Request Forgery (CSRF or XSRF) is still in the top ten list of The Open Web Application Security Project (OWASP). Fortunately, ASP.NET MVC has built-in support to mitigate this attack since its earlier versions. The default ASP.NET MVC template include code to mitigate this attack. But if you are using ajax requests then you need to keep some points in your mind. In this article, I will tell you some tips that will help you when you are doing CSRF protection in your ajax requests.

            Description:

     

     

                        First tip is that when you send an ajax request to server then you need to explicitly attach anti-forgery token with your request. Let say you have this form in your ASP.NET MVC view,

            
        @using (Html.BeginForm("Action", "Controller", FormMethod.Post, new { }))
        {
             @Html.AntiForgeryToken()
             .......................
             .......................
    

                        Then you can easily include/attach the request anti-forgery token with your ajax request using these lines of javascript(assuming that you are using jQuery),

            
        function appendAntiXsrfToken(data) {
            if (data instanceof Array) {
                data.push({ name: "__RequestVerificationToken", value: $('input[name=__RequestVerificationToken]').val() });
            } else {
                data.__RequestVerificationToken = $('input[name=__RequestVerificationToken]').val();
            }
        };
        .................................................
        appendAntiXsrfToken(data);
        $.ajax({
            type: 'POST',
            url: uri,
            data: data,
        })
    

                        Note that I am appending anti-forgery token to data before sending ajax request. The data can be object or array. The function will automatically handle this. 

                        On the server side, if you are using ajax then most of the time you need to send the anti-fogery exception type response in JSON format. You can handle this situation in a custom exception filter or in your BaseController.OnException method. Here is an example(you can change the JSON if you need different response), 

        
            protected override void OnException(ExceptionContext filterContext)
            {
                if (filterContext.ExceptionHandled || !Request.IsAjaxRequest() || !(filterContext.exception is HttpAntiForgeryException))
                {
                    base.OnException(filterContext);
                    return;
                }
                filterContext.ExceptionHandled = true;
                filterContext.Result = new JsonResult
                {
                    Data = new { code = 400, message = "Invalid Token" },
                    JsonRequestBehavior = JsonRequestBehavior.AllowGet
                };
    	}
    

                       You can also put your controller action in try/catch block and invoke AntiForgery.Validate explicitly.

                        On the server side, if you are using ajax then most of the time you need to send the anti-fogery exception type response in JSON format. You can handle this situation in a custom exception filter or in your BaseController.OnException method. Here is an example(you can change the JSON if you need different response), 

                       

            Summary:

                        Using ValidateAntiForgeryTokenAttribute with ajax requests, you might find some problems. In this article, I showed you some tips about using ASP.NET MVC ValidateAntiForgeryTokenAttribute with ajax requests.

    Read more...

  • A simple Bootstrap Pager Html Helper

            Introduction:


                       In ASP.NET MVC 5, MVC project templates uses Bootstrap 3.0 user interface framework. It makes the user interface sleek and responsive look. Bootstrap 3.0 also have nice pagination support. In this article, I will show you how to create a simple html helper which will generate Bootstrap 3.0 pagination specific markup.


            Description:

     

     

                        So, what do we need in this pager html helper? currentPageIndex(the current page number), action(the url pointing to an action), totalItems(total number(count) of items),  pageSize(items per page) and numberOfLinks(number of links in a page, for example if numberOfLinks = 5 then it will generate 1 2 3 4 5)


            
        namespace Shopex.Web.HtmlHelpers
        {
            public static class HtmlHelperExtensions
            {
                public static MvcHtmlString BootstrapPager(this HtmlHelper helper, int currentPageIndex, Func<int, string> action, int totalItems, int pageSize = 10, int numberOfLinks = 5)
                {
                    if (totalItems <= 0)
                    {
                        return MvcHtmlString.Empty;
                    }
                    var totalPages = (int)Math.Ceiling(totalItems / (double)pageSize);
                    var lastPageNumber = (int)Math.Ceiling((double)currentPageIndex / numberOfLinks) * numberOfLinks;
                    var firstPageNumber = lastPageNumber - (numberOfLinks - 1);
                    var hasPreviousPage = currentPageIndex > 1;
                    var hasNextPage = currentPageIndex < totalPages;
                    if (lastPageNumber > totalPages)
                    {
                        lastPageNumber = totalPages;
                    }
                    var ul = new TagBuilder("ul");
                    ul.AddCssClass("pagination");
                    ul.InnerHtml += AddLink(1, action,  currentPageIndex == 1, "disabled", "<<", "First Page");
                    ul.InnerHtml += AddLink(currentPageIndex - 1, action, !hasPreviousPage, "disabled", "<", "Previous Page");
                    for (int i = firstPageNumber; i <= lastPageNumber; i++)
                    {
                        ul.InnerHtml += AddLink(i, action, i == currentPageIndex, "active", i.ToString(), i.ToString());
                    }
                    ul.InnerHtml += AddLink(currentPageIndex + 1, action, !hasNextPage, "disabled", ">", "Next Page");
                    ul.InnerHtml += AddLink(totalPages, action, currentPageIndex == totalPages, "disabled", ">>", "Last Page");
                    return MvcHtmlString.Create(ul.ToString());
                }
    
                private static TagBuilder AddLink(int index, Func<int, string> action, bool condition, string classToAdd, string linkText, string tooltip)
                {
                    var li = new TagBuilder("li");
                    li.MergeAttribute("title", tooltip);
                    if (condition)
                    {
                        li.AddCssClass(classToAdd);
                    }
                    var a = new TagBuilder("a");
                    a.MergeAttribute("href", !condition ? action(index) : "javascript:");
                    a.SetInnerText(linkText);
                    li.InnerHtml = a.ToString();
                    return li;
                }
            }
        }
    

                        Now you can use this html helper in your view,


        
        @using HtmlHelpers
    
        @Html.BootstrapPager(pageIndex, index => Url.Action("Index", "Product", new { pageIndex = index }), Model.TotalCount, numberOfLinks: 10)
    


                       

            Summary:


                        Most applications requires some sort of nice and clean pagination. Bootstrap 3.0 have nice pagination support. In this article, I showed you how to create a simple html helper which generate Bootstrap 3.0 pagination specific markup.



    Read more...

  • Forcing Visual Studio 2013 to use ASP.NET MVC 5.1, ASP.NET Web API 2.1 and ASP.NET Web Pages 3.1

            Introduction:



                       DISCLAIMER: This was done completely for my own benefit, but I thought this might be useful to others, so I am sharing my work with you. But please backup your files before replacing.

                        A few days ago, Microsoft announced the release of ASP.NET MVC 5.1, ASP.NET Web API 2.1 and ASP.NET Web Pages 3.1 and Visual Studio 2013 Update 1. We can now create ASP.NET MVC 5.1, ASP.NET Web API 2.1 and ASP.NET Web Pages 3.1 application by creating a new web application and update the released NuGet packages(means running Install-Package Microsoft.AspNet.Mvc -Version 5.1.0, Install-Package Microsoft.AspNet.WebApi -Version 5.1.0 and Install-Package Microsoft.AspNet.WebPages -Version 3.1.0). But doing this every time when you create a new web application takes some time and easily forgettable. In this article, I will tell you some quick tips to force Visual Studio 2013 to use the new versions automatically when you create a new web application.  


            Description:

     

     

                        First of all download VS2013TemplatesForMVC5.1WebAPI2.1WebPages3.1. These templates will force Visual Studio 2013 to use MVC 5.1, Web API 2.1, Web Pages 3.1 and Katana(Owin) 2.1. The download zip file includes 3 folders. First, copy/paste the contents of 'C Program Files (x86) Microsoft ASP.NET ASP.NET Web Stack 5 Packages' to C:\Program Files (x86)\Microsoft ASP.NET\ASP.NET Web Stack 5\Packages. Next, copy/paste the contents of 'C Program Files (x86) Microsoft Visual Studio 12.0 Common7 IDE WebTemplates' to C://Program Files (x86)/Microsoft Visual Studio 12.0/Common7/IDE/WebTemplates and finally copy/paste the contents of 'C Program Files (x86) Microsoft Web Tools Packages' to C:\Program Files (x86)\Microsoft Web Tools\Packages. That's it. Now whenever you create a new web application, Visual Studio will use MVC 5.1, Web API 2.1, Web Pages 3.1 and Katana(Owin) 2.1. So, no need to update the NuGet packages.

     

            Summary:


                        Creating a new ASP.NET MVC 5.1, ASP.NET Web API 2.1 and ASP.NET Web Pages 3.1 application might be painful because you need to update the NuGet packages every time you create a new web application. In this article, I showed you how to force Visual Studio 2013 to use the new versions automatically when you create new web application. Hopefully you enjoyed my this article too.



    Read more...

  • Centralizing SqlDataSource Events

            Introduction:



                       I was working with an old legacy web-form application. This web-form includes a good amount of physical web-form pages and each web-form uses SqlDataSource control heavily. I was required to do some things with all SqlDataSource controls in all web-form pages. Doing this with each SqlDataSource control in all web-form pages is a daunting task. I was able to centralize SqlDataSource events to perform my tasks with all SqlDataSource controls just at one place. In this article, I will show you how to log the time taken by a SqlDataSource in a/an INSERT/UPDATE/DELETE/SELECT operation. I will also show you how to change the database isolation-level globally with SqlDataSource control. 


            Description:

     

     

                        In my legacy application, I have a base page class. If you don't have a base page then please create it first. Let's say we have WebForm1.aspx,


        <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="WebForm1.aspx.cs" Inherits="WebFormApp.WebForm1" %>
        <!DOCTYPE html>
        <html xmlns="http://www.w3.org/1999/xhtml">
        <head runat="server">
            <title></title>
        </head>
        <body>
            <form id="form1" runat="server">
            <div>
            
                <asp:GridView ID="GridView1" AutoGenerateDeleteButton="True" AutoGenerateEditButton="True" AutoGenerateSelectButton="True" runat="server" AutoGenerateColumns="False" DataKeyNames="Id" DataSourceID="SqlDataSource1" EmptyDataText="There are no data records to display.">
                    <Columns>
                        <asp:BoundField DataField="Id" HeaderText="Id" ReadOnly="True" SortExpression="Id" />
                        <asp:BoundField DataField="Name" HeaderText="Name" SortExpression="Name" />
                    </Columns>
                </asp:GridView>
                <asp:SqlDataSource ID="SqlDataSource1" runat="server" ConnectionString="<%$ ConnectionStrings:SampleConnectionString1 %>" DeleteCommand="DELETE FROM [Product] WHERE [Id] = @Id" InsertCommand="INSERT INTO [Product] ([Id], [Name]) VALUES (@Id, @Name)" ProviderName="<%$ ConnectionStrings:SampleConnectionString1.ProviderName %>" SelectCommand="SELECT [Id], [Name] FROM [Product]" UpdateCommand="UPDATE [Product] SET [Name] = @Name WHERE [Id] = @Id">
                    <DeleteParameters>
                        <asp:Parameter Name="Id" Type="Int32" />
                    </DeleteParameters>
                    <InsertParameters>
                        <asp:Parameter Name="Id" Type="Int32" />
                        <asp:Parameter Name="Name" Type="String" />
                    </InsertParameters>
                    <UpdateParameters>
                        <asp:Parameter Name="Name" Type="String" />
                        <asp:Parameter Name="Id" Type="Int32" />
                    </UpdateParameters>
                </asp:SqlDataSource>
            
            </div>
            </form>
        </body>
        </html>
    

                        I have a Product table with Id and Name. This simple web-form page allows user to see, update and delete a product. Here is the WebForm1 code-behind,


        
        public partial class WebForm1 : BasePage
        {
            protected void Page_Load(object sender, EventArgs e)
            {
            }
        }
    


                        Note that WebForm1 is inheriting from BasePage instead of System.Web.UI.Page. Your all web-form pages should be inherit from BasePage in order to centralize SqlDataSource events. For making our work easy, we will create an extension methods for the ControllCollection class,

     

        public static class ControllCollectionExtensions
        {
            public static IEnumerable<Control> FindAll(this ControlCollection collection)
            {
                foreach (Control item in collection)
                {
                    yield return item;
                    if (item.HasControls())
                    {
                        foreach (var subItem in item.Controls.FindAll())
                        {
                            yield return subItem;
                        }
                    }
                }
            }
            public static IEnumerable<T> FindAll<T>(this ControlCollection collection) where T : Control
            {
                return collection.FindAll().OfType<T>();
            }
        }
    

     

     

                        The ControlCollection.FindAll extension method recursively find all controls of a specific type. Here is a simple version of BasePage.cs,

     

     

        public class BasePage : System.Web.UI.Page
        {
            private Logger logger = LogManager.GetCurrentClassLogger();
            protected override void OnLoad(EventArgs e)
            {
                base.OnLoad(e);
                RegisterEvents();
            }
    
            protected virtual void ExecutingSqlDatasource(object sender, SqlDataSourceCommandEventArgs e)
            {
                var stopWatch = new Stopwatch();
                stopWatch.Start();
                Context.Items[e.Command.CommandText] = stopWatch;
                e.Command.Connection.Open();
                e.Command.Transaction = e.Command.Connection.BeginTransaction(IsolationLevel.ReadUncommitted);
            }
    
            protected virtual void ExecutedSqlDatasource(object sender, SqlDataSourceStatusEventArgs e)
            {
                var stopWatch = Context.Items[e.Command.CommandText] as Stopwatch;
                stopWatch.Stop();
                logger.Info(string.Format("{0} takes {1}", e.Command.CommandText, stopWatch.Elapsed.ToString()));
                if (e.Exception == null)
                {
                    e.Command.Transaction.Commit();
                }
                else
                {
                    e.Command.Transaction.Rollback();
                }
            }
    
            private void RegisterEvents()
            {
                var sqlDataSourceCollection = Controls.FindAll<SqlDataSource>();
                foreach (var sqlDataSource in sqlDataSourceCollection)
                {
                    if (!string.IsNullOrEmpty(sqlDataSource.SelectCommand))
                    {
                        sqlDataSource.Selecting += ExecutingSqlDatasource;
                        sqlDataSource.Selected += ExecutedSqlDatasource;
                    }
                    if (!string.IsNullOrEmpty(sqlDataSource.InsertCommand))
                    {
                        sqlDataSource.Inserting += ExecutingSqlDatasource;
                        sqlDataSource.Inserted += ExecutedSqlDatasource;
                    }
                    if (!string.IsNullOrEmpty(sqlDataSource.UpdateCommand))
                    {
                        sqlDataSource.Updating += ExecutingSqlDatasource;
                        sqlDataSource.Updated += ExecutedSqlDatasource;
                    }
                    if (!string.IsNullOrEmpty(sqlDataSource.DeleteCommand))
                    {
                        sqlDataSource.Deleting += ExecutingSqlDatasource;
                        sqlDataSource.Deleted += ExecutedSqlDatasource;
                    }
                }
            }
        }
    

                       

                         BasePage simply invoke RegisterEvents method during OnLoad. RegisterEvents method first grab all the SqlDataSource controls on the current page using the above FindAll extension method. Then for each SqlDataSource control, register the XXXing and XXXted event if their related command exist(for example, check SqlDataSource.SelectCommand exist before registering SqlDataSource.Selecting and SqlDataSource.Selected events). Then on a XXXing event, I am creating and starting a Stopwatch and then saving this Stopwatch in Context.Items for later use.  I am also setting the sql connection transaction-level  as read-uncommitted/dirty-read(please don't use this transaction-level unless you have some valid reason). Then inside XXXted event, I am committing or roll-backing the transaction depending on exception exist. I am also grabbing the Stopwatch, stopping and logging the total elapsed time. Here I am using I am using NLog to log the timespan. You can use any other logging framework.

     

            Summary:


                        Centralizing the SqlDataSource events is a daunting task. Specially, when you have a huge amount of web-form pages. In this article, I showed you how easily one can centralize the SqlDataSource events. I also showed you how to change the transaction-level used in SqlDataSource and how to log the timespan for each raw SQL(or SP) used by  SqlDataSource. Hopefully you enjoyed my this article too.



    Read more...

  • My favourite SQL Server 3rd Party Tools

            Introduction:


                       There are some great 3rd party tools that makes the development of SQL Server faster, easier, smarter and enjoyable. In this small blog post I would like to point some good 3rd party SQL Server tools which help me a lot during application development.


            Description:

     

     

            SQL Complete:

     

                        dbForge's SQL Complete is one of my favorite tool. It is an add-on of SQL Server. It has a free and paid version. It simplify and accelerate your work by predicting keywords and object names. It has a great intellisense. Also, it support SQL formatter, statement expansion, SQL snippets, code navigation and much more. You can find more about SQL complete at http://www.devart.com/dbforge/sql/sqlcomplete/ 

     

            SQL Search:

     

                        Red Gate's SQL Search is another very helpful tool. SQL Search quickly find fragments of SQL text within stored procedures, functions, views and more. It's completly free. It also allows you to quickly navigate to different objects. It makes the search easier and increase your development efficiency.  You can find more at http://www.red-gate.com/products/sql-development/sql-search/  

                       

     

             SQL Sentry Plan Explorer:

     

                        If you are performance guy then you must have SQL Sentry Plan Explorer. It makes the query plan analysis very efficient. It is very lightweight and standalone. It's color coding highlights the potential trouble areas. It allows deeper analysis. It also have free and paid version.  You can find more at http://sqlsentry.net/plan-explorer/sql-server-query-view.asp

     

     

             SQL Toolbelt:

     

                        SQL Toolbelt include sixteen essential and excellent tools for SQL Server. It include a powerful set of tools. For example, SQL Compare which compare and sync the database schema. You can find more at http://www.red-gate.com/products/sql-development/sql-toolbelt/

     

            Summary:


                        In this article, I showed you some very essential and most important SQL SERVER 3rd party tools that I use in my daily application develoment. Hopefully you enjoyed my this article too.



    Read more...

  • A simple implementation of Microsoft.AspNet.Identity

            Introduction:


                       Microsoft.AspNet.Identity (famously known as ASP.NET Identity) is a brand new library for asp.net membership system that allows you to build modern ASP.NET web applications. The beauty of ASP.NET Identity is that it allows you to use any storage system. There is an implementation of Microsoft.AspNet.Identity in EF provided by Microsoft. You can also find some implementation of Microsoft.AspNet.Identity by community. For example, AspNet.Identity.RavenDB and NHibernate.AspNet.Identity. Currently, the EF implementation include Roles and Claims. But sometimes, you don't need any Claims and Roles. In this article, I will show you how to implement an implementation of Microsoft.AspNet.Identity without using Claims and Roles.


            Description:

     

     

                        First of all create a MVC 5 application. Then implement IUser,


            
        public class ApplicationUser : IUser
        {
            public ApplicationUser()
            {
                this.Id = Guid.NewGuid().ToString();
            }
            public ApplicationUser(string userName): this()
            {
                UserName = userName;
            }
            public virtual string Id { get; set; }
            public virtual string PasswordHash { get; set; }
            public virtual string SecurityStamp { get; set; }
            public virtual string UserName { get; set; }
        }
    

                        Next we need a DbContet to store the Users,


        
        public class ApplicationDbContext : DbContext
        {
            public ApplicationDbContext()
                : base("DefaultConnection")
            {
            }
            public virtual IDbSet<ApplicationUser> Users { get; set; }
        }
    


                        and then we need to implement IUserStore, IUserPasswordStore and IUserSecurityStampStore,

     

            
        public class MyUserStore : IUserStore<ApplicationUser>, IUserPasswordStore<ApplicationUser>, IUserSecurityStampStore<ApplicationUser>
        {
            UserStore<IdentityUser> userStore = new UserStore<IdentityUser>(new ApplicationDbContext());
            public MyUserStore()
            {
            }
            public Task CreateAsync(ApplicationUser user)
            {
                var context = userStore.Context as ApplicationDbContext;
                context.Users.Add(user);
                context.Configuration.ValidateOnSaveEnabled = false;
                return context.SaveChangesAsync();
            }
            public Task DeleteAsync(ApplicationUser user)
            {
                var context = userStore.Context as ApplicationDbContext;
                context.Users.Remove(user);
                context.Configuration.ValidateOnSaveEnabled = false;
                return context.SaveChangesAsync();
            }
            public Task<ApplicationUser> FindByIdAsync(string userId)
            {
                var context = userStore.Context as ApplicationDbContext;
                return context.Users.Where(u => u.Id.ToLower() == userId.ToLower()).FirstOrDefaultAsync();
            }
            public Task<ApplicationUser> FindByNameAsync(string userName)
            {
                var context = userStore.Context as ApplicationDbContext;
                return context.Users.Where(u => u.UserName.ToLower() == userName.ToLower()).FirstOrDefaultAsync();
            }
            public Task UpdateAsync(ApplicationUser user)
            {
                var context = userStore.Context as ApplicationDbContext;
                context.Users.Attach(user);
                context.Entry(user).State = EntityState.Modified;
                context.Configuration.ValidateOnSaveEnabled = false;
                return context.SaveChangesAsync();
            }
            public void Dispose()
            {
                userStore.Dispose();
            }
           
            public Task<string> GetPasswordHashAsync(ApplicationUser user)
            {
                var identityUser = ToIdentityUser(user);
                var task = userStore.GetPasswordHashAsync(identityUser);
                SetApplicationUser(user, identityUser);
                return task;
            }
            public Task<bool> HasPasswordAsync(ApplicationUser user)
            {
                var identityUser = ToIdentityUser(user);
                var task = userStore.HasPasswordAsync(identityUser);
                SetApplicationUser(user, identityUser);
                return task;
            }
            public Task SetPasswordHashAsync(ApplicationUser user, string passwordHash)
            {
                var identityUser = ToIdentityUser(user);
                var task = userStore.SetPasswordHashAsync(identityUser, passwordHash);
                SetApplicationUser(user, identityUser);
                return task;
            }
            public Task<string> GetSecurityStampAsync(ApplicationUser user)
            {
                var identityUser = ToIdentityUser(user);
                var task = userStore.GetSecurityStampAsync(identityUser);
                SetApplicationUser(user, identityUser);
                return task;
            }
            public Task SetSecurityStampAsync(ApplicationUser user, string stamp)
            {
                var identityUser = ToIdentityUser(user);
                var task = userStore.SetSecurityStampAsync(identityUser, stamp);
                SetApplicationUser(user, identityUser);
                return task;
            }
            private static void SetApplicationUser(ApplicationUser user, IdentityUser identityUser)
            {
                user.PasswordHash = identityUser.PasswordHash;
                user.SecurityStamp = identityUser.SecurityStamp;
                user.Id = identityUser.Id;
                user.UserName = identityUser.UserName;
            }
            private IdentityUser ToIdentityUser(ApplicationUser user)
            {
                return new IdentityUser
                {
                    Id = user.Id,
                    PasswordHash = user.PasswordHash,
                    SecurityStamp = user.SecurityStamp,
                    UserName = user.UserName
                };
            }
        }
    

     

     

                        For password hash and security stamp, I am using the UserStore's implementation for making thing simpler. Finally we just need to change AccountController's constructor to leverage our MyUserStore implementation,

     

     

            public AccountController()
                : this(new UserManager<ApplicationUser>(new MyUserStore()))
            {
            }
    
            public AccountController(UserManager<ApplicationUser> userManager)
            {
                UserManager = userManager;
            }
    

                       

     

     

            Summary:


                        The new Microsoft.AspNet.Identity make it very easy to extend the storage system. In this article, I showed you how to implement a simple implementation of Microsoft.AspNet.Identity. Hopefully you enjoyed my this article too.



    Read more...