ASP.NET 4 Membeship schema changed - asp.net-mvc

I've installed yesterday Visual Studio 2012 (RTM, via mytt DreamSpark account) and created a demo MVC site (using .NET 4.0 since I wish it to be supported on Azure).
I've started to investigate the project and in addition to built-in option to use external services (Facebook, Twitter, Windows Live and Google) I've found out that the entire membership schema has been changed:
The new structure contains 4 tables (the UserProfile is a first-code approch Entity Framework table).
Note that although the tables prefix is "webpages_" its a proper MVC 4 site.
I've opened the AccountModels.cs file and saw that it has been changed too:
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Data.Entity;
using System.Globalization;
using System.Web.Mvc;
using System.Web.Security;
namespace MyGuestbook.Models
{
public class UsersContext : DbContext
{
public UsersContext()
: base("DefaultConnection")
{
}
public DbSet<UserProfile> UserProfiles { get; set; }
}
[Table("UserProfile")]
public class UserProfile
{
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int UserId { get; set; }
public string UserName { get; set; }
}
public class RegisterExternalLoginModel
{
[Required]
[Display(Name = "User name")]
public string UserName { get; set; }
public string ExternalLoginData { get; set; }
}
public class LocalPasswordModel
{
[Required]
[DataType(DataType.Password)]
[Display(Name = "Current password")]
public string OldPassword { get; set; }
[Required]
[StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)]
[DataType(DataType.Password)]
[Display(Name = "New password")]
public string NewPassword { get; set; }
[DataType(DataType.Password)]
[Display(Name = "Confirm new password")]
[Compare("NewPassword", ErrorMessage = "The new password and confirmation password do not match.")]
public string ConfirmPassword { get; set; }
}
public class LoginModel
{
[Required]
[Display(Name = "User name")]
public string UserName { get; set; }
[Required]
[DataType(DataType.Password)]
[Display(Name = "Password")]
public string Password { get; set; }
[Display(Name = "Remember me?")]
public bool RememberMe { get; set; }
}
public class RegisterModel
{
[Required]
[Display(Name = "User name")]
public string UserName { get; set; }
[Required]
[StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)]
[DataType(DataType.Password)]
[Display(Name = "Password")]
public string Password { get; set; }
[DataType(DataType.Password)]
[Display(Name = "Confirm password")]
[Compare("Password", ErrorMessage = "The password and confirmation password do not match.")]
public string ConfirmPassword { get; set; }
}
public class ExternalLogin
{
public string Provider { get; set; }
public string ProviderDisplayName { get; set; }
public string ProviderUserId { get; set; }
}
}
So I would like to ask:
- Does this the new users structure (that is generated from asp_regsql.exe) or this is a template-specific structure?
- Does somebody have any documentation about the new structure and how to integrate with it?
- Does anybody know how one can migrate an "older" project (e.g. MVC 3 project) with the old structure to the new one?
Thanks! :)

I've found some article that answer my question.
Edit:
Why the sudden changes:
The changes has been made because Microsoft has changed the default ASP.NET MVC 4 template.
The standard "Internet Application" template which gives default accounts management has been changed and now using the WebMatrix 2 helpers.
The AccountController has been totally rewritten in order to use SimpleMembership class which supports the third-party integration and gives us the ability to use Entity Framework code-first approach.
Usage of old membership providers
As long as I've read, because the SimpleMembership class using ExtendedMembershipProvider you cannot use the default universal providers and must use the built-in provider OR creating an ExtendedMembershipProvider custom provider.
More information can be found here:
Implementing membership providers using the new ASP.NET WebForms and ASP.NET MVC 4 template
Cheers!

Related

Exclude property of model in insert Entity Framework

