Additional fields MVC - c#

I have table UserProfile, where I have some additional fields, as email, typeAccount, isActivated etc.
When I get Membership.GetUser().(..), I don't have these fields. How to resolve it? And how to change value of this fields?
[Table("UserProfile")]
public class UserProfile
{
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int UserId { get; set; }
public string UserName { get; set; }
public string Email { get; set; }
public int typeAccount { get; set; }
public bool activated { get; set; }
public string activationcode { get; set; }
public bool del { get; set; }
}
Regards

The membership provider is not handling profiles. If you want to retrieve the UserProfile record of the currently authenticated user simply use the context:
[Authorize]
public ActionResult SomeAction()
{
using (UsersContext db = new UsersContext())
{
UserProfile user = db
.UserProfiles
.FirstOrDefault(u => u.UserName == User.Identity.Name);
// do something with the profile
}
...
}

Related

How to include the ApplicationUser of an object in ASP.NET Core

I'm trying to make an app just like LinkedIn / Facebook.
I have a list of posts and each one has an ApplicationUser (ASP.NET IdentityUser).
In my PostController, I want to return the list of posts and include the ApplicationUser.
But I don't want every attribute of the user as an object containing a (hashed) password.
How can I return a post including ApplicationUser but without the password attribute?
Post.cs
public class Post
{
[Key]
public int Id { get; set; }
[Required]
public string ApplicationUserID { get; set; }
[MaxLength(500)]
public string Contents { get; set; }
[Required]
public ulong Timestamp { get; set; }
}
PostController:
[Authorize]
[HttpGet("{id}")]
public async Task<ActionResult<Post>> GetPost(int id)
{
var post = await _context.Posts
.Include(x=> x.ApplicationUser)
.FirstOrDefaultAsync(x => x.Id == id);
if (post == null)
{
return NotFound();
}
return post;
}
ApplicationUser:
public class ApplicationUser : IdentityUser
{
}
You can create a view model which included the required properties, such as below:
public class PostViewModel
{
[Key]
public int Id { get; set; }
[Required]
public string ApplicationUserID { get; set; }
[MaxLength(500)]
public string Contents { get; set; }
[Required]
public ulong Timestamp { get; set; }
public string UserName { get; set; } //Directly add the username property, used to store the user name
public UserViewModel User { get; set; } //create a new view model which contains the username
}
public class UserViewModel
{
public string UserName { get; set; }
}
Then, change the LINQ statement as as below:
var query = _dbcontext.Posts.Include(c => c.ApplicationUser)
.Select(c => new PostViewModel()
{
Id = c.Id,
Contents = c.Contents,
Timestamp = c.Timestamp,
UserName = c.ApplicationUser.UserName,
User = new UserViewModel()
{
UserName = c.ApplicationUser.UserName
}
}).ToList();
The result as below:

Ef code first error: EntityType: 'ModelName' has no key defined

I'm struggling to make a login system in my project but I have a one Exception error.
The error look likes this:
This is my Person model:
namespace Entities.Concrete
{
public class Person:IEntity
{
public int Id { get; set; }
public string Name { get; set; }
public string Surname { get; set; }
public bool IsActive { get; set; }
public ICollection<User> Users { get; set; }
}
}
This is my User model:
namespace Entities.Concrete
{
public class User:IEntity
{
[ForeignKey("Person")]
public int PersonId { get; set; }
public string UserName { get; set; }
public string Password { get; set; }
public bool IsActive { get; set; }
public DateTime LastLoginDate { get; set; }
public int PersonForeignKey { get; set; }
public Person Person { get; set; }
}
}
My context look like this:
namespace DataAccess.Concrete.EntityFramework
{
public class SchoolDBContext : DbContext
{
public SchoolDBContext():base("SchoolDB")
{
}
public DbSet<Student> Students{ get; set; }
public DbSet<Person> Persons { get; set; }
public DbSet<User> Users { get; set; }
}
}
Finally, my Login method look like this:
public bool Login(string username, string password)
{
using (TContext context = new TContext())
{
var user = (from p in context.Persons
join u in context.Users
on p.Id equals u.PersonId
where p.IsActive == false &&
u.UserName == username &&
u.Password == password &&
u.IsActive == true
select p).FirstOrDefault();
if (user != null)
return true;
return false;
}
}
I am getting a error in the user variable.
I don't know how to assign a key with Entity framework Code first. Can you help me?
You don't have an 'Id' field for user, so it doesn't know what the Primary Key is for the User type.
Id is used by default by EF or you can specify your own one using the Key attribute.
just add
public int Id { get; set; }
to the User class type
the EF core docs show what to do here too -> https://learn.microsoft.com/en-us/ef/core/modeling/keys?tabs=data-annotations

ASP.net MVC: PK and FK values are not in sync on lazy loading for one-to-many

