Microsoft Unit Testing with ASP.NET membership provider - asp.net-mvc

Is anyone else frustrated with the built in ASP.NET unit testing framework? The problem I am having is connecting and testing against the Membership provider for ASP.NET in a MVC3 application. It looks like the database connection has not been established or that there is a different set of rules in place then when I run the application normally. Here are the two scenarios.
1) Attempting to find an existing user by name:
Unit Test -
[TestMethod]
public void RegisterTest()
{
AccountController target = new AccountController();
RegisterModel model = new RegisterModel() { UserName = "existinguser", Email = "email#test.com", Password = "Password", ConfirmPassword = "Password" };
actual = target.Register(model);
}
Code chunk from the AccountController -
MembershipCreateStatus createStatus;
MembershipUserCollection members = Membership.FindUsersByName(model.UserName);
MembershipUser user = null;
if (members.Count > 0)
createStatus = MembershipCreateStatus.DuplicateUserName;
Result -
When I step into this code the members array is empty even though I know this user to be in the system. Is there some trick to establishing a connection to the membership store in the unit testing application? I have attempted using the datasource attribute with no success.
2) Attempting to create a new membership account:
The unit test is the same as above however I am passing a new user that is not already in the system. When I step into the controller and get to the following line it gives me a membershipCreateStatus of 'InvalidQuestion'. This seems odd since when running this live I don't have that problem and can create accounts with the line as it is.
user = Membership.CreateUser(model.UserName, model.Password, model.Email, string.Empty, string.Empty, true, null, out createStatus);
Thanks in advance for your help. I am really trying to do this test first method but it's making it harder using the built in testing framework. Certainly there is a way to connect to the DB for all the unit tests (not providing a connection for each test) and simulate the same actions I would through a browser.

When you run your unit tests it will effectively run as a new application and will therefore use its own config file - in other words not web.config that your MVC app uses. So what I would guess you are missing without more information is an entry in the app.config file in your test project, for the connection string to the database that holds your membership information (you may also be missing app.config).
If you are trying to take a TDD approach you should be writing unit tests and if you need to connect to a database for the unit tests to run, they are probably integration tests rather than unit tests. Because the Membership classes use static methods this makes things difficult. What I would recommend is wrapping the membership functionality up in it's own service with a corresponding interface (IMembershipService for example) which can then be injected by your IoC container. For the purposes of your unit tests, you can then simply mock the IMembershipService interface that you created with no need to connect to your database.

I had the same problem. And yes it looks like my unit tests are more like integration tests but I just needed to test the controllers and speed wasn't a concern at this point in the project. I basically added all the sql memberbership config and connection string from the MVC 3 project's web.config to test project's app.config and the membership provider worked when the unit tests ran. Below is my test project's app.config in it's entiriety.
<?xml version="1.0" encoding="utf-8"?>
<!--
Note: Add entries to the App.config file for configuration settings
that apply only to the Test project.
-->
<configuration>
<appSettings></appSettings>
<connectionStrings>
<add name="ApplicationServices" connectionString="mySqlServer;initial catalog=mySqlMembershipDB;persist security info=True;user id=mySqlUser;password=mySqlPassword;" providerName="System.Data.SqlClient" />
</connectionStrings>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.0.5.0" newVersion="4.0.5.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
<system.web>
<membership defaultProvider="AspNetSqlMembershipProvider">
<providers>
<clear />
<add name="AspNetSqlMembershipProvider" type="System.Web.Security.SqlMembershipProvider" connectionStringName="ApplicationServices" enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="false" requiresUniqueEmail="true" maxInvalidPasswordAttempts="5" minRequiredPasswordLength="6" minRequiredNonalphanumericCharacters="0" passwordAttemptWindow="10" applicationName="/" />
</providers>
</membership>
<profile defaultProvider="AspNetSqlProfileProvider">
<providers>
<clear />
<add name="AspNetSqlProfileProvider" type="System.Web.Profile.SqlProfileProvider" connectionStringName="ApplicationServices" applicationName="/" />
</providers>
</profile>
<roleManager enabled="false" defaultProvider="AspNetSqlRoleProvider">
<providers>
<clear />
<add name="AspNetSqlRoleProvider" type="System.Web.Security.SqlRoleProvider" connectionStringName="ApplicationServices" applicationName="/" />
</providers>
</roleManager>
</system.web>
</configuration>

Related

Users don't load Sitefinity

