How to add a repeated foreign key in the same model - asp.net-mvc

I am working in an ASP MVC project, which uses MvcScaffolding a lot, I have a project and a client model, the thing is that the project has to be relationed with client model in two ways (Billing client and Service Client, and both data are from same client model)
I have no idea how to do this, here are my models
Client Model
public class ClientsX
{
[Key]
public int idcliente { get; set; }
[Required(ErrorMessage = "A Legal ID is required")]
[StringLength(150)]
[Display(Name = "Company Name: ")]
public string CompanyName { get; set; }
[StringLength(150)]
[Display(Name = "Legal ID: ")]
public string LegalID { get; set; }
[Required(ErrorMessage = "A Contact First Name is required")]
[StringLength(150)]
[Display(Name = "First Name: ")]
public string FirstName { get; set; }
[Required(ErrorMessage = "A Contact Last Name is required")]
[StringLength(150)]
[Display(Name = "Last Name: ")]
public string LastName { get; set; }
[Required(ErrorMessage = "A Contact Email Address is required")]
[DataType(DataType.EmailAddress, ErrorMessage = "Please enter a valid email address")]
[EmailAddress(ErrorMessage = "Please enter a valid email address")]
[StringLength(150)]
[Display(Name = "Email Address: ")]
public string email { get; set; }
[Required(ErrorMessage = "A Phone Number is required")]
[StringLength(15)]
[Display(Name = "Phone: ")]
public string phone { get; set; }
[Required(ErrorMessage = "An Username is required")]
[MaxLength(50, ErrorMessage = "Your Username cannot exceed 50 characters")]
[RegularExpression(#"^[\S]*$", ErrorMessage = "No White spaces are Accepted")]
[Display(Name = "Username: ")]
public string username { get; set; }
[Required(ErrorMessage = "A Password is required")]
[DataType(DataType.Password)]
[Display(Name = "Password: ")]
public string password { get; set; }
}
Project Model
public class Project
{
[Key]
public int idProject { get; set; }
[Display(Name = "Billing Client")]
[Required(ErrorMessage = "This Field is required")]
public int ClientsXId { get; set; }
[Display(Name = "Client")]
[Required(ErrorMessage = "This Field is required")]
public int ClientsXId { get; set; }
[Display(Name = "Status")]
[Required(ErrorMessage = "This Field is required")]
public int estatusId { get; set; }
}
Yes, I know ClientsXId is repeated, but is on purpose, because I need to have the same data in the project model, but it gives me this error:
Error 5 The type 'SSMS_2._0._1.Models.Project' already contains a definition for 'ClientsXId' D:\PC\Visual Studio 2013\Projects\SSMS-2.0.1\SSMS-2.0.1\Models\ProjectModel.cs 99 20 SSMS_2._0._1
How can I make this work?

Related

Add Control to validate in ModelState manually

I have one scenario as mentioned below :
In my xyz.cshtml page, i have two form. and in xyz.cshtml.cs page i have one InputModel that contains Property for both form.
public class InputModel
{
[Required(ErrorMessage = "The Email field is required.")]
[EmailAddress(ErrorMessage = "Enter a valid email address.")]
[RegularExpression(
#"^[A-Za-z0-9](([_\.\-]?[a-zA-Z0-9]+)*)#([A-Za-z0-9]+)(([\.\-]?[a-zA-Z0-9]+)*)\.([A-Za-z]{2,})$",
ErrorMessage = "Enter a valid email address.")]
public string Email { get; set; }
[Required(ErrorMessage = "The Password field is required.")]
[DataType(DataType.Password)]
public string Password_ChangeEmail { get; set; }
[Required(ErrorMessage = "The OldPassword field is required.")]
[DataType(DataType.Password)]
public string OldPassword { get; set; }
[Required(ErrorMessage = "The New Password field is required.")]
[DataType(DataType.Password)]
[CustomPassword(8, 15, ErrorMessage = "The password is invalid.")]
public string Password { get; set; }
[Required(ErrorMessage = "The Confirm Password field is required.")]
[DataType(DataType.Password)]
[Compare("Password", ErrorMessage = "The passwords do not match.")]
public string ConfirmPassword { get; set; }
}
I am using first 2 property in one form and rest of the property in 2nd form.
Now, issue is when i am pressing Submit button from 1st form, it's validating 2nd form as well. So for the time i have used ModelState.Clear() . But if i am using this and i am not wrong it will stop validating all the property.
So, if you guys have any solution like, is it possible to control in ModelState manually for validate.
If i need to share anything else, please suggest.
Thanks
1) You could split the model into two, one model for each form and use them in the post actions for these forms.
public class LoginModel
{
[Required(ErrorMessage = "The Email field is required.")]
[EmailAddress(ErrorMessage = "Enter a valid email address.")]
[RegularExpression(
#"^[A-Za-z0-9](([_\.\-]?[a-zA-Z0-9]+)*)#([A-Za-z0-9]+)(([\.\-]?[a-zA-Z0-9]+)*)\.([A-Za-z]{2,})$",
ErrorMessage = "Enter a valid email address.")]
public string Email { get; set; }
[Required(ErrorMessage = "The Password field is required.")]
[DataType(DataType.Password)]
public string Password_ChangeEmail { get; set; }
}
public class ChangePasswordModel
{
[Required(ErrorMessage = "The OldPassword field is required.")]
[DataType(DataType.Password)]
public string OldPassword { get; set; }
[Required(ErrorMessage = "The New Password field is required.")]
[DataType(DataType.Password)]
[CustomPassword(8, 15, ErrorMessage = "The password is invalid.")]
public string Password { get; set; }
[Required(ErrorMessage = "The Confirm Password field is required.")]
[DataType(DataType.Password)]
[Compare("Password", ErrorMessage = "The passwords do not match.")]
public string ConfirmPassword { get; set; }
}
2) Create a combined model
public class InputModel
{
public LoginModel LoginModel { get; set; }
public ChangePasswordModel ChangePasswordModel { get; set; }
}
3) add two post actions
public IActionResult LoginPost(InputModel model)
{
...
return View("InputPage", model);
}
public IActionResult ChangePasswordPost(InputModel model)
{
...
return View("InputPage", model);
}
4) use the combined model in your cshtml page
#model InputModel
...
#using (Html.BeginForm("LoginPost", "Home")) {
#Html.TextBoxFor(m => m.LoginModel.Email)
<input type="submit" value="submit" />
}

