This is probably a very simple problem but I cant see the solution and its really beginning to bug me!
I have a simple ASP.Net MVC2 application which is intended as a learning aid which requires users to log in by providing username and password. These are authenticated against a DB using a membership provider was created and configured using the aspnet_regsql tool.
The web config looks like this (which I think is right... maybe not sure about the forms authentication bit however):
<authentication mode="Forms">
<forms loginUrl="~/Account/LogOn" timeout="2380"/>
</authentication>
<membership>
<providers>
<clear />
<add name="AspNetSqlMembershipProvider" type="System.Web.Security.SqlMembershipProvider" connectionStringName="ApplicationServices" enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="false" requiresUniqueEmail="false" maxInvalidPasswordAttempts="5" minRequiredPasswordLength="6" minRequiredNonalphanumericCharacters="0" passwordAttemptWindow="10" applicationName="/" />
</providers>
</membership>
<profile>
<providers>
<clear />
<add name="AspNetSqlProfileProvider" type="System.Web.Profile.SqlProfileProvider" connectionStringName="ApplicationServices" applicationName="/" />
</providers>
</profile>
<roleManager enabled="false">
<providers>
<clear />
<add name="AspNetSqlRoleProvider" type="System.Web.Security.SqlRoleProvider" connectionStringName="ApplicationServices" applicationName="/" />
<add name="AspNetWindowsTokenRoleProvider" type="System.Web.Security.WindowsTokenRoleProvider" applicationName="/" />
</providers>
</roleManager>
The code in the view which performs the log procedure looks like this:
public ActionResult LogOn()
{
return View();
}
[HttpPost]
public ActionResult LogOn(LogOnModel model, string returnUrl)
{
if (ModelState.IsValid){
if (MembershipService.ValidateUser(model.UserName, model.Password)){
FormsService.SignIn(model.UserName, model.RememberMe);
if (!String.IsNullOrEmpty(returnUrl)){
return Redirect(returnUrl);
}
else{
return RedirectToAction("Index", "Home");
}
}
else{
ModelState.AddModelError("", "The user name or password provided is incorrect.");
}
}
// If we got this far, something failed, redisplay form
return View(model);
}
And each method in the controller which requires security applied is tagged like so:
[Authorize]
public ActionResult New() {
return View();
}
[Authorize]
[HttpPost]
public ActionResult New(FormCollection collection) {
//do something...
}
I have also tagged the controller class with [Authorize] also.
However, when I log in to the site by creating a new item or editing an existing item I get logged out very quickly after logging in.
Do private methods in the controller also need to marked with [Authorize] and would this cause someone to get logged out?
Thanks for your help,
Morris
Related
I have a trivial console app and I can't connect my DBContext (Entity Framework 6.0.0) to the SQL Server 2022 database.
public class TestContext : DbContext
{
public TestContext(string connectionString) :base(connectionString)
{
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
}
}
Connecting with SqlConnection works just fine, but EF6 doesn't. There's no error.
static void Main(string[] args)
{
SqlConnectionStringBuilder cb = new SqlConnectionStringBuilder();
cb.DataSource = #"***";
cb.InitialCatalog = #"EF6Test";
cb.IntegratedSecurity = true;
SqlConnection conn = new SqlConnection();
conn.ConnectionString = cb.ConnectionString;
conn.Open(); //connection OK.
try
{
using (var ctx = new TestContext(cb.ConnectionString))
{
var s = ctx.Database.Connection.State;
;
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
When I add a breakpoint, the only error is here:
Edit: this is my App.config:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<section name="entityFramework"
type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
</configSections>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.8" />
</startup>
<entityFramework>
<defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework">
<parameters>
<parameter value="v11.0" />
</parameters>
</defaultConnectionFactory>
<providers>
<provider invariantName="System.Data.SqlClient"
type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
</providers>
</entityFramework>
</configuration>
I have an existing App written using Microsoft Visual C++ 2017, ASP.NET, MVC 5.2.7.0, Entity Framework Version=5, DB is SQL Server. When I add a new record to my DB, the key (ParkID) that results is a zero and when I try and save the change. I get an error.
Cannot insert the value NULL into column 'ParkID', table 'N_CWBFM-20170818.dbo.Park'; column does not allow nulls. INSERT fails.
The database N_CWBFM-20170818 was downloaded from the HOST where my app runs.
Confession, this is a hobby, so I may not use the correct terminology and translating other ways of adding data to a DB to the method I am using.
Model
using System;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace CWBFM.Models
{
public class Park
{
[Key]
public int ParkID { get; set; }
public bool ParkChangePending { get; set; } // change pending true/false
public int ParkChangeCount { get; set; } // Count the number of changes to this record
public int ParkPrevRec { get; set; } // points backwards to the previous version
public int ParkNextRec { get; set; } // ID of previous record
Omitted
DB Context
using CWBFM.Models;
using System.Data.Entity;
using System.Data.Entity.ModelConfiguration.Conventions;
namespace CWBFM.DAL
{
public class CWBFMContext : DbContext
{
public DbSet<Park> Parks { get; set; }
public DbSet<Photo> Photo { get; set; }
public DbSet<StateFilter> StateFilters { get; set; }
Omitted
Controller
using System;
using System.Data;
using System.Linq;
using System.Web.Mvc;
using CWBFM.Models;
using CWBFM.DAL;
namespace CWBFM.Controllers
{
public class ParkController : BaseController
{
private CWBFMContext db = new CWBFMContext();
Omitted
// POST: /Park/Create
[HttpPost]
[Authorize]
public ActionResult ParkCreate(Park park)
{
setYesNo(); //set the values for the dropdown box (Yes, No, Unknown)
if (ModelState.IsValid)
{
park.ParkChangePending = false;
park.ParkChangeCount = 0;
park.ParkDateCreated = DateTime.Now;
park.ParkDateChange = DateTime.Now;
park.ParkCreatedBy = #User.Identity.Name;
park.ParkChangedBy = #User.Identity.Name;
park.ParkStatus = "N";
db.Parks.Add(park);
int stop = park.ParkID;
db.SaveChanges();
park.ParkRecID = "Park" + park.ParkID.ToString();
db.SaveChanges();
return RedirectToAction("ParkDetails", new { id=park.ParkID });
}
return View(park);
}
Config
<?xml version="1.0" encoding="utf-8"?>
<!--
For more information on how to configure your ASP.NET application, please visit
http://go.microsoft.com/fwlink/?LinkId=152368
-->
<configuration>
<configSections>
<!-- For 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=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" /> -->
<section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
</configSections>
<appSettings>
<add key="webpages:Version" value="3.0.0.0" />
<add key="webpages:Enabled" value="false" />
<add key="ClientValidationEnabled" value="true" />
<add key="UnobtrusiveJavaScriptEnabled" value="true" />
</appSettings>
<system.web>
<compilation debug="true" targetFramework="4.6.1" />
<authentication mode="Forms">
<forms loginUrl="~/Account/LogOn" timeout="2880" />
</authentication>
<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.Routing" />
<add namespace="System.Web.WebPages" />
<add namespace="Telerik.Web.Mvc.UI" />
</namespaces>
</pages>
<httpRuntime targetFramework="4.6.1" maxRequestLength="20971520" />
<!-- This will handle requests up to 20MB -->
<profile inherits="CWBFM.Models.MyUserProfile" defaultProvider="DefaultProvider">
<providers>
<clear />
<add name="DefaultProvider" type="System.Web.Providers.DefaultProfileProvider, System.Web.Providers, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" connectionStringName="DefaultConnection" applicationName="/" />
</providers>
</profile>
<!--<profile defaultProvider="DefaultProfileProvider">
<providers>
<add name="DefaultProfileProvider" type="System.Web.Providers.DefaultProfileProvider, System.Web.Providers, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" connectionStringName="DefaultConnection" applicationName="/" />
</providers>
</profile>-->
<membership defaultProvider="DefaultMembershipProvider">
<providers>
<add name="DefaultMembershipProvider" type="System.Web.Providers.DefaultMembershipProvider, System.Web.Providers, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" connectionStringName="DefaultConnection" enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="false" requiresUniqueEmail="false" maxInvalidPasswordAttempts="5" minRequiredPasswordLength="6" minRequiredNonalphanumericCharacters="0" passwordAttemptWindow="10" applicationName="/" />
</providers>
</membership>
<roleManager enabled="true" defaultProvider="DefaultRoleProvider">
<providers>
<add connectionStringName="DefaultConnection" applicationName="/" name="DefaultRoleProvider" type="System.Web.Providers.DefaultRoleProvider, System.Web.Providers, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
</providers>
</roleManager>
<!--
If you are deploying to a cloud environment that has multiple web server instances,
you should change session state mode from "InProc" to "Custom". In addition,
change the connection string named "DefaultConnection" to connect to an instance
of SQL Server (including SQL Azure and SQL Compact) instead of to SQL Server Express.
-->
<sessionState mode="InProc" customProvider="DefaultSessionProvider">
<providers>
<add name="DefaultSessionProvider" type="System.Web.Providers.DefaultSessionStateProvider, System.Web.Providers, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" connectionStringName="DefaultConnection" />
</providers>
</sessionState>
<httpHandlers>
<add verb="GET,HEAD" path="asset.axd" validate="false" type="Telerik.Web.Mvc.WebAssetHttpHandler, Telerik.Web.Mvc" />
</httpHandlers>
<httpModules>
<add name="CompilableFileModule" type="SassAndCoffee.CompilableFileModule" />
</httpModules>
</system.web>
<system.webServer>
<security>
<requestFiltering>
<!-- This will handle requests up to 1024MB (1GB) -->
<requestLimits maxAllowedContentLength="1073741824" />
</requestFiltering>
</security>
<validation validateIntegratedModeConfiguration="false" />
<handlers>
<remove name="asset" />
<add name="asset" preCondition="integratedMode" verb="GET,HEAD" path="asset.axd" type="Telerik.Web.Mvc.WebAssetHttpHandler, Telerik.Web.Mvc" />
<remove name="ExtensionlessUrlHandler-Integrated-4.0" /><remove name="OPTIONSVerbHandler" /><remove name="TRACEVerbHandler" /><add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" /></handlers>
<modules>
<remove name="CompilableFileModule" />
<add name="CompilableFileModule" type="SassAndCoffee.CompilableFileModule" />
</modules>
</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-3.0.0.0" newVersion="3.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.WebPages" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="0.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="0.0.0.0-5.2.7.0" newVersion="5.2.7.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Net.Http.Formatting" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-5.2.7.0" newVersion="5.2.7.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
<entityFramework>
<defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework">
<parameters>
<parameter value="v11.0" />
</parameters>
</defaultConnectionFactory>
</entityFramework>
<connectionStrings>
It dies on the save (db.SaveChanges();). A breakpoint at int stop = park.ParkID; shows that the ParkID is zero.
ParkID = 0
I have looked at several proposed solutions, but just can’t find one that works. Any suggestions. Could I have missed an update in my config when I changed to EF 5?
This can occur if the database was set up without an Identity column set on the PK, but EF will automatically expect an identity column on keys named "Id" or with the "Id" suffix on the class name. (I.e. Park.ParkId) If the DB is not actually set up to use an Identity but EF is configured for an Identity column (DatabaseGeneratedOption.Identity) the resulting insert statements will not include the ParkId column, resulting in a #null failure in the database.
I generally recommend being explicit with configuration rather than relying on EF's conventions for behaviour:
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int ParkId { get; set; }
If you expect the new records to be given a PK value automatically by the database then update the database schema to mark these PKs as Identity columns. If your schema is code-first and generating Migrations then there should be a way to apply a migration to update the PKs to identity columns. Otherwise simply make the change within SSMS.
If instead you want to provide PKs from your code, (such as part of data imports from other data sources) then you need to configure EF to not treat the PK as an Identity.
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public int ParkId { get; set; }
I have a web application that already works well with SQL Server Compact. Now, I am adding a SQL Server model. If I just simple pass the SQL Server connection string to the DbContext instance, I get the following error:
System.ArgumentException: Additional information: Keyword not supported: 'application name'.
I can fix SQL Server (but break SQL Server Compact) it if I change the web.config from:
<entityFramework>
- <defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlCeConnectionFactory, EntityFramework">
<parameters>
- <parameter value="System.Data.SqlServerCe.4.0" />
</parameters>
</defaultConnectionFactory>
<providers>
<provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
<provider invariantName="System.Data.SqlServerCe.4.0" type="System.Data.Entity.SqlServerCompact.SqlCeProviderServices, EntityFramework.SqlServerCompact" />
</providers>
</entityFramework>
To:
<entityFramework>
+ <defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework">
<parameters>
+ <parameter value="mssqllocaldb" />
</parameters>
</defaultConnectionFactory>
<providers>
<provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
<provider invariantName="System.Data.SqlServerCe.4.0" type="System.Data.Entity.SqlServerCompact.SqlCeProviderServices, EntityFramework.SqlServerCompact" />
</providers>
</entityFramework>
How can I keep both working? I think I need to add some <context> tags in the web.config, but I have not got it right.
Solved! I left the web.config as it originally was with the default SQL Server Compact connection factory. The only difference is that I added the SQL Server provider, like this:
<entityFramework>
<defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlCeConnectionFactory, EntityFramework">
<parameters>
<parameter value="System.Data.SqlServerCe.4.0" />
</parameters>
</defaultConnectionFactory>
<providers>
<provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
<provider invariantName="System.Data.SqlServerCe.4.0" type="System.Data.Entity.SqlServerCompact.SqlCeProviderServices, EntityFramework.SqlServerCompact" />
+ <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
</providers>
</entityFramework>
Then, in my model context class, I call the DbContext(DbConnection existingConnection, bool contextOwnsConnection) constructor like this:
public partial class MyDbContext : DbContext
{
public MyDbContext()
: base(GetConnection(), true)
{
}
private static DbConnection GetConnection()
{
var factory = DbProviderFactories.GetFactory("System.Data.SqlClient");
var connection = factory.CreateConnection();
connection.ConnectionString = "Application Name=EntityFramework;Password=foo;Persist Security Info=True;User ID=bar;Initial Catalog=MyDb;Data Source=foo.database.windows.net";
return connection;
}
// ...
}
Now I can use multiple providers.
I have a small project with sqlite and entity framework 6.
I install sqlite by Package Manager Console: PM>Install-Package System.Data.SQLite
In my web.config:
<connectionStrings>
<remove name="demoSQLiteonnectionString" />
<add name="demoSQLiteonnectionString" connectionString="Data Source=|App_Data|DemoData.s3db" providerName="System.Data.SQLite.EF6" />
</connectionStrings>
<entityFramework>
<defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework">
<parameters>
<parameter value="v11.0" />
</parameters>
</defaultConnectionFactory>
<providers>
<provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
<provider invariantName="System.Data.SQLite.EF6" type="System.Data.SQLite.EF6.SQLiteProviderServices, System.Data.SQLite.EF6" />
</providers>
</entityFramework>
<system.data>
<DbProviderFactories>
<remove invariant="System.Data.SQLite" />
<add name="SQLite Data Provider" invariant="System.Data.SQLite" description=".Net Framework Data Provider for SQLite" type="System.Data.SQLite.SQLiteFactory, System.Data.SQLite" />
<remove invariant="System.Data.SQLite.EF6" />
<add name="SQLite Data Provider (Entity Framework 6)" invariant="System.Data.SQLite.EF6" description=".Net Framework Data Provider for SQLite (Entity Framework 6)" type="System.Data.SQLite.EF6.SQLiteProviderFactory, System.Data.SQLite.EF6" />
</DbProviderFactories>
</system.data>
In my context class:
public class DataContext : DbContext
{
public DataContext()
: base("demoSQLiteonnectionString")
{
Database.SetInitializer(new CreateDatabaseIfNotExists<DataContext>());
}
public DbSet<Client> Client { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
// Chinook Database does not pluralize table names
modelBuilder.Conventions
.Remove<PluralizingTableNameConvention>();
}
}
When get instance of context: var context = new DataContext(),
it shows this error:
Additional information: No Entity Framework provider found for the ADO.NET provider with invariant name 'System.Data.SQLite'. Make sure the provider is registered in the 'entityFramework' section of the application config file. See http://go.microsoft.com/fwlink/?LinkId=260882 for more information.
How to fix this problem?
You Should change the app config file to
<providers>
<provider invariantName="**System.Data.SQLite.EF6**" type="System.Data.SQLite.EF6.SQLiteProviderServices, System.Data.SQLite.EF6" />
</providers>
</providers>
to
<providers>
<provider invariantName="**System.Data.SQLite**" type="System.Data.SQLite.EF6.SQLiteProviderServices, System.Data.SQLite.EF6" />
</providers>
</providers>
and change the configuration file to :
public class DataContext : DbContext
{
public DataContext()
: base("demoSQLiteonnectionString")
{
}
public DbSet<Client> Client { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
// Chinook Database does not pluralize table names
modelBuilder.Conventions
.Remove<PluralizingTableNameConvention>();
Database.SetInitializer(new SqliteCreateDatabaseIfNotExists<DataContext>(modelBuilder));
}
}
I have an MVC 2 project where I have my own *.mdf file in the App_Data directory. The *.mdf file contains my normal tables but not a users table.
Is it possible to add a Users table to my *.mdf file and work with that instead of the simple register form? (if so: how could this be done?)
Because I don't know how to do these things above, I searched and only found steps to add build in Membership to my mdf file and I tried it:
I tried to add normal build in Membership to my *.mdf file with this:
aspnet_regsql.exe -C CONSTRINGHERE -d PATHTOMDFFILEHERE -A all
and I changed my Web.config file to this:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<connectionStrings>
<add name="CompanyDBEntities" connectionString="metadata=res://*/Models.CompanyDB.csdl|res://*/Models.CompanyDB.ssdl|res://*/Models.CompanyDB.msl;provider=System.Data.SqlClient;provider connection string="Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|\CompanyData.mdf;Integrated Security=True;User Instance=True;MultipleActiveResultSets=True"" providerName="System.Data.EntityClient" />
</connectionStrings>
<system.web>
<compilation debug="true" targetFramework="4.0">
<assemblies>
<add assembly="System.Web.Abstractions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
<add assembly="System.Web.Routing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
<add assembly="System.Web.Mvc, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
<add assembly="System.Data.Entity, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
</assemblies>
</compilation>
<authentication mode="Forms">
<forms loginUrl="~/Account/LogOn" timeout="2880" />
</authentication>
<membership defaultProvider="CompanyDBSqlProvider" userIsOnlineTimeWindow="15">
<providers>
<clear />
<add name="CompanyDBSqlProvider"
type="System.Web.Security.SqlMembershipProvider"
connectionStringName="CompanyDBEntities"
applicationName="/"
enablePasswordRetrieval="false"
enablePasswordReset="true"
requiresQuestionAndAnswer="true"
requiresUniqueEmail="true"
passwordFormat="Hashed"
maxInvalidPasswordAttempts="5"
minRequiredPasswordLength="6"
minRequiredNonalphanumericCharacters="0"
passwordAttemptWindow="10"
passwordStrengthRegularExpression=""
/>
</providers>
</membership>
<profile>
<providers>
<clear />
<add name="AspNetSqlProfileProvider" type="System.Web.Profile.SqlProfileProvider"
connectionStringName="CompanyDBEntities" applicationName="/" />
</providers>
</profile>
<roleManager enabled="false">
<providers>
<clear />
<add name="AspNetSqlRoleProvider" type="System.Web.Security.SqlRoleProvider"
connectionStringName="CompanyDBEntities" applicationName="/" />
<add name="AspNetWindowsTokenRoleProvider" type="System.Web.Security.WindowsTokenRoleProvider" applicationName="/" />
</providers>
</roleManager>
<pages>
<namespaces>
<add namespace="System.Web.Mvc" />
<add namespace="System.Web.Mvc.Ajax" />
<add namespace="System.Web.Mvc.Html" />
<add namespace="System.Web.Routing" />
</namespaces>
</pages>
</system.web>
<system.webServer>
<validation validateIntegratedModeConfiguration="false" />
<modules runAllManagedModulesForAllRequests="true" />
</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" newVersion="2.0.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
I did not modify anything else. I did not change the AccountController or something.
I builded and ran my MVC 2 application and went to LogOn and registered an account but got stuck there:
Account creation was unsuccessful. Please correct the errors and try again.
* The password retrieval answer provided is invalid. Please check the value and try again.
Summary:
I thought that it would be better to have a Users table in my *.mdf file but I don't know how to do the register/login/logout/membership/etc... things with an own users table.
So I tried adding Membership to my own *.mdf file so that everything would be in that one *.mdf file but that gives me also problems.
Maybe this info is important:
In the future I want it to be possible to let users register and login via Hotmail, Gmail, OpenId and I should need more fields like website, nickname, avatar, etc... other than the basic register form now. Also would need to show a profilepage from the user on the website.
Could anybody help me out?
PS: I don't have experience with Membership in ASP.NET :s
I encountered the same problem. You can customize the user register table by doing these:
First of all, configure the sqlmemberprovider service in web.config:
' add connectionStringName="PhotoSocialMemberService" applicationName="PhotoSocial"
minRequiredPasswordLength="5" minRequiredNonalphanumericCharacters="0"
requiresQuestionAndAnswer="true"
name="PhotoSocailMember" type="System.Web.Security.SqlMembershipProvider" /'
Edit the AccountModel.cs., look for
the method "CreateUser", the
abstract class should be like this:
public abstract class MembershipProvider : ProviderBase
{...
public abstract MembershipUser CreateUser(string username, string password, string email, string passwordQuestion, string passwordAnswer, bool isApproved, object providerUserKey, out MembershipCreateStatus status);
}
in the AccountModel.cs you can find implementation of the abstract method in
public interface IMembershipService
{
int MinPasswordLength { get; }
bool ValidateUser(string userName, string password);
MembershipCreateStatus CreateUser(string userName, string password, string email, string passwordquestion, string passwordanswer);
bool ChangePassword(string userName, string oldPassword, string newPassword);
}
and in
public MembershipCreateStatus CreateUser(string userName, string password, string email, string passwordquestion, string passwordanswer)
{
if (String.IsNullOrEmpty(userName)) throw new ArgumentException("Value cannot be null or empty.", "userName");
if (String.IsNullOrEmpty(password)) throw new ArgumentException("Value cannot be null or empty.", "password");
if (String.IsNullOrEmpty(email)) throw new ArgumentException("Value cannot be null or empty.", "email");
MembershipCreateStatus status;
_provider.CreateUser(userName, password, email, passwordquestion, passwordanswer, true, null, out status);
return status;
}
add as many as parameters as you like.
Edit the register model in RegisterModel in AccountModel.cs, add string you want to put into the registerModel:
public class RegisterModel
{[Required]
[DisplayName("User name")]
public string UserName { get; set; }
[Required]
[DataType(DataType.EmailAddress)]
[DisplayName("Email address")]
public string Email { get; set; }
[Required]
[ValidatePasswordLength]
[DataType(DataType.Password)]
[DisplayName("Password")]
public string Password { get; set; }
[Required]
[DataType(DataType.Password)]
[DisplayName("Confirm password")]
public string ConfirmPassword { get; set; }
[Required]
[DisplayName("Password security question")]
public string PasswordQuestion { get; set; }
[Required]
[DataType(DataType.Password)]
[DisplayName("Password security answer")]
public string PasswordAnswer { get; set; }
}
Last, rewrite the Register.aspx page, add the html tag:
Html.LabelFor(m => m.PasswordQuestion)
Most important, you need to change the _provider from readonly to private
public class AccountMembershipService : IMembershipService
{
private MembershipProvider _provider;
}
You can add your validation methods through this progress.