HotChocolate returns ignored field - c#

I have a user object, where i have created an ObjectType to ignore the Password field as it is genearlly not a good idea to expose that in my API :) However HotChocolate still returns the password field in the response.
Account.cs
public class Account {
[Key]
public string Id { get; set; }
[Required]
[StringLength(250)]
public string Email { get; set; }
[Required]
[StringLength(512)]
public string Password { get; set; }
[Required]
[Range(0, 2)]
// 0 = Landlord, 1 = Tenant, 2 = Maintenace
public int AccountType { get; set; }
[Required]
[StringLength(150)]
public string Name { get; set; }
[Required]
public long CreatedMilliseconds { get; set; }
[Required]
public long UpdatedMilliseconds { get; set; }
[Required]
public long LastSeenMilliseconds { get; set; }
}
public class AccountType : ObjectType<Account>
{
protected override void Configure(IObjectTypeDescriptor<Account> descriptor)
{
descriptor.Ignore(f => f.Password);
}
}
AccountQuery.cs
[ExtendObjectType(typeof(Query))]
public class AccountQuery {
private readonly Logger log = LogManager.GetCurrentClassLogger();
[Authorize]
public Account GetMe(ClaimsPrincipal claimsPrincipal, [Service] DataContext context) {
string userId = AuthHelper.GetUserId(claimsPrincipal);
return context.Accounts.Where(x => userId == x.Id).FirstOrDefault();
}
}
My program.cs
// Add GraphQL services
builder.Services
.AddHttpContextAccessor()
.AddDbContext<DataContext>()
.AddGraphQLServer()
.AddAuthorization()
.AddQueryType<Query>()
.AddMutationType<Mutations>()
.AddTypeExtension<AccountMutations>()
.AddTypeExtension<AccountQuery>();

You can use the [GraphQLIgnore] attribute as described here.
[GraphQLIgnore]
public string Password { get; set; }

Related

Linq2db AssociationAttribute implementation returns an error

I have been trying to get related data by using Linq2db LoadWith extension method. My purpose is getting a user's posts by using LoadWith extension method.
It returns an error that says like this.
LinqToDB.Linq.LinqException: 'Expression 'Param_0.CreatedBy' is not a Field.' but Post entity class has a property that is called CreatedBy.
Here is my AppUser class.
public class AppUser : BaseEntity, IAppUser
{
[Required, Identity]
[Key]
public new int Id { get; set; }
[Required]
[ForeignKey("UserDetail")]
public int DetailId { get; set; }
[LinqToDBAssociation.Association(ThisKey = nameof(DetailId), OtherKey = nameof(AppUserDetail.Id), CanBeNull = true, Relationship = Relationship.OneToOne)]
public virtual AppUserDetail UserDetail { get; set; }
public string UserName { get; set; }
public string NormalizedUserName { get; set; }
public string PasswordHash { get; set; }
public bool EmailConfirmed { get; set; }
public string Email { get; set; }
public string NormalizedEmail { get; set; }
public DateTimeOffset? LockoutEnd { get; set; }
public int AccessFailedCount { get; set; }
public bool LockoutEnabled { get; set; }
public string PhoneNumber { get; set; }
public bool PhoneNumberConfirmed { get; set; }
public string SecurityStamp { get; set; }
public bool TwoFactorEnabled { get; set; }
public string ConcurrencyStamp { get; set; }
[LinqToDBAssociation.Association(ThisKey = nameof(Id), OtherKey = nameof(Post.CreatedBy), CanBeNull = true)]
public virtual IEnumerable<Post> UserPosts { get; set; }
}
Here is my Post class.
public class Post : BaseEntity
{
public Post()
{
PostImages = new HashSet<PostImage>();
PostComments = new HashSet<PostComment>();
PostVideos = new HashSet<PostVideo>();
}
public string Text { get; set; }
public int? PostType { get; set; }
public virtual ICollection<PostComment> PostComments { get; set; }
public virtual ICollection<PostImage> PostImages { get; set; }
public virtual ICollection<PostVideo> PostVideos { get; set; }
}
Here is my BaseEntity class.
public class BaseEntity : IEntity
{
public int Id { get; set; }
[ForeignKey("CreatedUser")] //By using CreatedUser integration, an owner of post,postComment,postLike that has been created, can be found easily thanks to it.
public virtual int? CreatedBy { get; set; }
public DateTime CreatedDate { get; set; }
[ForeignKey("ModifiedUser")] //ModifiedUser can be used in AdminUI.
public int? ModifiedBy { get; set; }
public DateTime? ModifiedDate { get; set; }
public int? StatusId { get; set; } //This can be Enumerations.
public BaseEntity()
{
CreatedDate = DateTime.Now;
}
public virtual AppUser CreatedUser { get; set; }
public virtual AppUser ModifiedUser { get; set; }
}
This LoadWith extension method returns that error.
var appUser = _appUserRepository.Table.LoadWith(p => p.UserPosts).FirstOrDefault(x => x.UserName == userName);
If you would like to see the project, you can check here;
https://github.com/dogaanismail/DevPlatform
How can I handle it ?
Best Regards
I suppose you need to add [LinqToDB.Mapping.Column] attribute to your properties or set [Table(IsColumnAttributeRequired = false)] for whole entity.
I encountered the same exception and found a solution at this issue in the library repository.

