Data annotation and custom attributes from xml - data-annotations

I want to attached custom attributes from xml configuration please help me out for this.
public partial class User
{
public Nullable<int> UserId { get; set; }
public string UserName { get; set; }
public string Password { get; set; }
public Nullable<int> salary { get; set; }
}
[MetadataType(typeof(CUserAttributes))]
public class Cuser : User
{
public Nullable<bool> IsRequire { get; set; }
}
//[Serializable]
public class CUserAttributes
{
[Required]
public Nullable<bool> IsRequire { get; set; }
[Display(Name="My UserId")]
[RequiredIf(IsRequiredPropertyName = "IsRequire", ErrorMessage = "required.")]
public Nullable<int> UserId { get; set; }
[RequiredIf(IsRequiredPropertyName = "IsRequire", ErrorMessage = "required.")]
public string UserName { get; set; }
[RequiredIf(IsRequiredPropertyName = "IsRequire", ErrorMessage = "required.")]
public string Password { get; set; }
[RequiredIf(IsRequiredPropertyName = "IsRequire", ErrorMessage = "required.")]
public Nullable<int> salary { get; set; }
}
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = false, Inherited = true)]
public class RequiredIf : ValidationAttribute, IClientValidatable
{
public string IsRequiredPropertyName { get; set; }
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
var isRequiredName = validationContext.ObjectInstance.GetType().GetProperty(this.IsRequiredPropertyName);
var isRequiredNameValue = isRequiredName.GetValue(validationContext.ObjectInstance, null);
if (isRequiredNameValue != null)
{
if (Convert.ToBoolean(isRequiredNameValue) == true)
{
if (value == null)
{
return new ValidationResult(this.ErrorMessage);
}
}
}
else if (isRequiredNameValue == null)
{
throw new Exception("RequiredIf property value is not found");
}
return ValidationResult.Success;
}
public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
{
ModelClientValidationRule mcvr = new ModelClientValidationRule();
mcvr.ValidationType = "requiredif";
mcvr.ErrorMessage = this.ErrorMessage;
mcvr.ValidationParameters.Add("isrequiredpropertyname", this.IsRequiredPropertyName);
return new List<ModelClientValidationRule> { mcvr };
}
}
I have create Model, Attributes class then custom attribute class, but now I want add those data annotations i.e Display, RequiredIf(custom attribute) from XML configuration.

it is possible to get the configuration for validations from xml,
you can follow the below link
http://www.primaryobjects.com/CMS/Article141.aspx

Related

MVC How do I create a new object with default value

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";

Cannot Add Previously Inserted Object to Another Object (Entity Framework)