I'm having an issue with SitefinityMembershipProvider in Sitefinity 9.1
When I login to the backend, navigate to Administration -> Users:Page keeps loading.
When I checked the error log it tells me that "Provider must implement the class 'System.Web.Security.MembershipProvider".
But my class inherits sitefinity membership provider i.e. MembershipDataProvider
which is of type Telerik.Sitefinity.Security.Data.
My web config have the following membership defined.
<membership defaultProvider="Default">
<providers>
<clear />
<add name="Default" type="Telerik.Sitefinity.Security.Data.SitefinityMembershipProvider, Telerik.Sitefinity" />
<add name="CredentialServiceProvider" type="SitefinityWebApp.Providers.CredentialServiceProvider" />
</providers>
You need to register the provider in the Security settings as explained here:
http://docs.sitefinity.com/custom-membership-provider-add-the-new-provider-to-the-sitefinity-providers-collection
Additionally, I had to remove the custom provider from the web.config
<providers>
<clear />
<add name="Default" type="Telerik.Sitefinity.Security.Data.SitefinityMembershipProvider, Telerik.Sitefinity" />
</providers>

Create user database via code first ASP.NET MVC

I'm trying to use a MySQL database with asp.net MVC via a code first approach and I don't know how to create the tables, I thought it would create by itself.
I get the message : "Table 'XXX.aspnetusers' doesn't exist"
Do I need to run migrations or something like that?
Thanks
I got a little further by using update-database. You must have change your connection string and your provider to correspond to your MySql
Example :
<add name="DefaultConnection" connectionString="server=127.0.0.1;User Id=root;password=;database=myDB" providerName="MySql.Data.MySqlClient" />
Provider :
<entityFramework>
<defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework" />
<providers>
<provider invariantName="MySql.Data.MySqlClient" type="MySql.Data.MySqlClient.MySqlProviderServices, MySql.Data.Entity.EF6, Version=6.9.9.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d"></provider>
</providers>
</entityFramework>
You should also put this on your dbContext :
[DbConfigurationType(typeof(MySql.Data.Entity.MySqlEFConfiguration))]
Thanks

Problems continuing a MVC project with Entity Famework

So I have to work on this project (ASP.NET MVC 4 with Umbraco) that uses Entity Framework and I think UmbracoMembeShipProvider.
Now I have to add Roles to the project. In the DB there's a Users table and some few others. There is no Identity/Roles or the sort in the DB. I tried to create a Roles table and a junction table between Users and Roles but then I couldn't update the models. I made an .edmx schema file and it didn't pick up the junction table, just the Roles table with all the columns pilled up from the junction table.
I tried to approach it by making a Roles entity in the .edmx file and then update the DB via migrations, that also didn't work because the project is stuctued in a way that is has a 'Core' project where all the models are and then a 'Web' project where some other models are. And it gave all heaps of errors.
In the Web project there's a 'Migrations' directory with 2 classes one of which has 2 empty methods (up/down) and one that creates some indexes and then a bunch of commented code.
I'm also quite a newbie in ORMs in general so I don't know how to approach this problem, continuing where the other devs, before me, left off.
In the meantime I'll pick up some tutorials about EF but any help or guidance will be really appreciated.
You need to include the necessary settings in your web.config file which references a connection string pointing to a database where the user/role tables exist. It should look something like this.
<membership defaultProvider="UmbracoMembershipProvider" userIsOnlineTimeWindow="15">
<providers>
<clear />
<add name="UmbracoMembershipProvider"
type="umbraco.providers.members.UmbracoMembershipProvider"
enablePasswordRetrieval="false"
enablePasswordReset="false"
requiresQuestionAndAnswer="false"
defaultMemberTypeAlias="Another Type"
passwordFormat="Hashed" />
<add name="UsersMembershipProvider"
type="umbraco.providers.UsersMembershipProvider"
enablePasswordRetrieval="false"
enablePasswordReset="false"
requiresQuestionAndAnswer="false"
passwordFormat="Hashed" />
</providers>
</membership>
<roleManager enabled="true" defaultProvider="UmbracoRoleProvider">
<providers>
<clear />
<add name="UmbracoRoleProvider" type="umbraco.providers.members.UmbracoRoleProvider" />
</providers>
</roleManager>
<roleManager enabled="true" defaultProvider="UmbracoRoleProvider">
<providers>
<clear />
<add name="UmbracoRoleProvider" type="umbraco.providers.members.UmbracoRoleProvider" />
</providers>
</roleManager>
<appSettings>
<add key="umbracoDbDSN" value="server=localhost;database=MSSM;user id=db_user;password=password" />

Error Unable connect to SQL Server when add <roleManager enabled="true">

