i want to make a relationship between aspnetusers and table uservotes.i did this relationship according to docs but whent i want to add data to uservotes and savechanges the compiler stops in savechanges line.does anyone khow the problem?thank you for any help.
public class UserVote
{
[Key]
public int VoteId { get; set; }
public string ClientId { get; set; }
public int Hpid { get; set; }
public int Hplid { get; set; }
[ForeignKey(nameof(Hpid))]
public TableHp TableHp { get; set; }
[ForeignKey(nameof(Hplid))]
public TableHpl TableHpl { get; set; }
[ForeignKey(nameof(ClientId))]
public ApplicationUser Applicationuser { get; set; }
}
public class ApplicationUser:IdentityUser
{
public virtual List<UserVote> UserVotes { get; set; }
}
public async Task<int> AddvoteForHp(int hpid, string userid)
{
UserVote vote = new UserVote()
{
Hpid = hpid,
ClientId = userid
};
await _context.AddAsync(vote);
await _context.SaveChangesAsync();
var user = await GetPersonByIdAsync(hpid);
user.Like++;
_context.TableHps.Update(user);
await _context.SaveChangesAsync();
return user.Like;
}
Related
Im currently working on an ASP.NET project but I have a problem. I know a little about policies. but dont really know how I can grant acces to a user to delete his own data(posts, comments, etc..) but denying to delete or modify the uther user's data. Can you guys help me with that? Im currently authenticating with a JWT token.
My token:
public static class JWTToken
{
public static string CreateToken(User user)
{
List lista = new List();
lista.Add(new Claim("id", user.Id.ToString()));
lista.Add(new Claim("username", user.Username));
lista.Add(new Claim("email", user.Email));
lista.Add(new Claim("password", user.Password));
lista.Add(new Claim("role", user.Role.Name));
var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Secure.Key));
;
var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
var token = new JwtSecurityToken(
claims: lista,
expires: DateTime.UtcNow.AddDays(5),
signingCredentials: creds);
var jwt = new JwtSecurityTokenHandler().WriteToken(token);
return jwt;
}
public static JwtSecurityToken DecodeToken(string stream) {
var handler = new JwtSecurityTokenHandler();
return handler.ReadJwtToken(stream);
}
//Már nem jó mert át lettek nevezve a jwt token adatok
public static string GetDataFromToken(HttpContext context, string type) {
ClaimsIdentity identity = context.User.Identity as ClaimsIdentity;
IEnumerable<Claim> claim = identity.Claims;
var data = claim.Where(x => x.Type == type).FirstOrDefault().ToString().Split(':')[1].Trim();
return data;
}
}
Post model:
[Table("Post")]
public class Post
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
public string Data { get; set; }
[NotMapped]
[JsonIgnore]
public virtual User User { get; set; }
[ForeignKey(nameof(User))]
public int Post_UserId { get; set; }
}
User model:
[Table("User")]
public class User
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
[MaxLength(15)]
[Required]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public string Username { get; set; }
[MaxLength(30)]
[Required]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public string Email { get; set; }
[MaxLength(30)]
[Required]
//[JsonIgnore]
public string Password { get; set; }
public int? Money { get; set; }
public bool Validated { get; set; }
public string ProfilePictureRoot { get; set; }
[NotMapped]
[JsonIgnore]
public virtual IList<NWEvent> Events { get; set; }
[NotMapped]
[JsonIgnore]
public virtual Role Role { get; set; }
[ForeignKey(nameof(Role))]
public string Rolename { get; set; }
[NotMapped]
[JsonIgnore]//nem volt itt
public virtual IList<Post> Posts { get; set; }
[NotMapped]
[JsonIgnore]
public virtual IList<Event_User_Connect> Event_User_Conns { get; set; }
/*
public string ApiString()
{
return $"{Id}~{Username}~{Email}~{Password}";
}
*/
}
How can I manage this?
I'm Learning Webapi so I'm trying to build a simple Api connected to SQL server and I got this error when I add new Movie data
Microsoft.EntityFrameworkCore.DbUpdateException: An error occurred while saving the entity changes. See the inner exception for details.
---> Microsoft.Data.SqlClient.SqlException (0x80131904): The INSERT statement conflicted with the FOREIGN KEY constraint "FK_Movies_SuperHeroes_HeroId". The conflict occurred in database "SupersDb", table "dbo.SuperHeroes", column 'HeroId'.
I have two models :
Superhero Model:
namespace SuperHeroesApi.Models
{
public class SuperHero
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int HeroId { get; set; }
[Required]
[MaxLength(100)]
public string Name { get; set; }
[MaxLength(100)]
public string FirstName { get; set; }
[MaxLength(100)]
public string LastName { get; set; }
[MaxLength(100)]
public string City { get; set; }
}
}
Movie Model :
namespace SuperHeroesApi.Models
{
public class Movie
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int MovieId { get; set; }
[Required]
[MaxLength(100)]
public string Title { get; set; }
public int Year { get; set; }
public double Rate { get; set; }
public byte [] Poster { get; set; }
[ForeignKey("SuperHero")]
public int HeroId { get; set; }
//public string SuuperHeroName { get; set; }
public virtual SuperHero SuperHero { get; set; }
}
}
dto :
namespace SuperHeroesApi.Otds
{
public class MoviesDtos
{
public string Title { get; set; }
public int Year { get; set; }
public double Rate { get; set; }
public IFormFile Poster { get; set; }
[ForeignKey("SuperHero")]
public int HeroId { get; set; }
}
}
MoviesController:
using SuperHeroesApi.Otds;
namespace SuperHeroesApi.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class MoviesController : ControllerBase
{
private readonly AppDbContext _dbContext;
private new List<string> _allowedExtention = new List<string> { "jbg", "png" };
private long _maxAllowedPosterSize = 5242880;
public MoviesController(AppDbContext dbContext)
{
_dbContext = dbContext;
}
[HttpGet]
public async Task<IActionResult>GetAllAsync()
{
var movie = await _dbContext.Movies.ToListAsync();
return Ok(movie);
}
[HttpPost]
public async Task <IActionResult> CreateAsync([FromForm] MoviesDtos dto)
{
if (_allowedExtention.Contains(Path.GetExtension(dto.Poster.FileName).ToLower()))
return BadRequest();
using var dataStream = new MemoryStream();
await dto.Poster.CopyToAsync(dataStream);
var movie = new Movie
{
Title = dto.Title,
Year = dto.Year,
Rate = dto.Rate,
Poster = dataStream.ToArray(),
};
await _dbContext.AddAsync(movie);
_dbContext.SaveChanges();
return Ok(movie);
}
}
}
You probably already have existing rows before you made changes to your schema. Now that you're creating a new foreignkey HeroId in movie which cannot be null and an integer for that matter which means it will be a zero by default. It becomes a problem for the existing rows because they will try to reference a Hero entity with Id of 0 which doesn't exist. So, the obvious solution is to make the foreign key nullable and redo the migrations
[ForeignKey("SuperHero")]
public int? HeroId { get; set; }
Currently I'm creating a new feature. It looks simple, but I am stuck at a problem with automapping dto to another one.
I have to create a wishlist [adding /deleting items of wishlist].
All works fine, except one thing: while adding an item to the wishlist, I'm get a message like this:
"type": "AutoMapperMappingException",
"message": "Error mapping types..."
However, I can see it got inserted into the database. Also, can delete it too. I understand the problem is linked to Automapper, but I could not figure out how to map correctly.
[HttpPost]
public async Task<IActionResult> Add(WishListItemCreationDto wishListItemDto)
{
var itemAdd = _mapper.Map<WishlistItemDto>(wishListItemDto);
var itemCreated = await _wishListItemService.AddAsync(itemAdd);
return CreatedAtAction(nameof(GetId), new { id = itemCreated.Id }, wishListItemDto);
}
//service
public async Task<WishlistItemDto> AddAsync(WishlistItemDto item)
{
var entity = _mapper.Map<WishlistItem>(item);
var entityDetails = await _productDetailsRepository.GetById(item.ProductDetailId);
entity.ProductDetails = entityDetails;
await _wishListItemRepository.AddAsync(entity);
return _mapper.Map<WishlistItemDto>(entity);
}
DTOs:
public class WishListItemCreationDto
{
[Required]
public string CustomerId { get; set; }
[Required]
public int ProductDetailId { get; set; }
[Min(1)]
[Required]
public int Quantity { get; set; }
}
public class WishlistItemDto
{
public int Id { get; set; }
public string CustomerId { get; set; }
public int ProductDetailId { get; set; }
public ProductDetailsDtoWithPrimaryImage ProductDetails { get; set; }
public int Quantity { get; set; }
}
public class WishlistItem
{
public int Id { get; set; }
public string CustomerId { get; set; }
public Customer Customer { get; set; }
public int ProductDetailsId { get; set; }
public ProductDetails ProductDetails { get; set; }
public int Quantity { get; set; }
}
ProductDetails DTO:
public class ProductDetails
{
public int Id { get; set; }
public int ProductId { get; set; }
public Product Product { get; set; }
public IList<ProductAttributeValue> ProductAttributes { get; set; } = new List<ProductAttributeValue>();
public int Quantity { get; set; }
public string Sku => $"BRD{Id}";
public byte[] RowVersion { get; set; } = new byte[0];
}
public class ProductDetailsDtoWithPrimaryImage
{
public int Id { get; set; }
public int Quantity { get; set; }
public int ProductId { get; set; }
public ProductDisplayEntity Product { get; set; }
public IEnumerable<ProductAttributeWithValueDto> ProductAttributes { get; set; }
public byte[] RowVersion { get; set; }
public string Sku => $"BRD{Id}";
public int? PrimaryImageId { get; set; }
}
AutoMapper:
public WishlistItemProfile()
{
CreateMap<WishlistItem, WishListItemCreationDto>().ReverseMap();
CreateMap<WishlistItemDto, WishListItemCreationDto>().ReverseMap();
CreateMap<WishlistItem, WishlistItemDto>()
.ForMember(wi => wi.ProductDetailId, opt => opt.MapFrom(f => f.ProductDetailsId))
.ForMember(wi => wi.ProductDetails, opt => opt.MapFrom(f => f.ProductDetails))
.ReverseMap();
}
everything is okay, but you missed inner mapping of your classes.
What the error says:
Mapping types:
ProductDetailsDtoWithPrimaryImage -> ProductDetails
SimpleWebApi.Controllers.ProductDetailsDtoWithPrimaryImage -> SimpleWebApi.Controllers.ProductDetails
Add additional mapping in your constructor WishlistItemProfile
CreateMap<ProductDetails, ProductDetailsDtoWithPrimaryImage>().ReverseMap();
And it starts works perfect
I am trying to find a simple way using AutoMapper to return all companies that are linked to a specific User Id in a many-to-many relationship scenario. I followed the SO Automapper many to many mapping but I get the error message "Expression of type 'System.Collections.Generic.List`1[API.Entities.CompanySetting]' cannot be used for parameter of type 'System.Linq.IQueryable" when trying to follow the logic.
My AppUser entity:
public class AppUser
{
public int Id { get; set; }
public string UserName { get; set; }
public virtual ICollection<AppUserCompanySetting> AppUserCompanySettings { get; set; } = new List<AppUserCompanySetting>();
}
My CompanySetting entity:
public class CompanySetting
{
public int Id { get; set; }
public string CompanyName { get; set; }
public string CompanyRegistrationNumber { get; set; }
public bool isActive { get; set; }
public bool isArchived { get; set; }
public virtual ICollection<AppUserCompanySetting> AppUserCompanySettings { get; set; } = new List<AppUserCompanySetting>();
}
And I have the Join table
public class AppUserCompanySetting
{
public int AppUserId { get; set; }
public virtual AppUser AppUser { get; set; }
public int CompanySettingsId { get; set; }
public virtual CompanySetting CompanySettings { get; set; }
}
I then created a CompanySettingDto
public class CompanySettingDto
{
public int Id { get; set; }
public string CompanyName { get; set; }
public string CompanyRegistrationNumber { get; set; }
public bool isActive { get; set; }
public bool isArchived { get; set; }
}
And a MemberDto:
public class MemberDto
{
public int Id { get; set; }
public string Username { get; set; }
public string PhotoUrl { get; set; }
public string KnownAs { get; set; }
public int TimeActive { get; set; }
public DateTime LastActive {get; set;}
public ICollection<PhotoDto> Photos { get; set; }
public ICollection<CompanySettingDto> CompanyInformation { get; set; }
}
I then tried Automapper to bring the relationships between the User and the Company Information I require:
public class AutoMapperProfiles : Profile
{
public AutoMapperProfiles()
{
CreateMap<AppUser, MemberDto>()
.ForMember(dest => dest.CompanyInformation, opt => opt.MapFrom(x => x.AppUserCompanySettings.Select(y => y.CompanySettings).ToList()))
CreateMap<CompanySetting, CompanySettingDto>();
}
}
I am writing an API call to get all companies that are linked to a specific UserId.
public async Task<IEnumerable<MemberDto>> GetCompaniesByUserIdAsync(int userId)
{
return await _context.Users
.Where(x => x.Id == userId)
.ProjectTo<MemberDto>(_mapper.ConfigurationProvider)
.ToListAsync();
}
I am using ASP.NET MVC 4 code first pattern for database layer. I have a many to many relationship between UserProfile and Task. When I try to add a task to the the collection of tasks of a user, it's added but if I try to query it and see if it's there it's not showing up.
My model:
public class UserProfile
{
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int UserId { get; set; }
public string UserName { get; set; }
public string FirstName { get; set; }
public string SirName { get; set; }
public string Position { get; set; }
public string Email { get; set; }
public ICollection<TaskModels> Tasks {get; set; }
public bool? isActive { get; set; }
public UserProfile()
{
Tasks = new HashSet<TaskModels>();
}
}
public class TaskModels
{
public int Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public DateTime? StartDate { get; set; }
public DateTime? EndDate { get; set; }
public ICollection<UserProfile> Employees { get; set; }
public int TimeNeeded { get; set; }
public int TimeWorked { get; set; }
public string Status { get; set; }
public bool isActive { get; set; }
public TaskModels()
{
Employees = new HashSet<UserProfile>();
}
}
public class WorkLogModels
{
public int Id { get; set; }
public UserProfile Author { get; set; }
public DateTime TimeBeganWorking { get; set; }
public int TimeWorkedOn { get; set; }
public TaskModels Task { get; set; }
public string Description { get; set; }
}
public class TimeTrackerDb : DbContext
{
public TimeTrackerDb() : base("DefaultConnection")
{
}
public DbSet<UserProfile> UserProfiles { get; set; }
public DbSet<TaskModels> Tasks { get; set; }
public DbSet<WorkLogModels> WorkLogs { get; set; }
}
I try to check if a UserProfile already exists in a Task's Employees list and it's always empty.
[HttpPost]
public ActionResult Create(WorkLogModels worklogmodels)
{
var tasks = db.Tasks.Where(x => x.Name == worklogmodels.Task.Name).SingleOrDefault();
if (tasks == null)
{
return View(worklogmodels);
}
if (ModelState.IsValid)
{
var user = db.UserProfiles.Where(x => x.UserId == WebSecurity.CurrentUserId).FirstOrDefault();
var task = db.Tasks.Where(x => x.Name == worklogmodels.Task.Name).FirstOrDefault();
WorkLogModels log = new WorkLogModels();
log.Description = worklogmodels.Description;
log.TimeBeganWorking = worklogmodels.TimeBeganWorking;
log.TimeWorkedOn = worklogmodels.TimeWorkedOn;
log.Author = user;
log.Task = task;
db.WorkLogs.Add(log);
if (!db.UserProfiles.Where(x => x.UserId == WebSecurity.CurrentUserId).First().Tasks.Any(x=> x.Name == worklogmodels.Task.Name))
{
db.UserProfiles.Where(x => x.UserId == WebSecurity.CurrentUserId).FirstOrDefault().Tasks.Add(task);
db.Tasks.Where(x => x.Name == worklogmodels.Task.Name).FirstOrDefault().Employees.Add(user);
}
db.SaveChanges();
return RedirectToAction("Index");
}
return View(worklogmodels);
}
I've been fighting with this for two days now.
Any help will be greatly appreciated
EDIT:
I am not sure if I made myself clear. In the Crate action for the WorkLog Controller I am trying to put the current user in the current task's collection and vice versa. It works correctly the first time, but then if I do it again it fails to skip the if statement and tries to add it once again and throws an exception : System.Data.SqlClient.SqlException. It's trying to add the same record to the intermediate table.