web api returning no response but data is formed at return

The GetPlaces method should return all users with their shares(homes), but I keep getting no response when I try to include the Shares.
The API gets called and it gets all data but when I try to return the data back,then I get no response.
It's not only that API call but every time I want to include another table from database, I get the same response. I am testing it with Postman
public class PlaceController : ControllerBase
{
PlaceService _PlaceService;
UserService _UserService;
ApplicationDbContext _db;
public PlaceController(PlaceService PlaceServicea, UserService _UserServicea, ApplicationDbContext db)
{
_db = db;
_PlaceService = PlaceServicea;
_UserService = _UserServicea;
}
//get all places
[HttpGet]
[Route("all")]
public async Task<ActionResult> GetPlaces()
{
var usersWithShares = await _db.Set<User>().Include(x => x.Shares).ToListAsync();
return Ok(usersWithShares);
// return Ok(await _PlaceService.GetAll());
}
}
This is my entity User
public class User
{
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 long PhoneNumber { get; set; }
public DateTime BirthDate { get; set; }
public string Token { get; internal set; }
public ICollection<Place> Shares { get; set; }
}
and this is my Entity place
public class Place
{
public int Id { get; set; }
public int Rooms { get; set; }
public int Garage { get; set; }
public bool Garden { get; set; }
public int Bathrooms { get; set; }
public int Toilet { get; set; }
public int Kitchen { get; set; }
public int LivingRoom { get; set; }
public string Description { get; set; }
public decimal Price { get; set; }
public User User { get; set; }
public Adres Adres { get; set; }
public ICollection<PlacePicture> PlacePictures { get; set; }
}
and this is my ConfigureServices
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<ApplicationDbContext>(
options => options.UseSqlServer(Configuration.GetConnectionString("Homesharing"))
);
// configure DI for application services
services.AddScoped<UserService>();
services.AddScoped<PlaceService>();
}
See image for more

How to connect Asp.Nets database with my own context?

