asp.net mvc - Why CustomRoleManager Initializer not run in Web API? -
i created custom membership , custom role provider follow exact same link:
for custom membership:
http://msdn.microsoft.com/en-us/library/6tc47t75(v=vs.100).aspx
more info:
http://msdn.microsoft.com/en-us/library/ms366730(v=vs.100).aspx
for custom role provider:
http://msdn.microsoft.com/en-us/library/317sza4k(v=vs.100).aspx
more info:
http://msdn.microsoft.com/en-us/library/tksy7hd7(v=vs.100).aspx
and have simplemembershipinitializer
using system; using system.data.entity; using system.data.entity.infrastructure; using system.threading; using webmatrix.webdata; using testproject.web.models; using system.web.http.controllers; using system.web.http.filters; namespace testproject.web.filters { [attributeusage(attributetargets.class | attributetargets.method, allowmultiple = false, inherited = true)] public sealed class initializesimplemembershipattribute : actionfilterattribute { private static simplemembershipinitializer _initializer; private static object _initializerlock = new object(); private static bool _isinitialized; public override void onactionexecuting(httpactioncontext actioncontext) { lazyinitializer.ensureinitialized(ref _initializer, ref _isinitialized, ref _initializerlock); } private class simplemembershipinitializer { public simplemembershipinitializer() { database.setinitializer<userscontext>(null); try { using (var context = new userscontext()) { if (!context.database.exists()) { ((iobjectcontextadapter)context).objectcontext.createdatabase(); } } websecurity.initializedatabaseconnection("testprojectentities", "users", "usrid","usrloginname", autocreatetables: false); } catch (exception ex) { throw ex; } } } } }
and wrote web api login:
using system; using system.collections.generic; using system.linq; using system.net; using system.net.http; using system.web.http; using system.web.security; using dotnetopenauth.aspnet; using microsoft.web.webpages.oauth; using webmatrix.webdata; using testproject.web.models; using testproject.web.filters; using system.configuration; namespace testproject.web.controllers { [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"; } } }
and web.config is:
<?xml version="1.0" encoding="utf-8"?> <!-- more information on how configure asp.net application, please visit http://go.microsoft.com/fwlink/?linkid=169433 --> <configuration> <configsections> <!-- more information on entity framework configuration, visit http://go.microsoft.com/fwlink/?linkid=237468 --> <section name="entityframework" type="system.data.entity.internal.configfile.entityframeworksection, entityframework, version=5.0.0.0, culture=neutral, publickeytoken=b77a5c561934e089" requirepermission="false" /> </configsections> <connectionstrings> <!--<add name="defaultconnection" connectionstring="data source=(localdb)\v11.0;initial catalog=aspnet-testproject.web-20130430091159;integrated security=sspi;attachdbfilename=|datadirectory|\aspnet-testproject.web-20130430091159.mdf" providername="system.data.sqlclient" />--> <add name="testprojectentities" connectionstring="data source=.;initial catalog=testproject;integrated security=true" providername="system.data.sqlclient"/> </connectionstrings> <appsettings> <add key="webpages:version" value="2.0.0.0" /> <add key="webpages:enabled" value="false" /> <add key="preserveloginurl" value="true" /> <add key="clientvalidationenabled" value="true" /> <add key="unobtrusivejavascriptenabled" value="true" /> <add key="enablesimplemembership" value="false"/> </appsettings> <system.web> <compilation debug="true" targetframework="4.5" /> <httpruntime targetframework="4.5" /> <authentication mode="forms"> <forms protection="all" loginurl="/" timeout="2880" requiressl="false" slidingexpiration="true" cookieless="usecookies"> <credentials passwordformat="sha1" /> </forms> </authentication> <authorization> <!--<deny users="?" lockallattributesexcept="allowanonymous" />--> <allow users="*"/> </authorization> <machinekey validationkey="c50b3c89cb21f4f1422ff158a5b42d0e8db8cb5cda1742572a487d9401e3400267682b202b746511891c1baf47f8d25c07f6c39a104696db51f17c529ad3cabe" decryptionkey="8a9be8fd67af6979e7d20198cfea50dd3d3799c77af2b72f" validation="sha1" /> <membership defaultprovider="usersmembershipprovider" userisonlinetimewindow="15"> <providers> <clear /> <add name="usersmembershipprovider" type="testproject.web.utility.usersmembershipprovider" connectionstringname="testprojectentities" applicationname="testproject" enablepasswordretrieval="true" enablepasswordreset="true" requiresquestionandanswer="true" requiresuniqueemail="true" passwordformat="hashed" /> </providers> </membership> <rolemanager defaultprovider="usersroleprovider" enabled="true" cacherolesincookie="true" cookiename=".asproles" cookietimeout="30" cookiepath="/" cookierequiressl="false" cookieslidingexpiration="true" cookieprotection="all" > <providers> <clear /> <add name="usersroleprovider" type="testproject.web.utility.usersroleprovider" connectionstringname="testprojectentities" applicationname="testproject" writeexceptionstoeventlog="false" /> </providers> </rolemanager> <pages> <namespaces> <add namespace="system.web.helpers" /> <add namespace="system.web.mvc" /> <add namespace="system.web.mvc.ajax" /> <add namespace="system.web.mvc.html" /> <add namespace="system.web.optimization" /> <add namespace="system.web.routing" /> <add namespace="system.web.webpages" /> </namespaces> </pages> </system.web> <system.webserver> <validation validateintegratedmodeconfiguration="false" /> <handlers> <remove name="extensionlessurlhandler-isapi-4.0_32bit" /> <remove name="extensionlessurlhandler-isapi-4.0_64bit" /> <remove name="extensionlessurlhandler-integrated-4.0" /> <add name="extensionlessurlhandler-isapi-4.0_32bit" path="*." verb="get,head,post,debug,put,delete,patch,options" modules="isapimodule" scriptprocessor="%windir%\microsoft.net\framework\v4.0.30319\aspnet_isapi.dll" precondition="classicmode,runtimeversionv4.0,bitness32" responsebufferlimit="0" /> <add name="extensionlessurlhandler-isapi-4.0_64bit" path="*." verb="get,head,post,debug,put,delete,patch,options" modules="isapimodule" scriptprocessor="%windir%\microsoft.net\framework64\v4.0.30319\aspnet_isapi.dll" precondition="classicmode,runtimeversionv4.0,bitness64" responsebufferlimit="0" /> <add name="extensionlessurlhandler-integrated-4.0" path="*." verb="get,head,post,debug,put,delete,patch,options" type="system.web.handlers.transferrequesthandler" precondition="integratedmode,runtimeversionv4.0" /> </handlers> </system.webserver> <runtime> <assemblybinding xmlns="urn:schemas-microsoft-com:asm.v1"> <dependentassembly> <assemblyidentity name="system.web.helpers" publickeytoken="31bf3856ad364e35" /> <bindingredirect oldversion="1.0.0.0-2.0.0.0" newversion="2.0.0.0" /> </dependentassembly> <dependentassembly> <assemblyidentity name="system.web.mvc" publickeytoken="31bf3856ad364e35" /> <bindingredirect oldversion="1.0.0.0-4.0.0.0" newversion="4.0.0.0" /> </dependentassembly> <dependentassembly> <assemblyidentity name="system.web.webpages" publickeytoken="31bf3856ad364e35" /> <bindingredirect oldversion="1.0.0.0-2.0.0.0" newversion="2.0.0.0" /> </dependentassembly> </assemblybinding> </runtime> <entityframework> <defaultconnectionfactory type="system.data.entity.infrastructure.sqlceconnectionfactory, entityframework"> <parameters> <parameter value="system.data.sqlserverce.4.0" /> </parameters> </defaultconnectionfactory> <!--<defaultconnectionfactory type="system.data.entity.infrastructure.localdbconnectionfactory, entityframework"> <parameters> <parameter value="v11.0" /> </parameters> </defaultconnectionfactory>--> </entityframework> </configuration>
after run api link:
/api/apiaccount/login/?username=test1&password=123456&rememberme=true
its give me error:
<error> <message>an error has occurred.</message> <exceptionmessage> call method, "membership.provider" property must instance of "extendedmembershipprovider". </exceptionmessage> <exceptiontype>system.invalidoperationexception</exceptiontype> <stacktrace> @ webmatrix.webdata.websecurity.verifyprovider() @ webmatrix.webdata.websecurity.login(string username, string password, boolean persistcookie) @ testproject.web.controllers.apiaccountcontroller.login(string username, string password, boolean rememberme) in c:\visual studio 2012\projects\testproject\testproject.web\controllers\apiaccountcontroller.cs:line 30 @ lambda_method(closure , object , object[] ) @ system.web.http.controllers.reflectedhttpactiondescriptor.actionexecutor.<>c__displayclass13.<getexecutor>b__c(object instance, object[] methodparameters) @ system.web.http.controllers.reflectedhttpactiondescriptor.actionexecutor.execute(object instance, object[] arguments) @ system.web.http.controllers.reflectedhttpactiondescriptor.<>c__displayclass5.<executeasync>b__4() @ system.threading.tasks.taskhelpers.runsynchronously[tresult](func`1 func, cancellationtoken cancellationtoken) </stacktrace> </error>
i check , see customrolemanager initializer not run in web api , when use view , not web api, ok.
what should do?
i uploaded test project in http://filebin.net/k8cqbyltac , made vs 2012, c#, mvc4, .net 4.5
plaese check url after run seeing error:
/api/apiaccount/login/?username=test1&password=123456&rememberme=true
after inspecting source found culprit:
your membership class should inherit extendedmembershipprovider
instead of membershipprovider
.
the websecurity class works base-class instead of membershipprovider
, if class doesn't inherit class, null-reference , correctly tells doesn't have reference object of correct type.
Comments
Post a Comment