Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why class attribute not work in WebAPI?

I used default ASP.NET MVC4 Web Application Template and Visual Studio Create InitializeSimpleMembershipAttribute in Filters Directory and create account Controller like this:

[Authorize]
[InitializeSimpleMembership]
public class AccountController : Controller
{
/* Some Default Actions like Login, LogOff, Register, ...*/
}

and i try to make AccountController WebAPI, my code is:

[Authorize]
[InitializeSimpleMembership]
public class APIAccountController : ApiController
{
    [System.Web.Http.AcceptVerbs("GET", "POST")]
    [System.Web.Http.HttpGet]
    [System.Web.Http.HttpPost]
    [System.Web.Http.AllowAnonymous]
    [System.Web.Mvc.ValidateAntiForgeryToken]
    public string Login(string UserName, string Password, bool RememberMe)
    {
        if (WebSecurity.Login(UserName, Password, persistCookie: RememberMe))
        {
            return "OK";
        }

        return "Failed";
    }
}

now, when i call api, its break in this line:

if (WebSecurity.Login(UserName, Password, persistCookie: RememberMe))

and said: You must call the "WebSecurity.InitializeDatabaseConnection" method before you call any other method of the "WebSecurity" class.

i ran it in InitializeSimpleMembershipAttribute and webapi controller is same with controller.

why attribute not run in WebAPI?

like image 485
Mehdi Yeganeh Avatar asked Oct 04 '22 03:10

Mehdi Yeganeh


1 Answers

The [InitializeSimpleMembership]-attribute inherits from System.Web.Mvc.ActionFilterAttribute

Action filters for Web API need to inherit from System.Web.Http.Filters.ActionFilterAttribute, so the filter is not actually getting executed on your Web API controller.

There's two things you can do:

  • Either implement your own filter, inheriting from System.Web.Http.Filters.ActionFilterAttribute
  • Add the following code to your global.asax

    private static SimpleMembershipInitializer _initializer;
    private static object _initializerLock = new object();
    private static bool _isInitialized;
    
    protected void Application_Start()
    {
        // Ensure ASP.NET Simple Membership is initialized only once per app start 
    LazyInitializer.EnsureInitialized(ref _initializer, ref _isInitialized, ref _initializerLock); 
    }
    

For this to work you need to move the logic from InitializeMembership into a separate class and make sure you can access it from the global.asax.

like image 114
Kenneth Avatar answered Oct 19 '22 09:10

Kenneth