I'm trying to build an application in Mvc with Individual User Accounts, and I'm trying to connect the automatically generated database with my own context.
The problem I have when I trying to create a view of my Create method I get this errormessage:
There was an error running the selected code generator: 'Unable to
retrieve metadata for 'Projekt_Dejtingsida.Models.Messages' is not
valid. The navigation property 'ApplicationUser' was not found on the
dependent type 'Projekt_Dejtsida.Models.Messages'. The Name value
should be a valid navigation property name.
Please help a beginner out!
Here are the models I'm using:
I have already tried the protected override void OnModelCreating(DbModelBuilder modelBuilder) method, but it didn't work...
public class Messages {
[Key, ForeignKey("ApplicationUser")]
public string Id { get; set; }
[Key]
public int MessageId { get; set; }
public virtual ApplicationUser Sender { get; set; }
public virtual ApplicationUser Receiver { get; set; }
[Required(AllowEmptyStrings = false, ErrorMessage = "You can't send a message without a content")]
[StringLength(300, MinimumLength = 3, ErrorMessage = "Your message should be between 3 and 300 characters")]
public string MessageContent { get; set; }
}
public class FriendRequests {
public string UserId { get; set; }
[Key]
public int RequestId { get; set; }
public virtual ApplicationUser RequestTo { get; set; }
public virtual ApplicationUser RequestFrom { get; set; }
public bool Confirmed { get; set; }
}
public class Profile {
[Key]
public string UserId { get; set; }
public byte[] ProfilePicture { get; set; }
public string Firstname { get; set; }
public int Age { get; set; }
public string Gender { get; set; }
public string City { get; set; }
public string About { get; set; }
public virtual ICollection<Messages> MyMessages { get; set; }
}
Here is the DbContext:
public class DatesiteContext : DbContext {
public DatesiteContext() : base() { }
public DbSet<FriendRequests> Requests { get; set; }
public DbSet<Messages> Messages { get; set; }
public DbSet<Profile> Profiles { get; set; }
}
Here is the MessageController
[Authorize]
public class MessageController : Controller
{
// GET: Message
public ActionResult Index()
{
var db = new DatesiteContext();
var userId = User.Identity.GetUserId();
var msgs = db.Messages.FirstOrDefault(m => m.Id == userId);
return View(new MessageViewModel {
Sender = msgs.Sender,
Receiver = msgs.Receiver,
MessageContent = msgs.MessageContent
});
}
public ActionResult Create(MessageViewModel model) {
DatesiteContext db = new DatesiteContext();
var userId = User.Identity.GetUserId();
var msgs = db.Messages.FirstOrDefault(m => m.Id == userId);
if (msgs == null) {
db.Messages.Add(new Messages {
Id = userId,
Sender = msgs.Sender,
Receiver = msgs.Receiver,
MessageContent = msgs.MessageContent
});
} else {
msgs.Sender = model.Sender;
msgs.Receiver = model.Receiver;
msgs.MessageContent = model.MessageContent;
}
db.SaveChanges();
return RedirectToAction("Index", "Profile");
}
}

The entity type 'System.Collections.Generic.IEnumerable`1[SomeModel]' provided for the argument 'clrType' must be a reference type

I'm getting the error message
The entity type 'System.Collections.Generic.IEnumerable`1[SomeModel]' provided for the argument 'clrType' must be a reference type.
When I try to do add-migration. I have no idea what and where the problem is here.
I don't know what is wrong with the UserRequest class.
I saw some similar questions, but their problem was with inherited controllers and similar.
Thank you! Any help is welcome!
public class UserRequest
{
[ScaffoldColumn(false)]
[System.ComponentModel.DataAnnotations.Schema.DatabaseGenerated(System.ComponentModel.DataAnnotations.Schema.DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
public int UserAccountId { get; set; }
public RequestCode RCode { get; set; }
public string CodeText { get; set; }
}
public class UserAccount
{
[ScaffoldColumn(false)]
[System.ComponentModel.DataAnnotations.Schema.DatabaseGenerated(System.ComponentModel.DataAnnotations.Schema.DatabaseGeneratedOption.Identity)]
public int UserAccountId { get; set; }
[Required(ErrorMessage = "First Name is required.")]
public string FirstName { get; set; }
[Required(ErrorMessage = "Second Name is required.")]
public string LastName { get; set; }
[Required(ErrorMessage = "Email is required.")]
[RegularExpression(#"^([\w-\.]+)#((\[[0-9]{1,3]\.)|(([\w-]+\.)+))([a-zA-
Z{2,4}|[0-9]{1,3})(\]?)$",
ErrorMessage = "Please enter valid email.")]
public string Email { get; set; }
[Required(ErrorMessage = "Username is required.")]
public string UserName { get; set; }
[Required(ErrorMessage = "Password is required.")]
[DataType(DataType.Password)]
public string Password { get; set; }
[Compare("Password", ErrorMessage = "Please confirm your password.")]
[DataType(DataType.Password)]
public string ConfirmPassword { get; set; }
public Role MyRole { get; set; }
public UserAccount()
{
MyRole = Role.Customer;
}
}
public class Administrator : UserAccount
{
public IEnumerable<UserRequest> ReceievedRequests { get; set; }
}
public class Customer : UserAccount
{
public int Spent { get; set; }
public ShoppingCart Cart { get; set; }
public virtual IEnumerable<UserRequest> UserRequests { get; set; }
}
DataAccessLayer:
public class TalonContext : DbContext
{
public TalonContext() { }
public TalonContext(DbContextOptions<TalonContext> options) :
base(options) { }
public DbSet<UserAccount> Users { get; set; }
public DbSet<UserRequest> Requests { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Administrator>()
.HasMany(r => r.ReceievedRequests);
//modelBuilder.Entity<Customer>()
// .HasOne(r => r.UserRequests);
modelBuilder.Entity<Customer>() // <--fixed
.HasMany(r => r.UserRequests);
modelBuilder.Entity<UserRequest>()
.HasAlternateKey(k => k.UserAccountId);
}
}