How to define two classes for one DB table in MVC

I have one table np_user_dtls with 4 fields in sql server
user_name
user_last_name
arabic_name
nationality
In mvc i created a model class as below
public partial class np_user_dtls
{
[Display(Name = "First Name*")]
[Required(ErrorMessage = "First name is required.")]
public string user_name { get; set; }
[Required(ErrorMessage = "last name is required.")]
public string user_last_name { get; set; }
[Required(ErrorMessage = "arabic name is required.")]
public string arabic_name { get; set; }
[Required(ErrorMessage = "nationality is required.")]
public string nationality { get; set; }
}
and in context model i define the relationship between model class and db table as follow
public System.Data.Entity.DbSet<****.Models.np_user_dtls> np_user__dtls { get; set; }
now i need an another class in which arabic name is not mandatory
so i create a model like below
public partial class np_user_dtls_1
{
[Display(Name = "First Name*")]
[Required(ErrorMessage = "First name is required.")]
public string user_name { get; set; }
[Required(ErrorMessage = "last name is required.")]
public string user_last_name { get; set; }
[Required(ErrorMessage = "nationality is required.")]
public string nationality { get; set; }
}
but when i create an entry for this in db context like below
public System.Data.Entity.DbSet<****.Models.np_user_dtls_1> np_user__dtls { get; set; }
its giving me an error
The type ****.Models.***** already contains a definition for
np_user__dtls
is it not possible to define multiple model for a single table?
You can set one entity model for one table. then you can bind different view model with your entity model.
entity class.
public partial class np_user_dtls
{
public string user_name { get; set; }
public string user_last_name { get; set; }
public string arabic_name { get; set; }
public string nationality { get; set; }
}
you can use this class for database table.
public partial class np_user_dtls_response1
{
[Display(Name = "First Name*")]
[Required(ErrorMessage = "First name is required.")]
public string user_name { get; set; }
[Required(ErrorMessage = "last name is required.")]
public string user_last_name { get; set; }
[Required(ErrorMessage = "arabic name is required.")]
public string arabic_name { get; set; }
[Required(ErrorMessage = "nationality is required.")]
public string nationality { get; set; }
}
you can use this class as view model. accept request by this class. then map this class np_user_dtls and save information in db.
later you can use another view model class such as
public partial class np_user_dtls_response2
{
[Display(Name = "First Name*")]
[Required(ErrorMessage = "First name is required.")]
public string user_name { get; set; }
[Required(ErrorMessage = "last name is required.")]
public string user_last_name { get; set; }
[Required(ErrorMessage = "nationality is required.")]
public string nationality { get; set; }
}
bind this class again with class np_user_dtls and save information in db. In this you can use two kind of validation in application level save data in database. Previously you can set validation database level. thats why you cant set two class

