Entity Framework - Validation error on entity read at Azure - c#

From yesterday i am struggling with that strange error. Localhost deploy works fine, but few hours after deploy on Azure i get
Validation failed for one or more entities. See 'EntityValidationErrors' property for more details.
It's happen when i enter to my controller registration action on fetching :
[AllowAnonymous]
public ActionResult Register()
{
Wallet stockMarketWallet = walletRepository.GetMarketWallet(); // here it comes
RegisterViewModel vm = new RegisterViewModel();
vm.UserStocks = new List<UserStockViewModel>();
foreach (UserStock stock in stockMarketWallet.OwnedStocks)
{
vm.UserStocks.Add(new UserStockViewModel {
StockId = stock.StockId,
Code = stock.Stock.Code
});
}
return View(vm);
}
Internal Error details says that UserApplications not unique username is rising ValidationError.
WalletRepository
public class WalletRepository : IWalletRepository
{
private ApplicationContext context;
public WalletRepository()
=> context = ApplicationContext.Create();
public Wallet GetMarketWallet()
{
string stockMarketUserName = ConfigurationManager.AppSettings["StockMarketUsername"];
return context.Wallets.FirstOrDefault(w => w.ApplicationUser.UserName.Equals(stockMarketUserName));
}
...
}
}
Wallet
public class Wallet
{
[Key, ForeignKey("ApplicationUser")]
public string WalletId { get; set; }
public decimal Founds { get; set; }
public virtual IList<UserStock> OwnedStocks { get; set; }
public virtual ApplicationUser ApplicationUser { get; set; }
public Wallet()
{
OwnedStocks = new List<UserStock>();
}
...
}
ApplicationUser
public class ApplicationUser : IdentityUser
{
public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager)
{
var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);
return userIdentity;
}
public virtual Wallet Wallet { get; set; }
}
What is even stranger to me after cloning Azure database to localhost it works fine too.

According to your codes, I have developed a test demo on my computer, it works well.
I suggest you could create a new azure sql database and use its connection string directly in the local to test again.
More details about my test demo, you could refer to below codes:
IdentityModels.cs:
public class ApplicationUser : IdentityUser
{
public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager)
{
// Note the authenticationType must match the one defined in CookieAuthenticationOptions.AuthenticationType
var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);
// Add custom user claims here
return userIdentity;
}
public virtual Wallet Wallet { get; set; }
}
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
public ApplicationDbContext()
: base("DefaultConnection", throwIfV1Schema: false)
{
}
public static ApplicationDbContext Create()
{
return new ApplicationDbContext();
}
public DbSet<Wallet> Wallets { get; set; }
public DbSet<UserStock> UserStocks { get; set; }
}
Wallet.cs
public class Wallet
{
[Key, ForeignKey("ApplicationUser")]
public string WalletId { get; set; }
public decimal Founds { get; set; }
public virtual IList<UserStock> OwnedStocks { get; set; }
public virtual ApplicationUser ApplicationUser { get; set; }
public Wallet()
{
OwnedStocks = new List<UserStock>();
}
}
WalletRepository.cs
public class WalletRepository
{
public ApplicationDbContext context;
public WalletRepository() { context = ApplicationDbContext.Create(); }
public Wallet GetMarketWallet()
{
string stockMarketUserName = "The user name";
return context.Wallets.FirstOrDefault(w => w.ApplicationUser.UserName.Equals(stockMarketUserName));
}
}
HomeController:
public class HomeController : Controller
{
public ActionResult Index()
{
return View();
}
//Add test record
public ActionResult About()
{
ApplicationDbContext d1 = new ApplicationDbContext();
ApplicationUser user = d1.Users.FirstOrDefault(w => w.UserName.Equals("UserName"));
Wallet w1 = new Wallet();
w1.ApplicationUser = user;
w1.Founds = 300;
UserStock u1 = new UserStock();
u1.id = 1;
List<UserStock> l1 = new List<UserStock>();
l1.Add(u1);
w1.WalletId = user.Id;
d1.Wallets.Add(w1);
d1.SaveChanges();
ViewBag.Message = "Add Completed";
return View();
}
//Call the Repository to get the value
public ActionResult Contact()
{
WalletRepository walletRepository = new WalletRepository();
var result = walletRepository.GetMarketWallet();
ViewBag.Message = "WalletId : " + result.WalletId;
return View();
}
}
Result:
If this is still generate the error, please the details information about the error message.