When I add
<roleManager enabled="true"></roleManager>
to my web.config, I get an error
Unable to connect to SQL Server database
occurs on this line of code:
System.Web.Security.Roles.AddUserToRole(m.UserName, "admin");
I added this to the web.config and it solved my problem:
<system.web>
<roleManager enabled="true" defaultProvider="CustomizedRoleProvider">
<providers>
<add name="CustomizedRoleProvider" type="System.Web.Security.SqlRoleProvider" connectionStringName="DefaultConnection" />
</providers>
</roleManager>
</system.web>
I had the exact same error when I had enabled believing I was enabling ASP.NET Identity 2. They are not the same! The enabled an old version of identity management which uses a different table structure to ASP.NET Identity 2 (which doesn't need "enabling" by the way - it's just there).
check the connection String.
If you are intentionally using the old role-manager and still getting the error you might be looking at the default localdb instead of your database, in which case you can modify to point at any connection string you want:
<roleManager
enabled="true"
cacheRolesInCookie="true"
defaultProvider="OurSqlRoleProvider"
>
<providers>
<add
connectionStringName="DefaultConnection"
applicationName="/"
name="OurSqlRoleProvider"
type="System.Web.Security.SqlRoleProvider" />
</providers>
</roleManager>
If you are are after using ASP.NET Identity 2, here's an article on it:
http://johnatten.com/2014/04/20/asp-net-mvc-and-identity-2-0-understanding-the-basics/

Deploy WebSharper 2.4 sitelet on IIS7.5

I created a websharper sitelet project from Visual Studio 2012, which I called SiteletTest.
I compiled this project.
Then I copied SiteletTest/Web to inetpub/wwwroot.
Then I go to localhost/SiteletTest, localhost/SiteletTest/Home and localhost/SiteletTest/home but in each case I get http 404.
If I go to localhost/Main.html then I get a page, so going to this directory seems to work, but websharper doesn't appear to be working.
My web.config is below, and I have no idea what else to do. I already set the application pool to use .net 4:
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.5" />
<authentication mode="Forms" />
<pages>
<controls>
<add tagPrefix="WebSharper" namespace="IntelliFactory.WebSharper.Web" assembly="IntelliFactory.WebSharper.Web" />
<add tagPrefix="ws" namespace="Website" assembly="Website" />
</controls>
</pages>
<httpModules>
<add name="WebSharper.Remoting" type="IntelliFactory.WebSharper.Web.RpcModule, IntelliFactory.WebSharper.Web" />
<add name="WebSharper.Sitelets" type="IntelliFactory.WebSharper.Sitelets.HttpModule, IntelliFactory.WebSharper.Sitelets" />
</httpModules>
</system.web>
<system.webServer>
<validation validateIntegratedModeConfiguration="false" />
<modules>
<add name="WebSharper.Remoting" type="IntelliFactory.WebSharper.Web.RpcModule, IntelliFactory.WebSharper.Web" />
<add name="WebSharper.Sitelets" type="IntelliFactory.WebSharper.Sitelets.HttpModule, IntelliFactory.WebSharper.Sitelets" />
</modules>
</system.webServer>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="1.0.0.0-2.0.0.0" newVersion="3.0.0.0" />
</dependentAssembly>
</assemblyBinding>
<assemblyBinding appliesTo="v4.0.30319" xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="FSharp.Core" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="2.0.0.0" newVersion="4.3.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
I am not going to be paying for a license until I get an idea if this may work for my needs, so, how do I get this to work?
I don't want to copy the sitelet code, but here are some fragments:
type Action =
| Home
| Contact
| Protected
| Login of option<Action>
| Logout
| Echo of string
and another fragment:
module Pages =
/// The home page.
let HomePage : Content<Action> =
Skin.WithTemplate "Home" <| fun ctx ->
[
H1 [Text "Welcome to our site!"]
"Let us know how we can contact you" => ctx.Link Action.Contact
]
I'm pretty sure you are missing 1 of three things:
1- Your sitelet/router isn't defined... something like this:
type Site() =
interface IWebsite<Action> with
member x.Sitelet =
Sitelet.Infer
<| function
| Home -> Pages.HomePage
...
member x.Actions = []
This maps each of the action cases to the correct page. There are many ways to define it but the above Sitelet.Infer will simply map the route by name.
2- You did not specify a Website assembly attribute... something like this:
[<assembly : Website(typeof<Site>)>]
do ()
I think this tells ASP.NET to load the above Sitelet as your site.
3- A third option is to automatically load a client-side JavaScript control from a Default.aspx page in the C# Web Project. If you use the Web Application (ASP.NET) template, you will see an example of that... but with that I do not think you can control the URL Path in a REST-full manner.

Resources