I have the EF classes OAFile and Email. I am loading the emails from the server and storing in the repository. The user can then list the e-mails and "associate" them with the selected file.
The email object is previously inserted into the repository, and I want to get the count of the emails of the file.
file.Emails.Add(email)
adds the email to the file object, but it is not being saved.
file.Emails.Count
returns always 0.
The email.FileID field is saved correctly.
What am I missing? How can get the number of email by calling file.Emails.Count?
[HttpPost]
[ValidateInput(false)]
public ActionResult AssignEmail(int emailId, int assignedTo)
{
if (emailId > 0 && assignedTo > 0)
{
Email email = repository.Emails.FirstOrDefault(x => x.EmailID == emailId);
OAFile file = repository.OAFiles.FirstOrDefault(x => x.FileID == assignedTo);
if (email != null && file != null)
{
email.FileID = assignedTo;
email.AssignedByID = HttpContext.User.Identity.GetUserId();
file.Emails.Add(email);
repository.Save();
return Json(new { success = true }, JsonRequestBehavior.DenyGet);
}
else
{
return Json(new { success = false }, JsonRequestBehavior.DenyGet);
}
}
else
{
return Json(new { success = false }, JsonRequestBehavior.DenyGet);
}
}
The Email class:
public class Email
{
public Email()
{
Attachments = new HashSet<EmailAttachment>();
}
[Key]
public int EmailID { get; set; }
public string EmailIdentifier { get; set; }
public int MessageNumber { get; set; }
public string From { get; set; }
public string Subject { get; set; }
public DateTime DateSent { get; set; }
public string Body { get; set; }
public int? FileID { get; set; }
public string AssignedByID { get; set; }
public string AssignedToID { get; set; }
public string EmailType { get; set; }
public ICollection<EmailAttachment> Attachments { get; set; }
[ForeignKey("FileID")]
public virtual OAFile OAFile { get; set; }
[ForeignKey("AssignedByID")]
public virtual AppUser AssignedBy { get; set; }
[ForeignKey("AssignedToID")]
public virtual AppUser AssignedTo { get; set; }
}
and the OAFile class:
public class OAFile
{
public OAFile()
{
Services = new HashSet<Service>();
Documents = new HashSet<Document>();
Notes = new HashSet<Note>();
Forms = new HashSet<Form>();
Emails = new HashSet<Email>();
}
[Key]
public int FileID { get; set; }
[Required]
public int CompanyID { get; set; }
[Required]
[StringLength(14)]
public string OurFileName { get; set; }
[Required]
[StringLength(100)]
public string CompanyFileName { get; set; }
[Required]
public string AppUserId_Creator { get; set; }
[DisplayFormat(DataFormatString = "{0:dd.MM.yyyy}")]
public DateTime CreatedOn { get; set; }
public int ClientID { get; set; }
[ForeignKey("ClientID")]
public virtual Client Client { get; set; }
public virtual ICollection<Service> Services { get; set; }
public ICollection<Document> Documents { get; set; }
public ICollection<Note> Notes { get; set; }
public ICollection<Form> Forms { get; set; }
public ICollection<Email> Emails { get; set; }
public virtual Company Companies { get; set; }
[ForeignKey("AppUserId_Creator")]
public virtual AppUser AppUsers_Creator { get; set; }
}
EDIT: I am calling the file.Emails.Count statement below to check whether the file has any emails associated with it.
public bool IsFileEmpty(int fileId)
{
bool isFileEmpty = true;
OAFile file = repository.FindOAFile(fileId);
if (file.Services.Count > 0 || file.Documents.Count > 0
|| file.Forms.Count > 0 || file.Notes.Count > 0 || file.CCTable != null || file.AccountingTable != null
|| file.Emails.Count > 0
)
{
isFileEmpty = false;
}
return isFileEmpty;
}
EDIT 2: I am calling the IsFileEmpty() method in another controller (HomeController.cs) while populating view model for search results. The results rows display the Delete link if the file is empty.
public ActionResult FilesSearch(FileSearchViewModel viewModel)
{
var files = !string.IsNullOrWhiteSpace(viewModel.Keyword) ? repository.FindOAFiles(viewModel.Keyword) : repository.OAFiles;
var sortedFile = files.Where(x => x.IsFileOpen).OrderByDescending(x => x.CreatedOn).ToList();
sortedFile.AddRange(files.Where(x => !x.IsFileOpen).OrderByDescending(x => x.CreatedOn));
var resultsList = new List<FileSearchResultsViewModel>();
foreach (OAFile file in sortedFile)
{
var resultsViewModel = new FileSearchResultsViewModel();
resultsViewModel.oAFile = file;
resultsViewModel.isFileEmpty = IsFileEmpty(file.FileID);
resultsList.Add(resultsViewModel);
}
return PartialView("_FilesSearch", resultsList);
}

Entity Framework & Code First: Can't get data in one-to-one between ApplicationUser and UserProfile