I have the tables Company and Roles with one-to-many relation. I know that for lazy loading set-up the FK value of a Role entity should be automatically set to be in sync with his PK value of a Company. In the Company table I have a company entity instance added, but for some reason it is added null when I add a new role entity instance. What am I doing wrong?
These are my domain classes and the context:
public class Company
{
public Company()
{
Roles = new List<Role>();
Employees = new List<Employee>();
}
public int CompanyId { get; set; }
public string Name { get; set; }
public string Address { get; set; }
public string PhoneNo { get; set; }
public string Email { get; set; }
public virtual ICollection<Role> Roles { get; set; }
public virtual ICollection<Employee> Employees { get; set; }
}
public class Role
{
public Role()
{
RoleOverviews = new List<RoleOverview>();
}
public int RoleId { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public virtual Company Company { get; set; }
public ICollection<RoleOverview> RoleOverviews { get; set; }
}
public class AppDbContext:DbContext
{
public DbSet<Company> Companies { get; set; }
public DbSet<Role> Roles { get; set; }
public DbSet<RoleOverview> RoleOverviews { get; set; }
public AppDbContext() : base("DefaultConnection")
{
}
}
public ActionResult Create([Bind(Include = "RoleId,Name,Description")] Role role)
{
if (ModelState.IsValid)
{
db.Roles.Add(role);
db.SaveChanges();
return RedirectToAction("Index", "CompaniesRolesMV");
}
return View(role);
}
The PK_FK relationship you have defined will only make certain that the company field in your Role table will have a valid ID. but it cannot 'guess' which company it belongs to unless the code tells it.
the Role you are defining/creating in your 'Create' method needs to have a CompanyID value supplied. Presumably, the user will have a choice from a Selector (?)
you probably need t define a Company selector in your View and your Create Method Action should include the CompanyID from that selector:
public ActionResult Create([Bind(Include = "RoleId,Name,Description,CompanyID")] Role role)
{
if (ModelState.IsValid)
{
db.Roles.Add(role);
db.SaveChanges();
return RedirectToAction("Index", "CompaniesRolesMV");
}
return View(role);
}

ASP MVC Application User Null using User.Identity.GetUserId

Ok so I have a relationship between the ApplicationUser and QuestionResults, my models are as below, the userId nor the UserName is retrieved, but I really need the UserId setup as a foreignKey on the QuestionResults entity.
Any help is much appreciated the error that I am receiving is as below:
An exception of type 'System.NullReferenceException' occurred in STRA.dll but was not handled in user code
Additional information: Object reference not set to an instance of an object.
on these lines of code:
qr.User.Id = User.Identity.GetUserId();
qr.User.UserName = User.Identity.GetUserName();
Models
public class QuestionResult
{
public QuestionResult()
{
DateCreated = DateTime.Now;
DateModified = DateTime.Now;
}
public int Id { get; set; }
public DateTime? DateCreated { get; set; }
public DateTime? DateModified { get; set; }
public int QuestionScore { get; set; }
//navigation properties
public virtual ApplicationUser User { get; set; }
//public ICollection<CategoryResult> CategoryResult { get; set; }
//public virtual Category Category { get; set; }
[NotMapped]
public int CategoryId { get; set; }
public virtual Question Question { get; set; }
public int QuestionId { get; set; }
//public virtual Category Category { get; set; }
//public int CategoryId { get; set; }
}
public class ApplicationUser : IdentityUser
{
public string FirstName { get; set; }
public string Surname { get; set; }
public string Industry { get; set; }
public string GlobalRegion { get; set; }
public string CurrentSituation { get; set; }
public int SalesForceSize { get; set; }
public bool IsVerified { get; set; }
//navigation properties
public virtual ICollection<CategoryResult> CategoryResult { get; set; }
public virtual ICollection<QuestionResult> QuestionResult { get; set; }
//public virtual ICollection<Report> Report { get; set; }
//public virtual ICollection<SurveyResult> SurveyResult { get; set; }
public virtual Organisation Organisation { get; set; }
public int? OrganisationId { 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;
}
}
Your code is equivalent to this::
var user = qr.User;
user.Id = User.Identity.GetUserId();
If the QuestionResult was already linked to a User then you would not be changing which User is linked to the QuestionResult, you would be changing the Id of an existing User - and that is not allowed anyway.
But the QuestionResult is not already linked to a User. qr.User is null - so you get a null reference exception.
In general, life is much easier in Entity Framework if you add the foreign key to your model:
public class QuestionResult
{
public string UserId { get; set; }
public virtual ApplicationUser User { get; set; }
}
And now you can set the foreign key directly:
qr.UserId = User.Identity.GetUserId();
References:
Why does Entity Framework Reinsert Existing Objects into My Database?
Making Do with Absent Foreign Keys
So, do you wanna make foreing key for userid?
You can do like that:
public int UserRefID { get; set; }
[ForeignKey("UserRefID")]
public xxx UserID { get; set; } //data name like ApplicationUser
And this error appear coz you have some problem about models or data classes.
Set it as a string
Model:
public ApplicationUser User { get; set; }
public string UserId { get; set; }
Controller:
qr.UserId = User.Identity.GetUserId();
And worked perfectly, even created foreign keys, that easy. Thanks so much!

Getting a foreign key in a table

In my website, a user can add foreignExpressions to his account. The user model looks like this:
[Table("UserProfile")]
public class UserProfile
{
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int UserId { get; set; }
public string UserName { get; set; }
public List<ForeignExpression> learnedexpressions { get; set; }
}
Then in the controller I'd like to get the current user's stored expressions like this:
db.ForeignExpressions.Select(f => f.UserId == Membership.GetUser().ProviderUserKey);
However, ForeignExpression does not contain a UserId field, so there's no visible UserId for f. But the UserProfile has a collecion of ForeignExpressions, so I have a UserId field in the ForeignExpression table. I'm confused, how am I supposed to get the ForeignExpressions for my user?
Edit:
public class ForeignExpression
{
public int ID { get; set; }
public string expression { get; set; }
public string context { get; set; }
public string meaning { get; set; }
public DateTime dateAdded { get; set; }
}
int userID = Membership.GetUser().ProviderUserKey;
db.UserProfiles.Find(q => q.UserID == userID).LearnedExpressions.ToList();

Categories