Related

Is there a better way to test this ASP.NET MVC application?

I have created mocks for both IUserService and IDataResult. The test works fine but instead of pulling from the database, I created a user object to test this getcustomerlogin method. Is there a better way to test this case? Can we test this method with actual data from the database?
This is the testing code:
namespace UnitTesting
{
public class Tests
{
[Test]
public void login_unit_test()
{
// arrange
var userinput = new UserForLogin()
{
email = "testmail#mail.com",
password = "123456"
};
var userobject = new User()
{
Email= "testmail#mail.com",
Password = "123456"
};
var mockIdataResult = new Mock<IDataResult<User>>();
mockIdataResult.Setup(i => i.Success).Returns(true);
mockIdataResult.Setup(i => i.Data).Returns(userobject);
var mockIUserService = new Mock<IUserService>();
mockIUserService.Setup(i => i.getByEmail(userinput)).Returns(mockIdataResult.Object);
var authscontroller = new AuthsController(mockIUserService.Object);
// action
IActionResult result = authscontroller.getcustomerlogin(userinput);
var okResult = result as OkObjectResult;
// assert
Assert.AreEqual(200, okResult.StatusCode);
}
}
}
This is the login function we are trying to test.
namespace WEBAPII.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class AuthsController : ControllerBase
{
IUserService _userService;
public AuthsController(IUserService userService)
{
_userService = userService;
}
[HttpPost("login")]
public IActionResult getcustomerlogin(UserForLogin userForLogin)
{
var user = _userService.getByEmail(userForLogin);
if (user.Success)
{
if (!(user.Data.Email == userForLogin.email &&
user.Data.Password == userForLogin.password))
{
return BadRequest(user);
}
return Ok(user);
}
return BadRequest(user);
}
[HttpPost("logindadmin")]
public IActionResult adminlogin(UserForLogin userForLogin)
{
var admin = _userService.getAdmin(userForLogin);
if (admin.Success)
{
return Ok(admin);
}
return BadRequest(admin);
}
}
}
This is the IUserService interface that is set inside Authscontroller
namespace Business.Abstract
{
public interface IUserService
{
List<User> GetAll();
User GetById(int userId);
void Add(User user);
IDataResult<User> getByEmail(UserForLogin userForLogin);
IDataResult<User> getAdmin(UserForLogin userForLogin);
}
}
This is UserForLogin class that takes user information parameters.
public class UserForLogin
{
public string email { get; set; }
public string password { get; set; }
}
This is the User class that we store our information:
namespace Entities.Concrete
{
public class User : IEntity
{
public int id { get; set; }
public string Email { get; set; }
public string Password { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public DateTime CreatedAt { get; set; }
public string roles { get; set; }
}
}
To test your functionality with actual data from the database, you need to implement an integration test instead of a unit test.
You can create a new test database or a replica of the existing production server and populate some test data into it.
Use EF or ADO.Net for DB operations in place of macking.

Receiving "InvalidOperationException:" in Asp.net MVC

I am trying to create a simple Asp.NET MVC database where a user can create an account, create categories for recipes, and then enter their recipe and file them into the category of their choosing. However, when I attempt to run the test to see if I can reach my list of categories(where I can also add a category), I get the following error message:
InvalidOperationException: Unable to resolve service for type 'LC101Project2017.Data.RecipeDbContext' while attempting to activate 'LC101Project2017.Controllers.CategoryController'.
I'm new to C# and am completely confused as to what I'm doing wrong. Here are my codes:
Controller: (CategoryController.cs)
public class CategoryController : Controller
{
private readonly RecipeDbContext context;
public CategoryController(RecipeDbContext dbContext)
{
context = dbContext;
}
public IActionResult Index()
{
List<RecipeCategory> categories = context.Categories.ToList();
return View(categories);
}
public IActionResult Add()
{
AddCategoryViewModel addCategoryViewModel = new AddCategoryViewModel();
return View(addCategoryViewModel);
}
[HttpPost]
public IActionResult Add(AddCategoryViewModel addCategoryViewModel)
{
if (ModelState.IsValid)
{
RecipeCategory newCategory = new RecipeCategory
{
Name = addCategoryViewModel.Name
};
context.Categories.Add(newCategory);
context.SaveChanges();
CategoryController: return Redirect("/Category");
};
return View(addCategoryViewModel);
}
}
Database (RecipeDbContext.cs)
public class RecipeDbContext : DbContext
{
public DbSet<Recipe> Recipes { get; set; }
public DbSet<RecipeCategory> Categories { get; set; }
}
MODEL (RecipeCategory.cs)
public class RecipeCategory
{
public int ID { get; set; }
public string Name { get; set; }
public IList<RecipeCategory> RecipeCategories { get; set; }
}
Check if you have configured to use your DbContext, RecipeDbContext, inside ConfigureServices method in Startup.cs
The method should look like this;
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
services.AddDbContext<RecipeDbContext >(options =>
options.UseSqlServer(Configuration.GetConnectionString("ConnectionStringName")));
}
Updated the answer in response to the comment by #Mel Mason
You need to declare a constructor that accepts DbContextOptions<RecipeDbContext>.
public class RecipeDbContext : DbContext
{
public DbSet<Recipe> Recipes { get; set; }
public DbSet<RecipeCategory> Categories { get; set; }
public RecipeDbContext(DbContextOptions<RecipeDbContext> options)
: base(options)
{ }
}
You can also check the official documentation:
https://learn.microsoft.com/en-us/ef/core/miscellaneous/configuring-dbcontext
https://learn.microsoft.com/en-us/ef/core/miscellaneous/connection-strings
Hope this helps.

