Prisma schema - Build up a custom object from a relation - next.js

Can I build a custom object using a relation, and the properties that it references?
For example, if I have two models like this, where User is populated during authentication:
model User {
id String #id #default(cuid()) #map("_id")
name String?
email String? #unique
}
model Post {
id String #id #default(auto()) #map("_id") #db.ObjectId
title String
description String
authorId String
authorEmail String
authorName String
user User #relation(fields: [authorId, authorEmail, authorName], references: [id, email, name])
}
This will take the user details and push them, individually, into authorId, authorName and authorEmail. What I would like is some way of loading them into an embedded document called author, like so:
model Post {
id String #id #default(auto()) #map("_id") #db.ObjectId
title String
description String
author Author
user User #relation(fields: [author], references: [id, email, name])
}
type Author {
id String
name String
email String
}
Is this at all possible? I feel like I've tried everything.

Related

GraphQL SPQR - How to get the list of the fields were requested by client using a query

is there a way to retrieve the list of the fields were requested in a GraphQL query by a client?
Lets assume I have the following types:
type Book {
isbn: String
title: String
genre: String
author: Author
}
type Author {
name: String
surname: String
age: Int
}
Is there a way on Java side inside a method annotated with #GraphQLQuery to know the fields were requested by the client?
For example, having the following queries:
query {
book ( isbn = "12345" ) {
title
genre
}
}
query {
book ( isbn = "12345" ) {
title
author {
name
surname
}
}
}
I can know the first query requested the fields title and genre of Book
and the second required title from Book and also name and surname of the Author ?
Thanks
Massimo
You can obtain this info via #GraphQLEnvironment. If you just need the immediate subfields, you can inject the names like this:
#GraphQLQuery
public Book book(String isbn, #GraphQLEnvironment Set<String> subfields) {
...
}
If you want all the subfields, or other selection info, you can inject ResolutionEnvironment and get DataFetcherEnvironment from there. That in turn gives you access to the whole SelectionSet.
#GraphQLQuery
public Book book(String isbn, #GraphQLEnvironment ResolutionEnvironment env) {
DataFetchingFieldSelectionSet selection = env.dataFetchingEnvironment.getSelectionSet();
...
}

Need to list out members in a group to which current user belongs toin flutter

I have a flutter app in which each user belongs to only one group
my user model is as follow
class OurUser {
String uid;
String email;
String fullName;
Timestamp accountCreated;
String groupId;
OurUser({
this.uid,
this.email,
this.fullName,
this.accountCreated,
this.groupId,
});
}?
My Group model is as follows
class OurGroup {
String id;
String name;
String leader;
List<String> members;
OurGroup(
{
this.id,
this.name,
this.leader,
this.members,
});
}
I want to list down the members in group model based on current user.
Any suggestions on how to go forward
So you must be having a List say _allGroups. To get the members you get the group first using a conditional like
userGroup = _allGroups.firstWhere((group) => currentUser.groupID == group.id)
This will give you the currentUser's group. Now you can do userGroup.members to get the members now.
members = userGroup.members;
I do not know your use case but ideally, members should of Type OurUser not String. Because members are users too right.

ASP.NET MVC password validation with hash

