views:

309

answers:

2

hi i am trying to create a custom attribute for my MVC application so that i can call [CheckLogin] this is to check my cookie as i am not using forms authentification.

i have created a class CheckLogin and this is in my App_Code folder and the code is as follows:

  using System.Web.Mvc;
  using System.Attributes;
  using System.Diagnostics.CodeAnalysis;
  using System.Globalization;
  using System.Web;
  using System;

  namespace corian_MVC.Controllers
  {
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, Inherited = true, AllowMultiple = true)]
public class CheckLoginAttribute : FilterAttribute, IAuthorizationFilter
{

    public CheckLoginAttribute() { 



    }

    public void OnAuthorization(AuthorizationContext filterContext)
    {
        // TODO: perform your cookie checks
        if (!userIsAuthenticated)
        {
            filterContext.Result = new RedirectResult(string.Format(
                "/Admin/Login",
                filterContext.HttpContext.Request.Url.AbsoluteUri));
        }
    }
}

}

what it does is not important here, the problem is i cant get my code to recognise this attribute if it is one in the first place, also how do i redirect to action if the login is failed ????

many thanks

my admin class:

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


 namespace corian_MVC.Controllers
 {
[HandleError]
public class AdminController : Controller
{
    [AcceptVerbs(HttpVerbs.Get)]
    public ActionResult Index()
    {
        //check login is not banned

        if ((int)Session["LoginCount"] >= 3) RedirectToAction("TooMany");

        return View();
    }

    public ActionResult Fraud()
    {
        Session["LoginCount"] = 3;
        return View();
    }

    public ActionResult TooMany()
    {
        return View();
    }

    [CheckLogin]
    public ActionResult Welcome()
    {
        return View();
    }

    private void Createcookie()
    {

    }

}

}

+2  A: 

This scenario is best handled by implementing an IAuthorizationFilter.

[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, Inherited=true, AllowMultiple=true)]
public class CheckLoginAttribute : FilterAttribute, IAuthorizationFilter
{
    public void OnAuthorization(AuthorizationContext filterContext)
    {
        // TODO: perform your cookie checks
        if (!userIsAuthenticated)
        {
            filterContext.Result = new RedirectResult(string.Format(
                "/loginUrl?ReturnUrl={0}",  
                filterContext.HttpContext.Request.Url.AbsoluteUri));
        }
    }
}

Then you can apply this attribute either at the controller level or at some particular actions.

By the way do you have any particular reason for not using the built-in FormsAuthentication?

Darin Dimitrov
yeah thats great but i can not get the attribute to even be picked up in my controllers, the usual im missing an assembly reference, however there in the same namespace etc. is there something extra i have to do in order to make it available ????
minus4
I don't understand. You get compile errors or what?
Darin Dimitrov
Arghh, I see. You use `App_Code`. Well don't use this folder. This is only used for ASP.NET web sites and not web applications which the standard model for ASP.NET MVC template.
Darin Dimitrov
moved it from app_code to main root of site, I.E CheckLoginAttribute.cs sits next to default.aspx ?? still not picking it up
minus4
Did you actually marked any of your controller action methods with this attribute?
Darin Dimitrov
[CheckLogin] public ActionResult Welcome() { return View(); }
minus4
thats what produces the error when i build
minus4
What's the error message you are getting?
Darin Dimitrov
have updated my post above to reflect both sides of the coin the error message is : - Error 16 The type or namespace name 'CheckLoginAttribute' could not be found (are you missing a using directive or an assembly reference?)
minus4
Your code looks fine. There's something else going on. I would suggest you putting the definition of the attribute inside the same `.cs` file as your `AdminController` just before it and inside the namespace.
Darin Dimitrov
that way im just making a reference to a class, and would only be available within the code but even then i cant reference the class i even tried taking the code for the handleerrorArribute and changed the name and still no joy and thats straight from mvc source ???? lolol am at point of cracking up, now its a matter of principle ya know !!!! there isent really a right lot of info on this subject either, but MVC is suposed to be extensible in this way.
minus4
as for not using forms, i dont have any mssql on my servers i use mysql linux server farm, and i use subsonic... i did a little reading and from what ican gather it is possible to change database etc but all the grief of trying to get that to work is going to be harder than this. i think i am going to have to accept the losses and create a class and just call code on the views i wish to protect.
minus4
cracked it, stopped thinking of it as an attribute but as an action filter, created a folder called ActionFilters then public class CheckLoginActionFilter : ActionFilterAttribute once i knew what i was/should be looking for http://www.asp.net/LEARN/mvc/tutorial-14-cs.aspx has a very good working example.thanks for all your help, not the answer but you got me thinking and sometimes that is all it takes.
minus4
A: 

Include .cs file with your attribute to the solution. Just placing it "near default.aspx" is not enough.

queen3
please read below, it is no longer there it is in controllersand i have triedadding a using tag but it wont
minus4