EntityType no keys defined

I'm creating an app where users log in via Facebook oAuth and then set up a list of songs. I am getting the following error message:
BandFinderCsharp.Models.IdentityUserLogin: : EntityType 'IdentityUserLogin' has no key defined. Define the key for this EntityType.
BandFinderCsharp.Models.IdentityUserRole: : EntityType 'IdentityUserRole' has no key defined. Define the key for this EntityType.
IdentityUserLogins: EntityType: EntitySet 'IdentityUserLogins' is based on type 'IdentityUserLogin' that has no keys defined.
IdentityUserRoles: EntityType: EntitySet 'IdentityUserRoles' is based on type 'IdentityUserRole' that has no keys defined.
The error message is occurring within my SongsController:
`namespace BandFinder.Controllers.Bread
{
public class SongsController : Controller
{
private SongDBContext db = new SongDBContext();
// GET: Songs
public ActionResult Index()
{
return View(db.Songs.ToList()); <--- This is where the error occurs
}
// GET: Songs/Details/5
public ActionResult Details(long? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Song song = db.Songs.Find(id);
if (song == null)
{
return HttpNotFound();
}
return View(song);
}
// GET: Songs/Create
public ActionResult Create()
{
return View();
}
// POST: Songs/Create
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include = "Id,UserId,BandId,Title,Artist,Genre,ListId,CreatedOn")] Song song)
{
if (ModelState.IsValid)
{
song.CreatedOn = DateTime.Now;
db.Songs.Add(song);
db.SaveChanges();
return RedirectToAction("Index");
}
return View(song);
}
// GET: Songs/Edit/5
public ActionResult Edit(long? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Song song = db.Songs.Find(id);
if (song == null)
{
return HttpNotFound();
}
return View(song);
}
// POST: Songs/Edit/5
// To protect from overposting attacks, please enable the specific properties you want to bind to, for
// more details see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit([Bind(Include = "Id,UserId,BandId,Title,Artist,Genre,ListId,CreatedOn")] Song song)
{
if (ModelState.IsValid)
{
db.Entry(song).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
return View(song);
}
// GET: Songs/Delete/5
public ActionResult Delete(long? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Song song = db.Songs.Find(id);
if (song == null)
{
return HttpNotFound();
}
return View(song);
}
// POST: Songs/Delete/5
[HttpPost, ActionName("Delete")]
[ValidateAntiForgeryToken]
public ActionResult DeleteConfirmed(long id)
{
Song song = db.Songs.Find(id);
db.Songs.Remove(song);
db.SaveChanges();
return RedirectToAction("Index");
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
db.Dispose();
}
base.Dispose(disposing);
}
}
}`
The thing I don't understand is, this controller has nothing to do with the IdentityUser code..
This is my ApplicationUser Model:
namespace BandFinderCsharp.Models
{
public class ApplicationUser : IdentityUser
{
public ApplicationUser()
{
CreatedOn = DateTime.Now;
this.ProfileImage = new byte[0];
this.facebookImage = new byte[0];
}
public byte[] facebookImage { get; set; }
[MaxLength(32)]
public string FirstName { get; set; }
[MaxLength(32)]
public string LastName { get; set; }
public byte[] ProfileImage { get; set; }
//public virtual ICollection<Instrument> Instruments { get; set; }
//public virtual ICollection<Song> Songs { get; set; }
//public virtual ICollection<Band> Bands { get; set; }
public string Zipcode { get; set; }
[Index]
public float Longitude { get; set; }
[Index]
public float Latitude { get; set; }
[Required]
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public DateTime CreatedOn { get; set; }
//////////////
public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager)
{
// Note the authenticationType must match the one defined in CookieAuthenticationOptions.AuthenticationType
var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);
// Add custom user claims here
return userIdentity;
}
}
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<IdentityUserLogin>().HasKey<string>(l => l.UserId);
modelBuilder.Entity<IdentityRole>().HasKey<string>(r => r.Id);
modelBuilder.Entity<IdentityUserRole>().HasKey(r => new { r.RoleId, r.UserId });
base.OnModelCreating(modelBuilder);
}
public ApplicationDbContext()
: base("DefaultConnection", throwIfV1Schema: false)
{
}
public static ApplicationDbContext Create()
{
return new ApplicationDbContext();
}
}
}
Why am I getting an error referring to Identity models from the songs controller? There should be no correlation between the two at this point.
The IdentityUser class is a built in .NET class which I don't believe I'm able to edit:
namespace Microsoft.AspNet.Identity.EntityFramework
{
//
// Summary:
// Default EntityFramework IUser implementation
public class IdentityUser : IdentityUser<string, IdentityUserLogin, IdentityUserRole, IdentityUserClaim>, IUser, IUser<string>
{
//
// Summary:
// Constructor which creates a new Guid for the Id
public IdentityUser();
//
// Summary:
// Constructor that takes a userName
//
// Parameters:
// userName:
public IdentityUser(string userName);
}
}
IdentityUserLogin
namespace Microsoft.AspNet.Identity.EntityFramework
{
//
// Summary:
// Entity type for a user's login (i.e. facebook, google)
public class IdentityUserLogin : IdentityUserLogin<string>
{
public IdentityUserLogin();
}
}
If the ApplicationUser class is the object you're looking to save in the Data Base, then it must contain a field named Id which is by default the primary key of the object to which Entity Framework is linking to.
Your Object should look like:
public class ApplicationUser
{
public int Id { get; set; }
public string Name { get; set; }
}
Or if you want to set a different property as the primary key for the object, you should add the [Key] attribute above that field - and you'll also need to add the System.ComponentModel.DataAnnotations namespace:
public class ApplicationUser
{
public int Id { get; set; }
[Key]
public string Name { get; set; }
}
Looking at your entities, I am missing the [Key] attribute that defines the fields for the primary key.
Look at this question, first answer:
EntityType 'Category' has no key defined. Define the key for this EntityType

