Ajax Authorize like stackoverflow with custom attribute in aspnet mvc 2

February 19th, 2010  |  Published in aspnet mvc

As stackoverflow is getting bigger and bigger , it becomes such a great source of information for IT developer in my opinion. On the other hand, it brings out a lot of good practice that the website does offer on it functionality, and one of which is the ajax authentication when user click on buttons that required logged in(see the picture to get what I mean). Thus, I decided to implement my own version of this functionality for one of my result. It turned out to be quite easy to do this, thanks to great flexibility created by aspnet mvc. So here is my approach for this.

First, I created a class called AuthorizeWithAjaxAttribute, which inherits from AuthorizeAttribute, the class code is:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace YourProject.Infrastructure
{
    public class AuthorizeWithAjaxAttribute:AuthorizeAttribute
    {
        public override void OnAuthorization(AuthorizationContext filterContext)
        {
            base.OnAuthorization(filterContext);

            if (filterContext.Result is HttpUnauthorizedResult && filterContext.HttpContext.Request.IsAjaxRequest())
            {
                filterContext.HttpContext.Response.StatusCode = 200;

                filterContext.Result = new ContentResult() { Content = "404" };
            }
        }
    }
}

2. Now I just need to add these attribute to the action that required ajax authorization like:

  [AuthorizeWithAjax()]
        public ActionResult Vote()
        {
               //Your vote action code
        }

3. Now, in the ajax return method ( in the ajax options on ajax helper, set the complete to the name of this function);

function CheckAuthenticatedAjax(data) {
    var szResult = data.get_data();
    if (szResult.toString() == "404") {
        $("#divAnswers").parent().append('<div class="messagepop pop"><p><label >You need to login first</label></p><p>Click<a href="' + szLogInUrl + '">here</a> to log in.</p><p> <a class="close" href="/">Cancel</a></p></div>');
        $(".pop").slideFadeToggle()
        //$("#email").focus();
        return false;
    }

}

That is it, now ajax authorization is fully implemented on the website. Please feel free to leave any comment here.
Hope this is helpful for you guys some how.

Use windsor in aspnet MVC 2

February 18th, 2010  |  Published in aspnet mvc

For those of you who doesnt know about DI ( dependency injection ) or IOC (Inversion of Control), I suggest you

have a look at this blog post written by Phil Haack http://haacked.com/archive/2007/12/07/tdd-and-dependency-injection-

with-asp.net-mvc.aspx. For me, on every single MVC project that I have done, this practice is always a must-

have one that I recommend.  There are plenty of choices out there for you to choose and the one that I have

always used the most was structure map that  Phil haved mentioned above. However, in one of the recent project, I

was trying to implementing IOC using windsor since I found it quite interesting.

For this, I have been  googling around like always and this article has got most of my attention since I just

dont like dealing with xml configuration , http://blog.andreloker.de/post/2009/03/28/ASPNET-MVC-with-

Windsor-programmatic-controller-registration.aspx. There were couple of more articles that was related to the

same subject if you do some more googling, however most of them was used in aspnet mvc 1 and things has changed.

Therefore I got to try implementing a bit  and bob from each source of information to come up with the solution

that I found most appropriate  for my aspnet mvc 2 application. So here it goes:

1. First step:

Go to this link http://www.castleproject.org/castle/download.html,

and download the release under windsor,  after extract the castle-windsor zip file, you just need to add the

following files in the bin folder to your project:

Castle.Core.dll

Castle.DynamicProxy2.dll

Castle.MicroKernel

Castle.Windsor.dll

2. Second Step:

We need to create custom Controller Factory class, create a new .cs file and called it .i.e

WindsorControllerFactory.cs. Here is the code for this class:


using System;

using System.Collections.Generic;

using System.Linq;

using System.Web;

using System.Web.Mvc;

using System.Web.Routing;

using Castle;

using Castle.Core;

using Castle.Windsor;

using Castle.MicroKernel;

using System.Reflection;

