Sorry for newbie questions, i'm brand new to MVC and OOP
I have the following model for my USER db table
namespace MyApp.Models
{
public class User
{
public int user_id { get; set; }
public string username { get; set; }
public string password { get; set; }
public string salt { get; set; }
public string email { get; set; }
public sbyte status { get; set; }
public System.DateTime creation_date { get; set; }
public sbyte type { get; set; }
public virtual Doctor Doctor { get; set; }
public virtual Owner Owner { get; set; }
public virtual UserToken UserToken { get; set; }
public virtual Veterinarian Veterinarian { get; set; }
}
}
Actually in order to recall a particular USER based on the mail or the id i use a specific class called CustomDbFunctions
namespace MyApp.Models.DAL
{
public static class CustomDbFunctions
{
public static User GetUserEntityFromEmail(string email, DbContext db)
{
return db.Users.FirstOrDefault(u => u.email == (string)email);
}
}
}
in that way i use in my code
User user = CustomDbFunctions.GetUserEntityFromEmail(email, db)
and this it 100% OK with me, but i don't know if this kind of approach is correct or not, or if there's a better way like
//select the single user by calling only the class USER
User mySelectedUser = new User(email)
Thank you very much.
Well for understanding how to access your data in your MVC4 application you could read this tutorial from the Asp.Net MVC main page. Read the whole tutorial about MVC4 and you'll get a solid idea on how to work with it.
But I also recommend this tutorial on a good Entityframework design pattern, it's called Repository Pattern, I just a nice way to get all your code ordered (like all other patterns). Let me know.
Related
In Asp net core (3.1) Identity i want add a many to many relationship between user and TourOperators.
(The concept is that many user can follow many tour operators).
I have the tour operators class:
public class TourOperator
{
public int Id { get; set; }
public ICollection<Follow> Follows { get; set; }
}
I have extended the UserIdentity class:
public class ApplicationUser: IdentityUser
{
public ICollection<Follow> Follow { get; set; }
}
I have the Follow class:
public class Follow
{
public long Id { get; set; }
public string UserId { get; set; }
public ApplicationUser ApplicationUser { get; set; }
public int TourOperatorId { get; set; }
public TourOperator TourOperator{ get; set; }
}
After execute the migration, why in the Follow table i have 4 field instead of 3?
I have the following field:
I think that ApplicationUserId couldn't be present
Entity Framework has no way to link the UserId and ApplicationUser properties. So you either need to follow convention, whereby EF can make an educated guess. The simplest option is to rename your string property:
public string ApplicationUserId { get; set; }
Alternatively, you can configure it, for example using an attribute:
[ForeignKey("ApplicationUser"]
public string UserId { get; set; }
public ApplicationUser ApplicationUser { get; set; }
Or in the OnModelCreating method, for example:
modelBuilder.Entity<Follow>()
.WithOne(f => f.ApplicationUser)
.HasForeignKey("UserId");
I have an API that is used in a multi-site/multi-location environment. At the moment, each user has roles defined but is locked to only one location. I am needing to extend this out to where a user may have admin roles for one location and then may be standard user at another location. They may also have no roles/no access to a bunch of locations.
Here is what I am working with right now (asp.net core 2.2):
public class ApplicationUser : IdentityUser
{
public string FirstName { get; set; }
public string LastName { get; set; }
public int? LocationId { get; set; }
public virtual Locations Locations { get; set; }
public int? ContactPersonId { get; set; }
public virtual ContactPerson ContactPerson { get; set; }
}
public class Locations
{
public int Id { get; set; }
public string Name { get; set; }
public virtual ApplicationUser ApplicationUser { get; set; }
}
public class ContactPerson
{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string UserId { get; set; }
public virtual ApplicationUser ApplicationUser { get; set; }
public virtual ICollection<ContactOrganizationPerson> ContactOrganizationPeople { get; set; }
public virtual ICollection<ContactAddress> ContactAddresses { get; set; }
public virtual ICollection<ContactPhone> ContactPhones { get; set; }
public virtual ICollection<ContactEmail> ContactEmails { get; set; }
}
I am planning on changing the ApplicationUser to Locations table relationship to a Many to Many which would link the User to the Locations they are allowed to access. I have though about placing a payload in the M2M relationship table that would specify UserId, LocationId and Roles, but I would rather let Identity handle it if possible.
Is there a way to extend AspNetUserRoles so that I can specify a User to Role relationship for each location? Or is there a better way to accomplish this?
I'm not sure if this is going to help you, but I have extended .Net Core with functionality with IAuthorizationRequirement.
public class CustomRequirement : IAuthorizationRequirement
{
public CustomRequirement ()
{
}
}
Create a new class
public class CustomHandler : AuthorizationHandler<CustomRequirement>
Override HandleRequirementAsync
protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, CustomRequirement requirement)
Here you can extract info about user from DB, compare, etc. If user is not allowed, return
return Task.CompletedTask;
If user is allowed, then use
context.Succeed(requirement);
Before returning. Then in your startup.cs:
services
.AddAuthorization(options =>
{
options.AddPolicy("CustomPolicy", policy =>
policy.Requirements.Add(new CustomRequirement()));
})
And then in your controllers you can add attribute
[Authorize(Policy = "CustomPolicy", Roles = "Admin")]
If requirement is not meet, user will get 401 unauthorized, which might not be what you want.
I am new to Web Api and just trying to learn by playing with different examples. I am completely stuck on trying to write a Get request to return a complex type. I have 3 entities, 1 of the entities has a list of another entity, So I am trying to figure out how to return the data from within both.
I looked at some examples on stack overflow, that showed to use the .Include linq statement, but when I try that, I am getting compiler errors (type argument cannot be inferred.
Basically, I have a class of Players, Teams and Specialties. Once I get this working, I am planning on writing an angular project. The specialties table is a multiselect for a given player.
Here is what I have written so far
public class Player
{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public int JerseyNo { get; set; }
public DateTime DateAquired { get; set; }
public string Bio { get; set; }
[ForeignKey("TeamID")]
public virtual Team Team { get; set; }
public virtual IEnumerable<Specialty> Specialites { get; set; }
}
public class Specialty
{
public int Id { get; set; }
public string Speciality { get; set; }
public virtual Player Player { get; set; }
}
public class Team
{
public int Id { get; set; }
public string TeamName { get; set; }
public virtual Player Player { get; set; }
}
public class dbContext :DbContext
{
public DbSet<Player> Players { get; set; }
public DbSet<Team> Teams { get; set; }
public DbSet<Specialty> Specialties { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder builder)
{
builder.UseSqlServer(#"Server=(localdb)\mssqllocaldb;Database=Test;Trusted_Connection=True;");
}
}
When I created the database using migrations, it looks how I want it to, but cannot figure out Web Api's joins to get the data from my specialties table. The .Include cannot recognize any value I enter as parameters
private dbContext db = new dbContext();
// GET: api/values
[HttpGet]
public IEnumerable<Player> Get()
{
var teams = db.
Players
.Include("Specialties")
.Select(p=> new Player
Looks like this an Entity Framework question.
Try if you can get this to work, for debugging purpose:
var teams = db.Players.ToList();
foreach (var player in teams)
{
// Force lazy loading of Specialities property
player.Specialities.ToList();
}
If this doesn't work, it looks like EF cannot figure out the mapping to the database.
I get this webservice error sometimes on a SL5 + EF + WCF app.
"Parameter 'role' of domain operation entry 'AddUserPresentationModelToRole' must be one of the predefined serializable types."
here is a similar error, however his solution doesn't work for me.
I have the codegenned DomainService which surfaces the database entities to my client:
[EnableClientAccess()]
public partial class ClientAppDomainService : LinqToEntitiesDomainService<ClientAppUserEntitlementReviewEntities>
{
public IQueryable<Account> GetAccounts()
{
return this.ObjectContext.Accounts;
}
//..etc...
and my custom service which is surfacing a Presentation model, and db entities.
[EnableClientAccess]
[LinqToEntitiesDomainServiceDescriptionProvider(typeof(ClientAppUserEntitlementReviewEntities))]
public class UserColourService : DomainService
{
[Update(UsingCustomMethod = true)]
public void AddUserPresentationModelToRole(UserPresentationModel userPM, Role role, Reviewer reviewer)
{
...
}
public IDictionary<long, byte> GetColourStatesOfUsers(IEnumerable<RBSUser> listOfUsers, string adLogin)
{
//....
}
}
and the PresentationModel:
public class UserPresentationModel
{
[Key]
public long UserID { get; set; }
public byte UserStatusColour { get; set; }
public string MessageText { get; set; }
[Include]
[Association("asdf", "UserID", "UserID")]
public EntityCollection<Account> Accounts { get; set; }
public DateTime AddedDate { get; set; }
public Nullable<long> CostCentreID { get; set; }
public DateTime? DeletedDate { get; set; }
public string EmailAddress { get; set; }
public long EmployeeID { get; set; }
public string FirstName { get; set; }
public Nullable<bool> IsLeaver { get; set; }
public string LastName { get; set; }
public DateTime LastSeenDate { get; set; }
public string LoginDomain { get; set; }
public string LoginName { get; set; }
public byte WorldBuilderStatusID { get; set; }
}
Also cannot get the solution to reliably fail. It seems whenever I change the service slightly ie make it recompile, everything works.
RIAServices unsupported types on hand-built DomainService - seems to be saying the same thing, that decorating the hand built services with the LinqToEntitiesDomainServiceDescriptionProvider should work.
Possible answer here will post back here too with results.
From Colin Blair:
I am a bit surprised it ever works, I don't think I have seen anyone trying to pass additional entiities into a named update before. It might be a bug in RIA Services that it is working at all. What are you trying to accomplish?
Side note, you have a memory leak with your ObjectContext since it is not getting disposed of correctly. Is there a reason you aren't using the LinqToEntitiesDomainSerivce? It would take care of managing the ObjectContext's lifetime for you.
Results:
1) This makes sense. Have refactored out to more sensible parameters now (ints / strings), and all working.
2) Have brought together my 3 separate services into 1 service, which is using the LinqToEntitiesDomainSerivce. The reason I'd split it out before was the assumption that having a CustomUpdate with a PresentationModel didn't work.. and I had to inherit off DomainService instead. I got around this by making a method:
// need this to avoid compile errors for AddUserPresentationModelToRole.. should never be called
public IQueryable<UserPresentationModel> GetUserPresentationModel()
{
return null;
}
I am using MVC3 and Entity Framework. I have a class called User with 20 different properties. I have already created a database and filled it with some data. I want to break out the Addresses property and make it it's own class.
namespace NameSpace.Domain.Entities
{
public class User
{
public int UserId { get; set; }
...
...
public string AddressOne { get; set; }
public string AddressTwo { get; set; }
}
}
I want to break out both Addresses like so
namespace NameSpace.Domain.Entities
{
public class User
{
public int UserId { get; set; }
...
...
public Addresses Addresses { get; set; }
}
public class Addresses
{
public string AddressOne { get; set; }
public string AddressTwo { get; set; }
}
}
HERE'S MY QUESTION:
Since I already have the data table filled with data, how can I update this in the Server Explorer?
Thanks ( if you need more info please let me know )
If you are using EF code first 4.3 you can use the concept of migrations to achive what you want.
You will need to do a code based manual migration since you change is a bit to advanced for the framework to figure it out itselfe.
Further reading: http://blogs.msdn.com/b/adonet/archive/2012/02/09/ef-4-3-code-based-migrations-walkthrough.aspx