Extending ASP.NET Identity Roles: IdentityRole is not part of the model for the current context

I'm trying to use the new ASP.NET Identity in my MVC5 application, specifically I'm trying to integrate ASP.NET Identity into an existing database. I've already read the questions/answers on SO pertaining to DB First and ASP.NET Identity, and having followed all the recommendations I still can't add roles to my database, although I have no problems adding users. Here's my code:
var context = new PayrollDBEntities();
var roleManager = new RoleManager<AspNetRole>(new RoleStore<AspNetRole>(context));
bool roleExists = roleManager.RoleExists(roleDto.Name);
if (roleExists){
return false;
}
var role = new AspNetRole(roleDto.Name){
Name = roleDto.Name,
};
IdentityResult result = roleManager.Create(role);//Getting exception here
At the last line of code I get an exception of type 'System.InvalidOperationException': The entity type IdentityRole is not part of the model for the current context.
Here is my context:
public partial class PayrollDBEntities : IdentityDbContext
{
public PayrollDBEntities()
: base("name=PayrollDBEntities")
{
}
public virtual DbSet<AspNetRole> AspNetRoles { get; set; }
public virtual DbSet<AspNetUserClaim> AspNetUserClaims { get; set; }
public virtual DbSet<AspNetUserLogin> AspNetUserLogins { get; set; }
public virtual DbSet<AspNetUser> AspNetUsers { get; set; }
......
}
My AspNetUser and AspNetRole classes derive from IdentityUser and IdentityRole respectively, but I'm still getting that exception. Here is my database diagram:
Any help would be greatly appreciated.
You have to specify during the creation of User Store that AspNetRole is used instead of IdentityRole. You can achieve this by using the UserStore class with 6 type parameters:
new UserStore<AspNetUser, AspNetRole, string, IdentityUserLogin, IdentityUserRole, IdentityUserClaim>(new PayrollDBEntities());
This indicates changes at User Manager creation as well. Here is a simplified example about the creation of needed instances:
public class AspNetUser : IdentityUser { /*customization*/ }
public class AspNetRole : IdentityRole { /*customization*/ }
public class PayrollDBEntities : IdentityDbContext //or : IdentityDbContext <AspNetUser, AspNetRole, string, IdentityUserLogin, IdentityUserRole, IdentityUserClaim>
{
}
public class Factory
{
public IdentityDbContext DbContext
{
get
{
return new PayrollDBEntities();
}
}
public UserStore<AspNetUser, AspNetRole, string, IdentityUserLogin, IdentityUserRole, IdentityUserClaim> UserStore
{
get
{
return new UserStore<AspNetUser, AspNetRole, string, IdentityUserLogin, IdentityUserRole, IdentityUserClaim>(DbContext);
}
}
public UserManager<AspNetUser, string> UserManager
{
get
{
return new UserManager<AspNetUser, string>(UserStore);
}
}
public RoleStore<AspNetRole> RoleStore
{
get
{
return new RoleStore<AspNetRole>(DbContext);
}
}
public RoleManager<AspNetRole> RoleManager
{
get
{
return new RoleManager<AspNetRole>(RoleStore);
}
}
}
After a few days of trying to get this to work in a clean manner, I've come to the conclusion that if you're using Database first and want to integrate ASP.NET Identity into your app, by far the easiest and cleanest solution is to create your own membership provider by overriding ASP.NET Identity. It's actually pretty easy, so far I've implemented UserStore and RoleStore to my liking. I've added columns/relations specific to my domain in my database, and whenever I create a user or a role, I take care of my database commits by adding the required relations. My UserStore implementation is quite similar to this. My RoleStore implementation is something like this:
public class ApplicationRoleStore : IRoleStore<ApplicationRoleDTO>
{
private PayrollDBEntities _context;
public ApplicationRoleStore() { }
public ApplicationRoleStore(PayrollDBEntities database)
{
_context = database;
}
public Task CreateAsync(ApplicationRoleDTO role)
{
if (role == null)
{
throw new ArgumentNullException("RoleIsRequired");
}
var roleEntity = ConvertApplicationRoleDTOToAspNetRole(role);
_context.AspNetRoles.Add(roleEntity);
return _context.SaveChangesAsync();
}
public Task DeleteAsync(ApplicationRoleDTO role)
{
var roleEntity = _context.AspNetRoles.FirstOrDefault(x => x.Id == role.Id);
if (roleEntity == null) throw new InvalidOperationException("No such role exists!");
_context.AspNetRoles.Remove(roleEntity);
return _context.SaveChangesAsync();
}
public Task<ApplicationRoleDTO> FindByIdAsync(string roleId)
{
var role = _context.AspNetRoles.FirstOrDefault(x => x.Id == roleId);
var result = role == null
? null
: ConvertAspNetRoleToApplicationRoleDTO(role);
return Task.FromResult(result);
}
public Task<ApplicationRoleDTO> FindByNameAsync(string roleName)
{
var role = _context.AspNetRoles.FirstOrDefault(x => x.Name == roleName);
var result = role == null
? null
: ConvertAspNetRoleToApplicationRoleDTO(role);
return Task.FromResult(result);
}
public Task UpdateAsync(ApplicationRoleDTO role)
{
return _context.SaveChangesAsync();
}
public void Dispose()
{
_context.Dispose();
}
private ApplicationRoleDTO ConvertAspNetRoleToApplicationRoleDTO(AspNetRole aspRole)
{
return new ApplicationRoleDTO{
Id = aspRole.Id,
EnterpriseId = aspRole.EnterpriseId,
Name = aspRole.Name
};
}
private AspNetRole ConvertApplicationRoleDTOToAspNetRole(ApplicationRoleDTO appRole)
{
return new AspNetRole{
Id = appRole.Id,
EnterpriseId = appRole.EnterpriseId,
Name = appRole.Name,
};
}
}
And my ApplicationRoleDTO:
public class ApplicationRoleDTO : IRole
{
public ApplicationRoleDTO()
{
Id = Guid.NewGuid().ToString();
}
public ApplicationRoleDTO(string roleName)
: this()
{
Name = roleName;
}
public string Id { get; set; }
public string Name { get; set; }
public Guid EnterpriseId { get; set; }
}
I also found these 2 articles pretty helpful:
Overview of Custom Storage Providers for ASP.NET Identity
Implementing a Custom MySQL ASP.NET Identity Storage Provider
I'll explain here with the code exampels :).
The trick is, they are already in the IdentityDbContext (AspNetRoles, AspNetUserClaims, AspNetUsers, ....)
In the IdentityModel you will see ApplicationUser is empty at the top. If you want to customize these users or roles, just add properties here and then update your database via the console
Example of my context
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
public ApplicationDbContext()
: base("DefaultConnection")
{
}
public DbSet<Request> Requests { get; set; }
public DbSet<Reservation> Reservations { get; set; }
public DbSet<PriceType> PriceTypes { get; set; }
public DbSet<Product> Products { get; set; }
public DbSet<Price> Prices { get; set; }
public DbSet<GuestbookPost> Posts { get; set; }
public DbSet<Count> Counts { get; set; }
public DbSet<Invoice> Invoices { get; set; }
public DbSet<InvoiceLine> InvoiceLines { get; set; }
...
}
So no application user is defined here, but I did add more properties to it, example:
public class ApplicationUser : IdentityUser
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string GroupName { get; set; }
public string Email { get; set; }
[StringLength(15)]
public string Phone { get; set; }
public string Remark { get; set; }
public DateTime? BirthDate { get; set; }
public DateTime ValidFrom { get; set; }
public DateTime ValidUntil { get; set; }
public string Street { get; set; }
public string ZipCode { get; set; }
public string City { get; set; }
public virtual ICollection<Request> Requests { get; set; }
}
I know this is an old question, but just in case someone else is having a hard time adding roles/users when they modified asp identity to use numeric primary keys (int/long) instead of the default string for the Identity Roles, so if you have changed the IdentityUserRole in IdentityModels.cs to something like this:
public class Role : IdentityRole<long, UserRole>
{
public Role() { }
public Role(string name) { Name = name; }
}
You have to use the class Role instead of the default IdentityRole when constructing the RoleManager, so your code should be like this:
public static void RegisterUserRoles()
{
ApplicationDbContext context = new ApplicationDbContext();
var RoleManager = new RoleManager<Role, long>(new RoleStore(context));
if (!RoleManager.RoleExists("Administrador"))
{
var adminRole = new Role {
Name = "Administrador",
};
RoleManager.Create(adminRole);
}
}
So this should populate your database properly, I think all experienced ASP programmers already know this, but for others this could take some time to figure out.
I solved with a different way.
First I splited in two different Projects and Contexts.
My project that Handle the Identity has this context:
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>, IDisposable
{
public ApplicationDbContext()
: base("DefaultConnection", throwIfV1Schema: false)
{
}
public static ApplicationDbContext Create()
{
return new ApplicationDbContext();
}
}
This is my ApplicationUser:
public class ApplicationUser : IdentityUser
{
//Put here the extra properties that Identity does not handle
[Required]
[MaxLength(150)]
public string Nome { get; set; }
public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager)
{
// Note the authenticationType must match the one defined in CookieAuthenticationOptions.AuthenticationType
var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);
// Add custom user claims here
return userIdentity;
}
}
And my ApplicationUserManager looks like this:
public class ApplicationUserManager : UserManager<ApplicationUser>
{
public ApplicationUserManager(IUserStore<ApplicationUser> store)
: base(store)
{
//Setting validator to user name
UserValidator = new UserValidator<ApplicationUser>(this)
{
AllowOnlyAlphanumericUserNames = false,
RequireUniqueEmail = true
};
//Validation Logic and Password complexity
PasswordValidator = new PasswordValidator
{
RequiredLength = 6,
RequireNonLetterOrDigit = false,
RequireDigit = false,
RequireLowercase = false,
RequireUppercase = false,
};
//Lockout
UserLockoutEnabledByDefault = true;
DefaultAccountLockoutTimeSpan = TimeSpan.FromMinutes(5);
MaxFailedAccessAttemptsBeforeLockout = 5;
// Providers de Two Factor Autentication
RegisterTwoFactorProvider("Código via SMS", new PhoneNumberTokenProvider<ApplicationUser>
{
MessageFormat = "Seu código de segurança é: {0}"
});
RegisterTwoFactorProvider("Código via E-mail", new EmailTokenProvider<ApplicationUser>
{
Subject = "Código de Segurança",
BodyFormat = "Seu código de segurança é: {0}"
});
//Email service
EmailService = new EmailService();
// Definindo a classe de serviço de SMS
SmsService = new SmsService();
var provider = new DpapiDataProtectionProvider("Braian");
var dataProtector = provider.Create("ASP.NET Identity");
UserTokenProvider = new DataProtectorTokenProvider<ApplicationUser>(dataProtector);
}
}
I hope that this helps someone.
This solution was from this article:
Eduardo Pires - But it is in Portuguese
I fixed this issue by changing the web.config DefaultConnection connectionString property so it points to the new SQLServer database