Filtering errors in ValidationSummary

I want to Show particular errors in validation summary and disappear some errors like below:` public class LogOnModel
{
[Display(Name = "Email")]
public string Email { get; set; }
[Required(ErrorMessage = "Username must be entered.")]
[Display(Name = "Kullanıcı Adı")]
public string Username { get; set; }
[Required(ErrorMessage = "Password must be entered.")]
[DataType(DataType.Password)]
[Display(Name = "Parola")]
public string Password { get; set; }
}
How can I filter particular errors in ValidationSummary() ?

MVC 3 add more fields then provided to account controler

Can somebody please help me?
I want to add more fields to account controller than is provided. I want to see these fields in a table as well. I add fields in a Register class. And I am not sure about ID field I want to use auto increment but do not know how if I do not see a table. In normal database it will do automatically. Thanks.
my
Account model:
public class ChangePasswordModel
{
[Required]
[DataType(DataType.Password)]
[Display(Name = "Current password")]
public string OldPassword { get; set; }
[Required]
[StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)]
[DataType(DataType.Password)]
[Display(Name = "New password")]
public string NewPassword { get; set; }
[DataType(DataType.Password)]
[Display(Name = "Confirm new password")]
[Compare("NewPassword", ErrorMessage = "The new password and confirmation password do not match.")]
public string ConfirmPassword { get; set; }
}
public class LogOnModel
{
[Required]
[Display(Name = "User name")]
public string UserName { get; set; }
[Required]
[DataType(DataType.Password)]
[Display(Name = "Password")]
public string Password { get; set; }
[Display(Name = "Remember me?")]
public bool RememberMe { get; set; }
}
public class RegisterModel
{
[Required]
public int ID { get; }
[Required]
[DataType(DataType.Text)]
[Display(Name = "First Name")]
public string FirstName { get; set; }
[Required]
[DataType(DataType.Text)]
[Display(Name = "Last Name")]
public string LastName { get; set; }
[Required]
[DataType(DataType.PhoneNumber)]
[Display(Name = "Phone")]
public string Phone { get; set; }
[Required]
[DataType(DataType.Text)]
[Display(Name = "First line of address")]
public string Address { get; set; }
[DataType(DataType.Date)]
[Display(Name = "DOB => dd/mm/yyyy")]
public DateTime DateOfBirth { get; set; }
[Required]
[PostCode(ErrorMessage= "PostCode is not valid")]
[Display(Name = "Post Code")]
public string PostCode { get; set; }
[Required]
[Display(Name = "User name")]
public string UserName { get; set; }
[Required]
[DataType(DataType.EmailAddress)]
[Display(Name = "Email address")]
public string Email { get; set; }
[Required]
[StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)]
[DataType(DataType.Password)]
[Display(Name = "Password")]
public string Password { get; set; }
[DataType(DataType.Password)]
[Display(Name = "Confirm password")]
[Compare("Password", ErrorMessage = "The password and confirmation password do not match.")]
public string ConfirmPassword { get; set; }
}
public class PostCodeAttribute : RegularExpressionAttribute
{
public PostCodeAttribute()
: base(
#"([Gg][Ii][Rr] 0[Aa]{2})|((([A-Za-z][0-9]{1,2})|(([A-Za-z][A-Ha-
hJ-Yj-y][0-9]{1,2})|(([A-Za-z][0-9][A-Za-z])|([A-Za-z][A-Ha-hJ-
Yj-y][0-9]?[A-Za-z])))) {0,1}[0-9][A-Za-z]{2})")
{
ErrorMessage = "PostCode is invalid";
}
}
Then in AccountController I can create user which has same data fields in a table but Membership do not have this option only
Membership.CreateUser(model.UserName, model.Password, model.Email, null, null, true, null, out createStatus);
You might want to consider SimpleMembership (it's the future) and using your own schema, and then using NuGet to use it with MVC 3.
This is "classic" ASP.NET but should help
http://www.asp.net/web-forms/tutorials/security/membership/storing-additional-user-information-cs
(From here adding more fields to registration form using membership on MySql and MVC 3)

Problems with editing using a custom model

I have this data model:
public class User
{
public long UserID { get; set; }
[Required(ErrorMessage = "User name is required.")]
[MaxLength(50, ErrorMessage = "User name cannot be longer than 50 characters.")]
public string UserName { get; set; }
[Email]
[Required(ErrorMessage = "Email is required.")]
[MaxLength(100, ErrorMessage = "Email cannot be longer than 100 characters.")]
public string Email { get; set; }
[Required(ErrorMessage = "Password is required.")]
[StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)]
[DataType(DataType.Password)]
public string Password { get; set; }
[MaxLength(150, ErrorMessage = "Full name cannot be longer than 150 characters.")]
public string FullName { get; set; }
public int UserTypeID { get; set; }
public virtual UserType UserType { get; set; }
public virtual ICollection<Page> Pages { get; set; }
}
and I'm using this model to only edit some fields (password shouldn't be editable):
public class EditUserModel
{
public long UserID { get; set; }
[Required]
[Display(Name = "User name")]
public string UserName { get; set; }
[Email]
[Required(ErrorMessage = "Email is required.")]
[MaxLength(100, ErrorMessage = "Email cannot be longer than 100 characters.")]
public string Email { get; set; }
[DataType(DataType.Text)]
[Display(Name = "Full name")]
[MaxLength(150, ErrorMessage = "Full name cannot be longer than 150 characters.")]
public string FullName { get; set; }
public int UserTypeID { get; set; }
public virtual UserType UserType { get; set; }
}
but I'm confused on how to pass the EditUserModel to my data context to update it. Sorry if seems elementary, but I'm really stumped.
This is the auto-generated edit action that I modified:
[IsAdministrator]
[HttpPost]
public ActionResult Edit(EditUserModel user)
{
if (ModelState.IsValid)
{
db.Entry(user).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
ViewBag.UserTypeID = new SelectList(db.UserTypes, "UserTypeId", "Name", user.UserTypeID);
return View(user);
}
This is the line I'm having trouble with:
db.Entry(user).State = EntityState.Modified;
The reason I created a custom class was to avoid exposing the password from the view.
This can't work because you're trying to save view model.
You could use AutoMapper to rewrite data from view model to your data model. After that you should be able to save changes.
User userModel = Mapper.Map<EditUserModel, User>(user);
userModel = // todo: get password from database
// todo: attach your model to context and save changes
I'm using Entity Framework Code First and that approach works great.

Resources