So I want to add my Custom Hash into my password, but it got stuck because my own validation
My Model:
public class ms_user
{
[Required(ErrorMessage = "Please Input your Login Email")]
[DataType(DataType.EmailAddress)]
public object user_id { get; set; }
[Required(ErrorMessage = "Please Input your Password")]
// Validation at least 1 uppercase & 1 number, password lenght must be greater then 6 and lower then 12, with no Special Character
[RegularExpression(#"^(?=.*\d)(?=.*[A-Z])[a-zA-Z0-9](.{6,12})$", ErrorMessage = "Error, Wrong Password Format")]
public object password { get; set; }
}
Sample:
Password Inputed : Admin123 // Pass Validation
HashedPassword Output: l92Vi3c2Af7Oftgy7JqYJKR8isYXef8pIOqvMzjrN6rnRct6W6UuDzv0YRCOudPPXnC69Gj2J4igXZWH1WRz9C19abN4UWKSqX8d0TxA+0IvXJAvzoksaEWPQm56gy/l:9KZQeh3nB9apjy81V/FvfU // After i hashed my password,
My Project pass the Password Validation, but on the db.SaveChanges(); it return error, because the Password validation
is there any solution?? i prefer not to add javascript validation...
Thx
Change the Datatype of Password column to nvarchar(MAX) in your User table to accomodate the Hashed Password.
I faced this exact same problem, because I updated the password length in database to nvarchar(max) but didn't update the model in visual studio after that. So Update the Model and it should fix that.

How to implement Asp.net membership in my developed web application

I am working on a web application. I already completed it. But when I gone through security audit, I came to know that I should use asp.net membership for, login, password change, creating user, reset password etc.
So I stared using asp.net membership. I created a login page and it's working fine. I also got a database in my App_Data folder.
The problem is that I already have a database for my application where I have a user table which is having more fields than the table aspnet_Users. see the image below.
So please suggest me how to implement asp.net membership in my web application, as I need more fields in user table,
how to insert data along with my fields with the fields above mentioned in the above image, because I didn't fine any code through using asp.net membership. If I could got, I would surely make changes accordingly.
I mean how to merge this database and mine without any code.
I would also recommend that you use ASP.Net Identity as it is the framework for handling security.
However, if you are going to use simple membership, here is some code to help you "add fields" to your user table.
First, create your user model with all needed properties like so:
[Table("User")]
public class User
{
public int UserId { get; set; }
[Display(Name = "User name")]
[Required(ErrorMessage = "Usernname is required.")]
[StringLength(80, ErrorMessage = "Please enter a value no more than 80 characters.")]
public string UserName { get; set; }
[Display(Name = "First Name")]
[Required(ErrorMessage = "First name is required.")]
[StringLength(80, ErrorMessage = "Please enter a value no more than 80 characters.")]
public string FirstName { get; set; }
[Display(Name = "Last Name")]
[Required(ErrorMessage = "Last name is required.")]
[StringLength(80, ErrorMessage = "Please enter a value no more than 80 characters.")]
public string LastName { get; set; }
[Required]
[Display(Name = "Email")]
[DataType(DataType.EmailAddress)]
[StringLength(254, ErrorMessage = "Please enter a value no more than 254 characters.")]
public string Email { get; set; }
//Add other properties... etc
}
Next, write the code to initialize your database. You probably have this code somewhere in the InitializeSimpleMembershipAttribute.cs file. Or, you can take it out from there and put in on your Application Start method. Here is the piece you need to modify:
WebSecurity.InitializeDatabaseConnection("YourDBConnectionName", "User", "UserId", "UserName", autoCreateTables: true);
//Modify the above properties if you change your user model to be a different table name
See reference to InitializeDatabaseConnection.
Now, when you want to create a user, call the following method:
WebSecurity.CreateUserAndAccount(user.UserName, user.Password, new { user.Email, user.FirstName, user.LastName });
//user is the User object that has all your data populated from some type of input
Reference to create user account: CreateUserAndAccount
The one you are trying to implement is legacy ASP.Net Membership Provider created using aspnet_regsql.exe. Do not use it, because it has been deprecated long time ago.
Currently, Microsoft offers 3 types of Memberships -
ASP.NET Universal Providers
Simple Membership Provider
ASP.NET Identity
Since your application is new and doesn't have existing users, you want to use -
ASP.NET Identity 2
The problem is that I already have a database for my application where
I have a user table which is having more fields than the table
aspnet_Users.
ASP.Net Identity lets you create custom fields in User table.
FYI: Make sure you use Version 2.

DropDownListFor "the value is invalid" when setting navigation property

I am attempting to set a navigation property (foreign key) based on the return value from a DropDownList.
I have the following data model:
(Some properties and details omitted for the sake of brevity).
An invite, which has a Guid Id and a collection of guests.
public class Invite
{
public Guid InviteId { get; set; }
public virtual ICollection<Guest> Guests { get; set; }
}
A guest, with an Invite property linking it to invite.
public class Guest
{
public virtual Invite Invite { get; set; }
}
In my DataInitaliser I can correctly build these objects and they are sent to the database, for example:
new Invite()
{
InviteId = Guid.NewGuid(),
Name = "Bloggs",
AllDay = false,
Guests = new List<Guest>()
{
new Guest() { GuestId = Guid.NewGuid(), FirstName = "Joe", LastName = "Bloggs", Vip = false},
}
};
In my GuestController I build the list of possible invites and add it to the ViewBag for presenting in the view.
void PopulateInvite(object invite)
{
var query = db.Invites.Select(i => i).OrderBy(i => i.Name).ToList();
ViewBag.Invites = new SelectList(query, "InviteId", "Name", invite);
}
I present the list of objects in the Guest View like so:
#model Models.Guest
<div class="form-group">
#Html.LabelFor(model => model.Invite, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownListFor(model => model.Invite, (IEnumerable<SelectListItem>)ViewBag.Invites, String.Empty)
#Html.ValidationMessageFor(model => model.Invite)
</div>
</div>
This correctly displays the expected values from the database.
The problem occurs when I post the values back to the GuestController.
The Post function for the create is pretty much the standard scaffold.
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Create([Bind(Include="GuestId,FirstName,LastName,Vegetarian,Attending,Vip,Invite")] Guest guest)
{
if (ModelState.IsValid)
{
guest.GuestId = Guid.NewGuid();
db.Guests.Add(guest);
await db.SaveChangesAsync();
return RedirectToAction("Index");
}
this.PopulateInvite(guest.Invite);
return View(guest);
}
I've dug into the cause a little bit here and I think I understand the underlying problem. My function PopulateInvite, places InviteId into the collection which is a Guid, this is returned as a String (not a Guid?) which cannot be converted into an Invite object.
"The parameter conversion from type 'System.String' to type 'Models.Invite' failed because no type converter can convert between these types."
I did try changing my PopulateInvite collection so its populated with an actual Invite object like so:
void PopulateInvite(object invite)
{
var query = db.Invites.Select(i => i).OrderBy(i => i.Name).ToList().Select(i =>
{
return new
{
Invite = new Invite() { InviteId = i.InviteId },
Name = i.Name
};
});
ViewBag.Invites = new SelectList(query, "Invite", "Name", invite);
}
However this also fails with the same error as above, confusingly I am returned a String representation of the object, instead of the actual object itself.
ModelState["Invite"].Value.RawValue
{string[1]}
[0]: "Models.Invite"
So...what is the correct way to set way to set the navigation property based on the post from the form?
Should I act before ModelState.IsValid to change the Guid into an actual Invite object?
As this tutorial from asp.net suggests, should I add a property to hold an InviteId, instead of using an invite object? In the sample Department is unused so I don't really understand why it has been added - am I missing something?
public class Course
{
public int DepartmentID { get; set; }
public virtual Department Department { get; set; }
}
Some other better method?
You can't bind a complex component like model.Invite in a DropDownListFor:
#Html.DropDownListFor(model => model.Invite, (IEnumerable<SelectListItem>)ViewBag.Invites, String.Empty
You need to put a singular value like a int from ID. Try to replace the code above to:
#Html.DropDownListFor(model => model.Invite.InviteID, (IEnumerable<SelectListItem>)ViewBag.Invites, String.Empty
Well, the answer was in the actual tutorial I linked in the question. I needed to add an InviteId field to act as the foreign key then the actual object acts as the navigation property, as explained below both are required (not just one as I was using it).
Creating an Entity Framework Data Model for an ASP.NET MVC Application
The StudentID property is a foreign key, and the corresponding
navigation property is Student. An Enrollment entity is associated
with one Student entity, so the property can only hold a single
Student entity (unlike the Student.Enrollments navigation property you
saw earlier, which can hold multiple Enrollment entities).
The CourseID property is a foreign key, and the corresponding
navigation property is Course. An Enrollment entity is associated with
one Course entity.
Entity Framework interprets a property as a foreign key property if
it's named (for
example, StudentID for the Student navigation property since the
Student entity's primary key is ID). Foreign key properties can also
be named the same simply (for example,
CourseID since the Course entity's primary key is CourseID).

Resources