using Castle.MicroKernel.ComponentActivator;

using Castle.MicroKernel.Registration;

namespace YOurProject.Infrastructure

{

public class WindsorControllerFactory : DefaultControllerFactory

{

readonly IWindsorContainer container;

public WindsorControllerFactory(IWindsorContainer container) {

this.container = container;

}

protected override IController GetControllerInstance(System.Web.Routing.RequestContext requestContext, Type

controllerType) {

return (IController)this.container.Resolve(controllerType);

}

}

}

3. Third step

Now we just need to add more code to the Global.asax file for the web site to use our controller factory instead

of the default one. Here is all the code in this file:

using System;

using System.Collections.Generic;

using System.Linq;

using System.Web;

using System.Web.Mvc;

using System.Web.Routing;

using Castle;

using Castle.Core;

using Castle.Windsor;

using Castle.MicroKernel;

using YourProject.Infrastructure;

using System.Reflection;

using Castle.MicroKernel.ComponentActivator;

using Castle.MicroKernel.Registration;

namespace YorProject.Web

{

// Note: For instructions on enabling IIS6 or IIS7 classic mode,

// visit http://go.microsoft.com/?LinkId=9394801

public class MvcApplication : System.Web.HttpApplication

{

static IWindsorContainer container;

public static void RegisterRoutes(RouteCollection routes)

{

routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

routes.IgnoreRoute("{*favicon}", new { favicon = @"(.*/)?favicon.ico(/.*)?" });

//routes.MapRoute(

//    "Default",                                              // Route name

//    "{controller}/{action}/{id}",                           // URL with parameters

//    new { controller = "Home", action = "Index", id = "" }  // Parameter defaults

//);

routes.MapRoute("Default", // Route name

"{controller}/{action}/{id}",

new

{

controller = "Home",

action = "Index",

id = ""

});  // Parameter defaults )

}

//this is for the windsor

//static void CreateWindsorContainer()

//{

//    container = new WindsorContainer();

//}

protected void Application_Start()

{

RegisterRoutes(RouteTable.Routes);

CreateWindsorContainer();

RegisterControllers();

RegisterControllerFactory();

}

static void RegisterControllers()

{

//this is to find all the class that implement icontroller interface

IEnumerable&lt;Type&gt; controllerTypes = from t in Assembly.GetExecutingAssembly().GetTypes()

where typeof(IController).IsAssignableFrom(t)

select t;

//now add component life style for these classes

//transient is used since a controller can be used multiple times

foreach (Type t in controllerTypes)

container.AddComponentLifeStyle(t.FullName, t, LifestyleType.Transient);

//these are to register the component that we used for the controllers

container.Register( Component.For&lt;your repository interface&gt;().ImplementedBy&lt; the class of the

repository that you used for this kind of interface &gt;().LifeStyle.Transient);

}

//this is to register the controller factory  without using xml configuration

static void RegisterControllerFactory()

{

container.Register(

Component

.For&lt;IControllerFactory&gt;()

.ImplementedBy&lt;WindsorControllerFactory&gt;()

.LifeStyle.Singleton

);

var controllerFactory = container.Resolve&lt;IControllerFactory&gt;();

ControllerBuilder.Current.SetControllerFactory(controllerFactory);

}

static void CreateWindsorContainer()

{

if (container == null)

{

container = new WindsorContainer();

container.Register(

Component

.For&lt;IWindsorContainer&gt;()

.Instance(container)

);

}

}

}

}

That is it, now you have windsor implemented  in your aspnet mvc project. Hope you find this useful

Tags: , , ,

Hello world!

February 9th, 2010  |  Published in Uncategorized

Hello there,

Been digging on computer since 10 years old, IT has been the largest part of me life.  It has been almost 4 years now that I been doing development in the real  world , I has always wanted a space that I can share my daily experiences with techie people with the hope that some one else will not have to spend much time googling around as much as I did.

Anyway, thanks for visiting my blog, hopefully you will find something useful.