I get an error when inserting data into my database. My database columns are:
username, password
and I added confirmpassword to the model to extend it.
How do I get rid of the confirmpassword to insert the username and password while using the model with confirmpassword property?
My code:
BootstrapTrainingEntities db = new BootstrapTrainingEntities();
var u = new User();
u.username = user.username;
u.password = user.password;
// how to I remove or ignore the confirmPassword property when saving?
db.Users.Add(u);
db.SaveChanges();
Model
[MetadataType(typeof(metadataUser))]
public partial class User
{
public string confirmPassword { get; set; }
}
public class metadataUser
{
[Required(ErrorMessage = "Username is required", AllowEmptyStrings = false)]
[Display(Name ="Username")]
public string username { get; set; }
[Required(ErrorMessage ="Password is required", AllowEmptyStrings = false)]
[Display(Name = "Password")]
[DataType(DataType.Password)]
public string password { get; set; }
[Required(ErrorMessage ="Confirmation Password is required", AllowEmptyStrings = false)]
[Display(Name ="Confiramation Password")]
[DataType(DataType.Password)]
[Compare("password",ErrorMessage = "Password does not match")]
public string confirmPassword { get; set; }
}
This SO has three different solutions that may help you:
How not persist property EF4 code first?
Summary:
First try the DataAnnotations approach:
Make sure you include the required library. Then apply the [Not Mapped] annotation to your field in the model.
using System.ComponentModel.DataAnnotations;
[NotMapped]
public string confirmPassword { get; set; }
If this doesn't do it, try to modify your OnModelBuilding method in your dbContext. There are two options in this block. The first is to use the Ignore method.
public class MyContext : DbContext
{
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<MetaDataUser>().Ignore(p => p.confirmPassword);
}
}
The second is to manually remap the model building and exclude your field.
Additional SO answers that may be useful:
Entity Framework Code First - How to ignore a column when saving
Exclude a field/property from the database with Entity Framework 4 & Code-First
MS Doc on how to manually map properties to db fields:
https://learn.microsoft.com/en-us/ef/core/modeling/relational/columns
Clean example of answer provided:
http://www.dotnetodyssey.com/2015/03/31/ignore-class-property-to-table-column-in-entity-framework-code-first/
I think what you need to do is add a viewmodel for the page.First of all you will have model that is generated from entity framework which might look as below.
public class User
{
public int id{get;set;}
public string username {get;set;}
public string password {get;set;}
}
So now create a viewModel for your View .This might look as below.
public class UserViewModel
{
public int id{get;set;}
[Required(ErrorMessage = "Username is required", AllowEmptyStrings = false)]
[Display(Name ="Username")]
public string username { get; set; }
[Required(ErrorMessage ="Password is required", AllowEmptyStrings = false)]
[Display(Name = "Password")]
[DataType(DataType.Password)]
public string password { get; set; }
[Required(ErrorMessage ="Confirmation Password is required", AllowEmptyStrings = false)]
[Display(Name ="Confiramation Password")]
[DataType(DataType.Password)]
[Compare("password",ErrorMessage = "Password does not match")]
public string confirmPassword { get; set; }
}
and now in your controller action method. you can do as below.
[HttpPost]
public ActionResult AddUser(UserViewModel model)
{
User user=new User();
user.username=model.username;
user.password=model.password;
db.User.Add(user);
}
Hope it helps !

public HttpPostedFileBase ProfileImage { get; set; }

Im develope the MVC user Profile Image Uplaoder,i cant update database display the following error,please give me a solution? what are the missing ?
Error 2 Inconsistent accessibility: property type 'eData.DataClases.Masters.HttpPostedFileBase' is less accessible than property 'Data.KdbContext.ProfileImage' C:\Users\Mad\Videos\Projects2015\eData\DataClases\Masters\MasterContext.cs 117 32 eData
Model
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using eData.DataClases.Masters;
namespace eData
{
public class RegisterModel
{
[Required]
[Display(Name = "User name")]
public string UserName { get; set; }
[Required]
[StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)]
[DataType(DataType.Password)]
[Display(Name = "Password")]
public string Password { get; set; }
[DataType(DataType.Password)]
[Display(Name = "Confirm password")]
[Compare("Password", ErrorMessage = "The password and confirmation password do not match.")]
public string ConfirmPassword { get; set; }
public HttpPostedFileBase ProfileImage { get; set; }
}
}
Somewhere you have a custom HttpPostedFileBase class defined. Presumably like this:
namespace eData.DataClases.Masters
{
private class HttpPostedFileBase
{
// implementation
}
}
(or perhaps internal instead of private)
Since your HttpPostedFileBase class has a more strict visibility (private or internal), you can't use it as the type for a public property:
public HttpPostedFileBase ProfileImage { get; set; }
This is because any consuming code which encounters that property wouldn't be able to know the type for that property.
Generally the fix is to either make the class' visibility match the property's, or make the property's visibility match the class'. (Make the class public or make the property private or internal accordingly.) Though, to be honest, the fact that you even have a custom implementation of HttpPostedFileBase is a bit strange in the first place...