I have custom ApplicationUser and create UserProfile, but can't get data UserProfile from ApplicationUser.
Attack Image:
Please refer to http://www.mediafire.com/file/a9bpajjc44fuewp/DemoMVC6.rar
Update my code:
namespace DemoMVC6.Models
{
// Add profile data for application users by adding properties to the ApplicationUser class
public class ApplicationUser : IdentityUser
{
public virtual UserProfile UserProfile { get; set; }
}
[Table("UserProfile")]
public class UserProfile : EntityBase
{
[Required, MinLength(3), MaxLength(20)]
public string FirstName { get; set; }
[Required, MinLength(3), MaxLength(20)]
public string LastName { get; set; }
public bool? Gender { get; set; }
public DateTime? Birthday { get; set; }
public string Address { get; set; }
public virtual ApplicationUser ApplicationUser { get; set; }
}
public abstract class EntityBase
{
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public virtual int Id { get; set; }
[EnumDataType(typeof(RecordStatus))]
public virtual RecordStatus ActiveStatus { get; set; }
[DataType(DataType.DateTime)]
public virtual DateTime CreatedOn { get; set; }
public virtual int CreatedBy { get; set; }
[DataType(DataType.DateTime)]
public virtual DateTime ModifiedOn { get; set; }
public virtual int ModifiedBy { get; set; }
}
public enum RecordStatus { Inactive = 0, Active = 1 }
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
: base(options)
{
}
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
// Customize the ASP.NET Identity model and override the defaults if needed.
// For example, you can rename the ASP.NET Identity table names and more.
// Add your customizations after calling base.OnModelCreating(builder);
}
public override int SaveChanges()
{
var currentTime = DateTime.Now;
var trackerEntries = this.ChangeTracker.Entries().Where(e => e.State == EntityState.Added || e.State == EntityState.Modified);
//Find all Entities that are Added/Modified that inherit from my EntityBase
foreach (var entry in trackerEntries)
{
if (entry.State == EntityState.Added)
{
if (entry.Metadata.FindProperty("ActiveStatus") != null)
entry.Property("ActiveStatus").CurrentValue = RecordStatus.Active;
if (entry.Metadata.FindProperty("CreatedOn") != null)
entry.Property("CreatedOn").CurrentValue = currentTime;
if (entry.Metadata.FindProperty("ModifiedOn") != null)
entry.Property("ModifiedOn").CurrentValue = currentTime;
}
else
{
if (entry.Metadata.FindProperty("ModifiedOn") != null)
entry.Property("ModifiedOn").CurrentValue = currentTime;
}
}
return base.SaveChanges();
}
public DbSet<UserProfile> UserProfiles { get; set; }
}
}

MVC Code- or Model First

Most of the tutorials for MVC with Entity Framework are centered around Code-First, where you write classes for generating the model. This gives the advantage of control and Migrations, but I think it lack overview. I would therefore prefer to create the model using the graphical designer, but I cannot see how or if data migrations work in this context. It seems, that when I change the model (with data in the database), all the data is deleted in all tables.
Is there a way around this?
How can I do validation when using Model-First? Partial classes?
you may use the global validation beside mvc validation
example :
public class ValidationCriteria
{
public ValidType Type { get; set; }
public ValidRange Range { get; set; }
public ValidFormat Format { get; set; }
public ValidIsNull IsNull { get; set; }
public ValidCompare Compare { get; set; }
public ValidDB DB { get; set; }
public string Trigger { get; set; }
public Dictionary<string, ValidationCriteria> Before { get; set; }
public string After { get; set; }
public class ValidDB
{
public string functionName { get; set; }
public object[] param { get; set; }
public object functionClass { get; set; }
public string msg { get; set; }
public bool check = false;
}
public class ValidCompare
{
public string first { get; set; }
public string second { get; set; }
public string compareOperator { get; set; }
public string compareValue { get; set; }
public string msg { get; set; }
public bool check = false;
}
public ValidationCriteria()
{
this.Range = new ValidRange();
this.Format = new ValidFormat();
this.IsNull = new ValidIsNull();
this.Type = new ValidType();
this.Compare = new ValidCompare();
this.DB = new ValidDB();
this.Trigger = "blur";
this.Before = new Dictionary<string, ValidationCriteria>();
this.After = "";
}
public class ValidType
{
// checking element is integer.
public bool isInt { get; set; }
// checking element is decimal.
public bool isDecimal { get; set; }
public string msg { get; set; }
public bool check = false;
}
public class ValidRange
{
public long min { get; set; }
public long max { get; set; }
public string msg { get; set; }
public bool check = false;
}
public class ValidFormat
{
public bool isEmail { get; set; }
public string regex { get; set; }
public string msg { get; set; }
public bool check = false;
}
public class ValidIsNull
{
public string nullDefaultVal { get; set; }
public string msg { get; set; }
public bool check = false;
}
}
Meanwhile you may use validation part in your controller
Example :
private bool validateMaintainanceManagement(MaintainanceCRUD.Maintainance model, bool edit = false, bool ServerValidation = true)
{
bool ValidModel = false;
Dictionary<string, ValidationCriteria> validCriteria = new Dictionary<string, ValidationCriteria>();
#region maintainTitle Criteria
ValidationCriteria maintainTitle = new ValidationCriteria();
maintainTitle.IsNull.msg = Resources.Home.ErrmaintainTitle;
maintainTitle.IsNull.check = true;
maintainTitle.IsNull.nullDefaultVal = "-1";
//maintainTitle.Trigger = "change"; // this may trigger if you are using dropdown
validCriteria.Add("maintainTitle", maintainTitle);
#endregion

The model item passed into the dictionary is of type 'ViewModels.SiteModel',

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

Resources