There are two models
User
public class User
{
private const int NameLength = 200;
private const int EmailLength = 100;
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
[StringLength(NameLength)]
public string Name { get; set; }
[Required]
[EmailAddress]
[StringLength(EmailLength)]
public string Email { get; set; }
[Required]
[DataType(DataType.Password)]
[StringLength(200)]
public string Password { get; set; }
public string PasswordSalt { get; set; }
[Required]
[DefaultValue(UserType.User)]
public UserType Type { get; set; }
[DefaultValue(true)]
public bool IsActive { get; set; }
public virtual List<Task> Tasks { get; set; }
public User()
{
Tasks = new List<Task>();
}
}
[Flags]
public enum UserType
{
Admin = 0,
User = 1
}
and RegisterUserModel which I use to register user
public class RegisterUserModel
{
private const int NameLength = 200;
private const int EmailLength = 100;
private const int PasswordMinLength = 5;
private const int PasswordMaxLength = 20;
[Key]
public int Id { get; set; }
[Required]
[StringLength(NameLength)]
public string Name { get; set; }
[Required]
[EmailAddress]
[StringLength(EmailLength)]
public string Email { get; set; }
[Required]
[DataType(DataType.Password)]
[StringLength(PasswordMaxLength, MinimumLength = PasswordMinLength)]
public string Password { get; set; }
}
and this is method from my controller
[HttpPost]
[AjaxAction]
public ActionResult Registration(RegisterUserModel registerUser)
{
if (ModelState.IsValid)
{
if (!IsUserExist(registerUser.Email))
{
var crypto = new SimpleCrypto.PBKDF2();
var encrpPass = crypto.Compute(registerUser.Password);
var newUser = db.Users.Create();
newUser.Name = registerUser.Name;
newUser.Email = registerUser.Email;
newUser.Type = UserType.User;
newUser.IsActive = true;
newUser.Password = encrpPass;
newUser.PasswordSalt = crypto.Salt;
db.Users.Add(newUser);
db.SaveChanges();
FormsAuthentication.SetAuthCookie(newUser.Email, false);
return Json(new {status = "OK", message = "Success"}, JsonRequestBehavior.AllowGet);
}
return Json(new { status = "ERROR", message = "User already exists" }, JsonRequestBehavior.AllowGet);
}
return Json(new { status = "ERROR", message = "Data is incorrect" }, JsonRequestBehavior.AllowGet);
}
And I don't like I need to set values
newUser.Type = UserType.User;
newUser.IsActive = true;
in controller manually although I have these default values in my User model, I think it's not very good practice, but I don't know how to avoid it?
DefaultValueAttribute doesn't do what you think it does, namely, actually set an actual value on the property. If you want the property to have a default value, then you need a custom getter and setter:
private UserType? type;
public UserType Type
{
get { return type ?? UserType.User; }
set { type = value; }
}
In that scenario you can either use the properties to set the values for the User or you can create a constructor and set those properties inside..
If you don't like setting properties manually you can use a mapping tool such as AutoMapper (http://automapper.org/) to do the mapping for you.
Regards,
Related
I have a view that has add/edit, edit is working fine but for add I would like to set default values for type. Is there a way to do this in the view the cshtml file?
add view
#Html.Partial("RegimenReferences", new (ReferencesModel {Type = "defaultType}") )
edit view
#Html.Partial("RegimenReferences", (ReferencesModel)Model)
Model
public class ReferencesModel
{
public ReferencesModel()
{
}
public ReferencesModel(Reference reference)
{
this.Id = reference.Id;
this.Link = reference.Link;
this.Text = reference.Text;
this.Type = reference.Type;
this.Regimens = reference.Regimens;
this.GuidelineId = reference.GuidelineId;
this.SortOrder = reference.SortOrder;
}
public long Id { get; set; }
public string Link { get; set; }
public string Text { get; set; }
public string Type { get; set; }
public int Regimens { get; set; }
public Guid? GuidelineId { get; set; }
public int SortOrder { get; set; }
}
}
Are you wanting to set those types specifically in cshtml?
Could you create a new constructor for your model that takes in any fields you want to set with a default?
public class ReferencesModel
{
public ReferencesModel(string type = null)
{
Type = type;
}
public ReferencesModel(Reference reference)
{
this.Id = reference.Id;
this.Link = reference.Link;
this.Text = reference.Text;
this.Type = reference.Type;
this.Regimens = reference.Regimens;
this.GuidelineId = reference.GuidelineId;
this.SortOrder = reference.SortOrder;
}
public long Id { get; set; }
public string Link { get; set; }
public string Text { get; set; }
public string Type { get; set; }
public int Regimens { get; set; }
public Guid? GuidelineId { get; set; }
public int SortOrder { get; set; }
}
or just set a default value in the constructor/in variable declaration
public ReferencesModel()
{
Type = "default type";
}
public string Type = "default type";
I'm getting a "Cannot insert null into column" error from an unrelated table when trying to add a new record for the "original" table.
I have the following two (relevant) entities:
public class Complex
{
[Key]
public Guid Id { get; set; }
public string Name { get; set; }
public Guid OwnerId { get; set; }
[ForeignKey("OwnerId")]
public Owner Owner { get; set; }
public Guid AddressId { get; set; }
[ForeignKey("AddressId")]
public virtual Address Address { get; set; }
public virtual ICollection<Unit> Units { get; set; }
public virtual ICollection<StaffMember> StaffMembers { get; set; }
public Complex()
{
this.Id = System.Guid.NewGuid();
this.Units = new HashSet<Unit>();
this.StaffMembers = new HashSet<StaffMember>();
}
public void AddUnit(Unit unit)
{
Units.Add(unit);
}
public void AddStaff(StaffMember staffMember)
{
StaffMembers.Add(staffMember);
}
}
and
public class Owner
{
[Key]
public Guid Id { get; set; }
public string Name { get; set; }
public Guid ContactInfoId { get; set; }
[ForeignKey("ContactInfoId")]
public ContactInfo ContactInfo { get; set; }
public ICollection<StaffMember> Employees { get; set; }
public ICollection<Complex> Complexes { get; set; }
public Owner()
{
this.Id = System.Guid.NewGuid();
this.Employees = new HashSet<StaffMember>();
this.Complexes = new HashSet<Complex>();
}
public void AddEmployee(StaffMember employee)
{
Employees.Add(employee);
}
public void AddComplex(Complex complex)
{
Complexes.Add(complex);
}
}
I'm trying to add a new owner in the following code:
if (ModelState.IsValid)
{
Owner newOwner = new Owner();
ContactInfo newContactInfo = new ContactInfo();
Address newAddress = new Address();
newAddress.Address1 = viewModel.ContactInfo.Address.Address1;
newAddress.Address2 = viewModel.ContactInfo.Address.Address2;
newAddress.City = viewModel.ContactInfo.Address.City;
newAddress.State = viewModel.ContactInfo.Address.State;
newAddress.Zip = viewModel.ContactInfo.Address.Zip;
newContactInfo.Address = newAddress;
newContactInfo.Email = viewModel.ContactInfo.Email;
newContactInfo.Phone1 = viewModel.ContactInfo.Phone1;
newContactInfo.Phone2 = viewModel.ContactInfo.Phone2;
newOwner.Name = viewModel.Name;
newOwner.ContactInfo = newContactInfo;
using (REMSDAL dal = new REMSDAL())
{
dal.Owners.Add(newOwner);
var result = await dal.SaveChangesAsync();
if (result > 0)
{
viewModel.ActionStatusMessageViewModel.StatusMessage = "Owner " + viewModel.Name + " added.";
viewModel.Name = "";
return View(viewModel);
}
}
}
...but getting this error:
Exception Details: System.Data.SqlClient.SqlException: Cannot insert the value NULL into column 'OwnerId', table 'REMS.dbo.Complexes'; column does not allow nulls. UPDATE fails.
The statement has been terminated.
How can I be getting an error regarding Complexes when I'm trying to add an Owner?
There is class User
namespace TaskManager.Models
{
public class User
{
private const int NAME_LENGTH = 200;
private const int EMAIL_LENGTH = 100;
private const int PASSWORD_MIN_LENGTH = 5;
private const int PASSWORD_MAX_LENGTH = 20;
public int Id { get; set; }
[Required]
[StringLength(NAME_LENGTH)]
public string Name { get; set; }
[Required]
[EmailAddress]
[StringLength(EMAIL_LENGTH)]
public string Email { get; set; }
[Required]
[DataType(DataType.Password)]
[StringLength(PASSWORD_MAX_LENGTH, MinimumLength = PASSWORD_MIN_LENGTH)]
public string Password { get; set; }
public string PasswordSalt { get; set; }
[Required]
[DefaultValue(UserType.User)]
public UserType Type { get; set; }
public ICollection<Task> Tasks { get; set; }
}
public enum UserType
{
Admin = 0,
User = 1
}
}
and I try to create custom user registration using SimpleCrypto.
Here is my method
[HttpGet]
public ActionResult Registration()
{
return View();
}
[HttpPost]
public ActionResult Registration(User user)
{
if (ModelState.IsValid)
{
if (!IsUserExist(user.Email))
{
var crypto = new SimpleCrypto.PBKDF2();
var encrpPass = crypto.Compute(user.Password);
var newUser = _db.Users.Create();
newUser.Name = user.Name;
newUser.Email = user.Email;
newUser.Type = UserType.User.ToString();
newUser.Password = encrpPass;
newUser.PasswordSalt = crypto.Salt;
_db.Users.Add(newUser);
_db.SaveChanges();
return RedirectToAction("Index", "Home");
}
else
{
ModelState.AddModelError("", "User already exists");
}
}
else
{
ModelState.AddModelError("", "Data is incorrect");
}
return View(user);
}
If I use this table schema, registration works correctly
but if I try to set Id as Primary Key and set Identity == true and Identity Increment = 1
I got an Exception in _db.SaveChanges(); method.
What do I do wrong? How to fix it?
Exception
System.Data.SqlServerCe.SqlCeException: The column cannot be modified. [ Column name = Id ]
I tried to change model
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
but I got the same exception.
I am testing my controller code using IOC Unity. The issue is with the initialisation of the model that I am passing to constructor of my controller.
Here is my code in the test project
[TestMethod]
public void TestHomeControllerIndexMethod()
{
HomeController controller = new HomeController(new stubPeopleService());
ViewResult result = controller.Index() as ViewResult;
Assert.AreEqual(0, result);
}
Below is the code of the stubPeopleService that I have created which I pass to my controller constructor above
public class stubPeopleService : IPeople
{
public int Age
{
get;
set;
}
public string BirthPlace
{
get;
set;
}
public DateTime DateOfBirth
{
get;
set;
}
public int GetAge(DateTime reference, DateTime birthday)
{
int age = reference.Year - birthday.Year;
if (reference < birthday.AddYears(age)) age--;
return age + 1;
}
public int Height
{
get;
set;
}
public List<People> listPeople { get { return GetPeople(); } }
public string Name
{
get;
set;
}
public int Weight
{
get;
set;
}
private List<People> GetPeople()
{
List<People> list = new List<People>();
list.Add(new People
{
Name = "Ranjit Menon",
DateOfBirth = DateTime.Today,
BirthPlace = "London",
Age = 25,
Height = 175,
Weight = 85
});
return list.OrderBy(x => x.Name).ToList();
}
}
When I debug my test , I notice that the all the properties do not contain any value. The only property that contains value is listPeople property. The listpeople property does initialise the other properties but throws an object cannot be created error.Let me know if I am doing the test correctly. I need to do a test initialising the model with some values.
Code from my home controller
private IPeople peopleService;
public HomeController(IPeople people)
{
this.peopleService = people;
}
public ActionResult Index()
{
return View(peopleService);
}
Please find the IPeople interface below
public interface IPeople
{
int Age { get; set; }
string BirthPlace { get; set; }
DateTime DateOfBirth { get; set; }
int GetAge(DateTime reference, DateTime birthday);
int Height { get; set; }
List<People> listPeople { get; }
string Name { get; set; }
int Weight { get; set; }
}
I'm newbie to MVC architecture.When I'm trying to update, its showing error ,Its totally strange but the data is updating.
The model item passed into the dictionary is of type 'CMS.Domain.Models.Site', but this dictionary requires a model item of type 'CMS.Web.ViewModels.SiteModel'.'.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.InvalidOperationException: The model item passed into the dictionary is of type 'CMS.Web.ViewModels.SiteModel', but this dictionary requires a model item of type 'System.Collections.Generic.IEnumerable`1[CMS.Web.ViewModels.SiteModel]'.
My code looks like:
ViewModels:
namespace CMS.Web.ViewModels
{
public class SiteModel
{
public SiteModel()
{
SiteStatus = new List<SelectListItem>();
}
[Key]
public int ID { get; set; }
[Required(ErrorMessage = "Site Name is required")]
[Display(Name = "Site Name")]
public string Title { get; set; }
[Display(Name = "Require Login")]
public bool RequiresLogin { get; set; }
[Display(Name = "Force HTTPS")]
public bool ForceHTTPS { get; set; }
[Display(Name = "Enable Approval")]
public bool Approval { get; set; }
[AllowHtml]
public IList<SelectListItem> SiteStatus { get; set; }
public bool Deleted { get; set; }
public string CreatedBy { get; set; }
public DateTime CreatedOn
{
get { return _createdOn; }
set { _createdOn = value; }
}
private DateTime _createdOn = DateTime.Now;
public string LastUpdatedBy { get; set; }
public DateTime LastUpdatedOn
{
get { return _lastUpdatedOn; }
set { _lastUpdatedOn = value; }
}
private DateTime _lastUpdatedOn = DateTime.Now;
[Display(Name = "Site State")]
public string SiteState { get; set; }
}
}
Model:
namespace CMS.Domain.Models
{
public partial class Site : Model
{
public string Title { get; set; }
public bool Approval { get; set; }
public bool RequiresLogin { get; set; }
public bool ForceHTTPS { get; set; }
public virtual string SiteStatus { get; set; }
public bool Deleted { get; set; }
}
}
Controller:
public ActionResult Index()
{
var _sites = _siterepository.FindAll();
return View(_sites);
}
public ActionResult Add()
{
var model = new SiteModel();
var _SiteStatus = _siterepository.GetSiteStatus();
foreach (var _sitestatus in _SiteStatus)
{
model.SiteStatus.Add(new SelectListItem()
{
Text = _sitestatus.StatusName,
Value = _sitestatus.StatusName.ToString()
});
}
return View(model);
}
[HttpPost]
public ActionResult Add(SiteModel _sitemodel)
{
var model = _sitemodel.ToEntity();
_siterepository.Add(model);
return View(model);
}
public ActionResult Edit(int id)
{
var model = new SiteModel();
var Site = _siterepository.Find(id);
model = Site.ToModel();
var _SiteStatus = _siterepository.GetSiteStatus();
foreach (var _sitestatus in _SiteStatus)
{
model.SiteStatus.Add(new SelectListItem()
{
Text = _sitestatus.StatusName,
Value = _sitestatus.StatusName.ToString(),
Selected = _sitestatus.StatusName == Site.SiteStatus
});
}
return View(model);
}
[HttpPost]
public ActionResult Edit(SiteModel _sitemodel)
{
var model = _sitemodel.ToEntity();
_siterepository.Update(model);
return View(model);
}
I'm struggling to resolve this , please help.
Check your View's model declaration. It is expecting an enumerable list (IEnumerable<CMS.Web.ViewModels.SiteModel>), but you are passing it a single instance of CMS.Web.ViewModels.SiteModel