Entity framework code first data annotation not working

Hi I am using entity framework code first approach for my project.
i have a class called Login as shown below
public class Login
{
[Required(ErrorMessage = "UserName Required")]
[DisplayName("Username")]
[Key]
public string Username { get; set; }
[DataType(DataType.Password)]
[Required(ErrorMessage = "Password Required")]
[DisplayName("Password")]
public string Password { get; set; }
[Required(ErrorMessage = "Email Id Required")]
[DisplayName("Email ID")]
[RegularExpression(#"^\w+([-+.']\w+)*#\w+([-.]\w+)*\.\w+([-.]\w+)*$",
ErrorMessage = "Email Format is wrong")]
public string Email { get; set; }
}
My database context is as below
public class ContextDB:DbContext
{
public DbSet<Login> LoginModel { get; set; }
}
The table created in the database is Logins.
In my view the validation messages are not working.
Can anyone please help?
This might sound stupid bud are u sure that you are passing right class to your Login ActionResult, not some LoginViewModel or similar stuff? I know that by default some preloaded models exist, so make sure that this isnt case.

EF6 Scaffolding /w FK to ApplicationUser fails to generate properly

This is a bit of a long winded question. I've been going through a lot trying to learn the ins and outs of EF6 and MVC5 at the same time, so I apologize if anything I'm saying is not making sense or is plain old wrong. (please let me know if it is!)
The problem is arising when I'm trying to scaffold CRUD pages for any models that have foreign keys to the pre-made AspNetUsers table. (This and a few other tables are already part of the DB if you choose a new MVC5 project with authentication.)
I've been able to successfully scaffold fully working CRUD pages for all my models that don't include links to the Users table. I'm wondering if it's something I've misunderstood, or if something I've done is messing this up.
I've been reading a lot of answers to questions here on SA for problems that are similar to mine, but to no avail. It seems to me like such a simple thing should be easier, but I've been struggling with this for days now.
To try to isolate the problem, I've started a new MVC project with authentication and done nothing other than add my models file, migrate the DB to add the tables and try to scaffold the pages. The scaffolding itself completes successfully, but adds this line to the IdentityModels.cs file:
public System.Data.Entity.DbSet<TestWhatever.Models.ApplicationUser> IdentityUsers { get; set; }
which is not correct (learned that from another SA thread). There should only be user generated dbsets in this file.
Upon running the app, I get the following error:
Multiple object sets per type are not supported. The object sets 'IdentityUsers' and 'Users' can both contain instances of type 'TestWhatever.Models.ApplicationUser'.
Edit: It was suggested below that I simply remove the generated IdentityUsers line - however doing that causes compiler errors in the generated CRUD pages. Something is not going right here, I'm starting to think that EntityFramework doesn't know how to use its own UserManager to display and update Users. ::
Is what I'm doing along the right path? Am I not supposed to be using the inbuilt tables for user auth? If not, why are they there? Any insight is appreciated, I've been finding this all very confusing as any documentation or answered questions I find are never covering quite the same topic. Thanks.
The tables that are giving me problems look like this:
public class ExamInProgress
{
[Key]
public int ProgressId { get; set; }
[Required]
[Display(Name = "User")]
public string UserId { get; set; }
[ForeignKey("UserId")]
public ApplicationUser User { get; set; }
[Required]
[Display(Name = "Exam")]
public int ExamId { get; set; }
public virtual Exam Exam { get; set; }
}
public class CompletedExam
{
[Key]
public int CompletedExamId { get; set; }
[Required]
[Display(Name = "Date Completed")]
public DateTime DateCompleted { get; set; }
[Required]
[Display(Name = "Final Score")]
public decimal FinalScore { get; set; }
[Required]
[Display(Name = "Exam Name")]
public string ExamName { get; set; }
[Required]
[Display(Name = "User")]
public string UserId { get; set; }
[ForeignKey("UserId")]
public ApplicationUser User { get; set; }
public virtual Exam Exam { get; set; }
}
Another example of the tables I'm using: (there are more but mainly just ints and strings)
public class Exam
{
[Key]
public int ExamId { get; set; }
[Required]
[StringLength(100, ErrorMessage = "Exam name cannot be longer than 100 characters.")]
[Display(Name = "Exam Name")]
public string ExamName { get; set; }
[Display(Name = "Exam Description")]
public string ExamDescription { get; set; }
public virtual ICollection<Module> Modules { get; set; }
}
public class Question
{
[Key]
public int QuestionId { get; set; }
[Required]
[Display(Name = "Question Text")]
public string QuestionText { get; set; }
[Display(Name = "Question Order Index")]
[Range(0, int.MaxValue, ErrorMessage = "Index can not be negative")]
public int? QuestionOrderIndex { get; set; }
[Required]
[Display(Name = "Question Type")]
public int QuestionTypeId { get; set; }
[Required]
[Display(Name = "Module")]
public int ModuleId { get; set; }
public virtual QuestionType QuestionType { get; set; }
public virtual Module Module { get; set; }
public virtual ICollection<Answer> Answers { get; set; }
}
public class QuestionType
{
[Key]
public int QuestionTypeId { get; set; }
[Required]
[StringLength(60, ErrorMessage = "QuestionType Name cannot be longer than 60 characters.")]
[Display(Name = "QuestionType Name")]
public string QuestionTypeName { get; set; }
[Display(Name = "QuestionType Description")]
public string QuestionTypeDescription { get; set; }
public virtual ICollection<Question> Questions { get; set; }
}
The error you're getting is due to having added the IdentityUsers property to your context. Your context is inheriting from IdentityDbContext<ApplicationUser>, and that class already has the following property:
public IDbSet<TUser> Users { get; set; }
Where TUser is the type passed in the generic, ApplicationUser. Adding your own DbSet for ApplicationUser creates two methods of access, and you get that error. Remove your property and you should be good.

ASP.NET MVC - updating an existing model

I am creating a web application that contains a model for the user. After creating the model without errors, I'm trying to update the password for the user (Change password form). Every time I try to update the model, the db.savechanges() throw an exception (Title and the category are required although this user has entries for both fields). When I try to debug this controller method, no exceptions are thrown and The user contains data for both the category and the faculty title!!
here is my user model:
[Key]
public int Id { get; set; }
[Required]
[ScaffoldColumn(false)]
[Display(Name = "Email address")]
public string Email { get; set; }
[ScaffoldColumn(false)]
[Required]
public virtual FacultyTitle Title { get; set; }
[Required]
[StringLength(128, MinimumLength = 2, ErrorMessage = "{0} must be less than {1} characters and more than {2} characters.")]
[DataType(DataType.Password)]
[Display(Name = "Password")]
public string Password { get; set; }
[Display(Name = "Position")]
[ScaffoldColumn(false)]
[Required]
public virtual Categories Categorie { get; set; }
And here is the part of the method that I am using to update the user password:
user.Password = Helper.EncryptPassword(newPass);
db.Entry(user).State = EntityState.Modified;
db.SaveChanges();
The exception message: The title and the categories field are required
Please any one help me

Resources