Entity Framework database seed doesn't seed

I'm quite new to EF. I'm trying to override a Seed method inside my custom initializer, using MVC 4.
The problem is when EF creates the database, i don't find any initial records inserted into my Admins table. Here's my code :
namespace FP.Domain.Configurations
{
public class InitializeSeed : DropCreateDatabaseIfModelChanges<EFDbContext>
{
protected override void Seed(EFDbContext context)
{
context.Admins.Add(new Admins
{
Username = "admin",
Password = "admin123456",
});
base.Seed(context);
}
}
}
And here's my controller :
namespace FP.WebUI.Controllers
{
public class AdminController : Controller
{
public ViewResult Login()
{
Database.SetInitializer(new InitializeSeed());
return View();
}
}
}
And here's my Admins entity :
namespace FP.Domain.Entities
{
public class Admins
{
public int ID { get; set; }
public string Username { get; set; }
public string HashedPassword { get; set; }
private string _password;
public string Password
{
set
{
this._password = value;
byte[] tempSrc = ASCIIEncoding.ASCII.GetBytes(_password);
HashedPassword = Convert.ToBase64String(new SHA256CryptoServiceProvider().ComputeHash(tempSrc));
}
}
}
}
You are not saving your changes to the database. Note that the default implementation of Seed does nothing.
Try adding a call to SaveChanges in your Seed.
protected override void Seed(EFDbContext context)
{
context.Admins.Add(new Admins
{
Username = "admin",
Password = "admin123456",
});
base.Seed(context);
context.SaveChanges();
}

Categories

Resources