EF 4: System.Data.Entity.Edm.EdmEntityType: Name: Each type name in a schema must be unique

I want to use EF code first approach.
I have read this post:
http://weblogs.asp.net/scottgu/archive/2010/07/16/code-first-development-with-entity-framework-4.aspx
and created my BL classes
public class AppData
{
public string Id { get; set; }
public string Url { get; set; }
public AppData_OptionsDialog OptionsDialog { get; set; }
public AppData_Compatibility Compatibility { get; set; }
}
public class AppData_Compatibility
{
public int Id { get; set; }
public string Platform { get; set; }
public string MaxVersion { get; set; }
}
public class AppData_OptionsDialog
{
public int Id { get; set; }
public string DisplayName { get; set; }
public string AppDesc { get; set; }
public string PrivacyPolicyUrl { get; set; }
public string TermsOfUseUrl { get; set; }
}
public class AppsDataContext : System.Data.Entity.DbContext
{
public AppsDataContext() : base("MaMDB") { }
public DbSet<Conduit.Mam.Common.BlData.AppsData.AppData> AppsData { get; set; }
public DbSet<Conduit.Mam.Common.BlData.AppsData.AppData_Compatibility> AppData_Compatibilities { get; set; }
public DbSet<Conduit.Mam.Common.BlData.AppsData.AppData_OptionsDialog> AppData_OptionsDialogs { get; set; }
}
I have created corrisponding tables in the DB.
I understand EF uses convention over configuration.
So is it magically maps the classes to the DB? no need to generate an em
I try to execute a test on of the methods:
public IList<Conduit.Mam.Common.BlData.AppsData.AppData> GetAll()
{
var apps = from app in AppsDataContext.AppsData
select app;
return apps.ToList();
}
but get the following error:
One or more validation errors were detected during model generation:
\tSystem.Data.Entity.Edm.EdmEntityType: Name: Each type name in a
schema must be unique. Type name 'AppData_OptionsDialog' is already
defined. \tSystem.Data.Entity.Edm.EdmEntityType: Name: Each type name
in a schema must be unique. Type name 'AppData_Compatibility' is
already defined.
I have seen this answer, but it didn't help me
Entity Framework error - "The EntityContainer name must be unique"
I think I know what the problem is, even though this is incredibly old, I'm running across the same problem now, it seems EF doesn't like it when you have:
public class User_Roles {
public bool Admin { get; set; }
public bool Moderator { get; set; }
public virtual User User { get; set; }
}
public class User {
public Guid Id { get; set; }
public string Username { get; set; }
public string Salt { get; set; }
public string Password { get; set; }
public virtual User_Roles Roles { get; set; }
}
In this case, either User_Roles needs to be renamed or the Roles property in User needs to be renamed, as so:
public class URoles {
public bool Admin { get; set; }
public bool Moderator { get; set; }
public virtual User User { get; set; }
}
public class User {
public Guid Id { get; set; }
public string Username { get; set; }
public string Salt { get; set; }
public string Password { get; set; }
public virtual URoles Roles { get; set; }
}
or you could simply change the "Roles" property in User:
public class User_Roles {
public bool Admin { get; set; }
public bool Moderator { get; set; }
public virtual User User { get; set; }
}
public class User {
public Guid Id { get; set; }
public string Username { get; set; }
public string Salt { get; set; }
public string Password { get; set; }
public virtual User_Roles URoles { get; set; }
}
in your case, this is happening on:
public AppData_OptionsDialog OptionsDialog { get; set; }
public AppData_Compatibility Compatibility { get; set; }
Either rename the class, or rename the properties.

Categories

Resources