Custom Validation in MVC Model - asp.net-mvc-4

I am having model as
public class GroupedIssueData
{
[Range(0, double.MaxValue, ErrorMessage = "Please enter valid number")]
public double IssueQty { get; set; }
public double ReqQty { get; set; }
public bool isSavings { get; set; }
}
This contains two properties as IssueQty and IsSaving, If the IsSaving is checked then IssueQty can be empty, If the IssueQty is not empty then IsSaving can be left blank. How can I validate this
My View is
<td>
#Html.DisplayFor(m => m.MaterialData[i].ReqQty)
#Html.HiddenFor(m => m.MaterialData[i].ReqQty)
</td>
<td>#Html.TextBoxFor(m => m.MaterialData[i].IssueQty, new { style = "width:70px" })#Html.ValidationMessageFor(m => m.MaterialData[i].IssueQty)</td>
<td class="text-center">#Html.CheckBoxFor(m => m.MaterialData[i].isSavings)</td>
And my Controller is
public async Task<ActionResult> GetWorkOrderMaterialDetails(IssueEntryModel m)
{
if (!ModelState.IsValid)
{
// redirect
}
var model = new IssueEntryModel();
}
How can I redirect to the if the Model is not valid. Do I need to redirect to same controller. I want to retain the entered data.
My View is

try this
`
[Required]
[Range(18, 100, ErrorMessage = "Please enter an age between 18 and 50")]
public int Age { get; set; }
[Required]
[StringLength(10)]
public int Mobile { get; set; }
[Range(typeof(decimal), "0.00", "15000.00")]
public decimal Total { get; set; } `
if (ModelState.IsValid)
{
//
}
return View(model);
Validation to the Model
Custom Validation Data Annotation Attribute

You can make a custom validation e.g. RequiredIfOtherFieldIsNullAttribute like described here:
How to validate one field related to another's value in ASP .NET MVC 3
public class RequiredIfOtherFieldIsNullAttribute : ValidationAttribute, IClientValidatable
{
private readonly string _otherProperty;
public RequiredIfOtherFieldIsNullAttribute(string otherProperty)
{
_otherProperty = otherProperty;
}
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
var property = validationContext.ObjectType.GetProperty(_otherProperty);
if (property == null)
{
return new ValidationResult(string.Format(
CultureInfo.CurrentCulture,
"Unknown property {0}",
new[] { _otherProperty }
));
}
var otherPropertyValue = property.GetValue(validationContext.ObjectInstance, null);
if (otherPropertyValue == null || otherPropertyValue as string == string.Empty)
{
if (value == null || value as string == string.Empty)
{
return new ValidationResult(string.Format(
CultureInfo.CurrentCulture,
FormatErrorMessage(validationContext.DisplayName),
new[] { _otherProperty }
));
}
}
return null;
}
public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
{
var rule = new ModelClientValidationRule
{
ErrorMessage = FormatErrorMessage(metadata.GetDisplayName()),
ValidationType = "requiredif",
};
rule.ValidationParameters.Add("other", _otherProperty);
yield return rule;
}
}
And use it like that:
[RequiredIfOtherFieldIsNull("IsSavings")]
public double IssueQty { get; set; }
[RequiredIfOtherFieldIsNull("IssueQty")]
public bool IsSavings { get; set; }

Use IValidatableObject
However your condition: If the IsSaving is checked then IssueQty can be empty, If the IssueQty is not empty then IsSaving can be left blank is bit confusing, but this might hint you anyways
public class GroupedIssueData : IValidatableObject
{
[Range(0, double.MaxValue, ErrorMessage = "Please enter valid number")]
public double IssueQty { get; set; }
public double ReqQty { get; set; }
public bool isSavings { get; set; }
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
if (!isSavings && IssueQty == 0)
{
yield return new ValidationResult("Error Message");
}
}
}
public async Task<ActionResult> GetWorkOrderMaterialDetails(IssueEntryModel m)
{
if (!ModelState.IsValid)
{
return View(m);
// redirect
}
}

Related

Invalid Include Path Error in Asp.net 6 Web API

After Adding a Include property on the parent model controller I am facing the following error:
'Microsoft.EntityFrameworkCore.Query.InvalidIncludePathError': Unable to find navigation ' CurrencyList' specified in string based include path ' CurrencyList'. This exception can be suppressed or logged by passing event ID 'CoreEventId.InvalidIncludePathError' to the 'ConfigureWarnings' method in 'DbContext.OnConfiguring' or 'AddDbContext'.'
I am sharing all the related class & model.
CurrencyList (Model) : This is the child class which I want to include into the parent class for populating the dropdown.
public class CurrencyList
{
[Key]
public int Id { get; set; }
[DisplayName("CURRENCY")]
[Required(ErrorMessage = "CURRENCY is a required field")]
public string? CurrencyName { get; set; }
[DisplayName("EXCHANGE RATE")]
[Required(ErrorMessage = "EXCHANGE RATE is a required field")]
public double Rate { get; set; }
}
CurrencyList Controller:
public class CurrencyListController : ControllerBase
{
private readonly IUnitOfWork _unitOfWork;
public CurrencyListController(IUnitOfWork unitOfWork)
{
_unitOfWork = unitOfWork;
}
[HttpGet]
public IEnumerable<CurrencyList> Get()
{
IEnumerable<CurrencyList> objCurrencyDropDownList = _unitOfWork.Currency.GetAll();
return _unitOfWork.Currency.GetAll();
}
[HttpGet("{id:int}")]
public CurrencyList GetDetails(int id)
{
return _unitOfWork.Currency.GetDetails(id);
}
[HttpPost]
[ProducesResponseType(StatusCodes.Status201Created)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
public IActionResult Create(CurrencyList obj)
{
if (ModelState.IsValid)
{
_unitOfWork.Currency.Add(obj);
_unitOfWork.Save();
return CreatedAtAction("GetDetails", new { id = obj.Id }, obj);
}
return BadRequest();
}
[HttpPut]
[ProducesResponseType(StatusCodes.Status204NoContent)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
public IActionResult Edit(CurrencyList obj)
{
if (ModelState.IsValid)
{
_unitOfWork.Currency.Update(obj);
_unitOfWork.Save();
return NoContent();
}
return BadRequest();
}
[HttpDelete]
[ProducesResponseType(StatusCodes.Status204NoContent)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
public IActionResult Delete(int? id)
{
var obj = _unitOfWork.Currency.GetFirstOrDefault(c => c.Id == id);
if (obj == null)
{
return NotFound();
}
_unitOfWork.Currency.Remove(obj);
_unitOfWork.Save();
return NoContent();
}
}
BTBNewLienOpening (Model) : This is the parent class where I created FK retalion with CurrencyList Model.
public class BTBNewLienOpening
{
[Key]
public int ExpLCNoId { get; set; }
[DisplayName("EXPORT L/C NO")]
[ValidateNever]
public string? ExpLCNo { get; set; }
[DisplayName("ORDER NO")]
[ValidateNever]
public string? OrderNo { get; set; }
[DisplayName("STYLE")]
public int? StyleListId { get; set; }
[ForeignKey("StyleListId")]
[ValidateNever]
public StyleList? StyleList { get; set; }
[DisplayName("VALUE")]
[ValidateNever]
[DisplayFormat(DataFormatString = "{0:C}", ApplyFormatInEditMode = false)]
public decimal? Value { get; set; }
[DisplayName("NET VALUE")]
[ValidateNever]
[DisplayFormat(DataFormatString = "{0:C}", ApplyFormatInEditMode = false)]
public decimal? NetValue { get; set; }
[DisplayName("CURRENCY")]
public int? CurrencyListId { get; set; }
[ForeignKey("CurrencyListId")]
[ValidateNever]
public CurrencyList? CurrencyList { get; set; }
[DisplayName("QTY PCS")]
[ValidateNever]
public string? QtyPcs { get; set; }
[DisplayName("SHIPMENT")]
[ValidateNever]
public string? Shipment { get; set; }
[DisplayName("EXPIRY DATE")]
[ValidateNever]
public string? Expiry { get; set; }
[DisplayName("COUNTRY")]
public int? CountryListId { get; set; }
[ForeignKey("CountryListId")]
[ValidateNever]
public CountryList? CountryList { get; set; }
}
BTBNewLienOpeningController : This is the controller where I use the include properties for including all the dropdown properties. In the GetAll() method I use the include properties and include the dropdown properties. If I run the program without CurrencyList the app works fine. But after adding CurrencyList it shows the Microsoft.EntityFrameworkCore.Query.InvalidIncludePathError'
public class BTBNewLienOpeningController : ControllerBase
{
private readonly IUnitOfWork _unitOfWork;
private readonly ILogger<BTBNewLienOpeningController> _logger;
public BTBNewLienOpeningController(IUnitOfWork unitOfWork, ILogger<BTBNewLienOpeningController> logger)
{
_unitOfWork = unitOfWork;
_logger = logger;
}
[HttpGet]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
public IActionResult GetNewLienOpening()
{
try
{
IEnumerable<BTBNewLienOpening> objBTBNewLienOpeningList = _unitOfWork.BTBNewLienOpening.GetAll(includeProperties: "StyleList, CurrencyList, CountryList");
return Ok(objBTBNewLienOpeningList);
}
catch (Exception ex)
{
_logger.LogError(ex, $"Something went wrong in the {nameof(GetNewLienOpening)}");
return StatusCode(500, "Internal Server Error, Please Try Again Leter!");
}
}
[HttpGet("{id:int}")]
public BTBNewLienOpening GetDetails(int id)
{
return _unitOfWork.BTBNewLienOpening.GetDetails(id);
}
//[Authorize(Roles = "Administrator")]
[HttpPost]
[ProducesResponseType(StatusCodes.Status201Created)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
public IActionResult Create(BTBNewLienOpening obj)
{
if (ModelState.IsValid)
{
_unitOfWork.BTBNewLienOpening.Add(obj);
_unitOfWork.Save();
return CreatedAtAction("GetDetails", new { id = obj.ExpLCNoId }, obj);
}
_logger.LogError($"Something went wrong in the {nameof(Create)}");
return StatusCode(500, "Internal Server Error, Please Try Again Leter!");
}
[HttpPut]
[ProducesResponseType(StatusCodes.Status202Accepted)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
public IActionResult Update(BTBNewLienOpening obj)
{
if (ModelState.IsValid)
{
_unitOfWork.BTBNewLienOpening.Update(obj);
_unitOfWork.Save();
return StatusCode(202, "Successfully Updated!");
}
_logger.LogError($"Something went wrong in the {nameof(Update)}");
return StatusCode(500, "Internal Server Error, Please Try Again Leter!");
}
[HttpDelete]
[ProducesResponseType(StatusCodes.Status204NoContent)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
public IActionResult Delete(int? id)
{
if (id < 1)
{
_logger.LogError($"Invalid Delete Attempt In {nameof(Delete)}");
return BadRequest();
}
try
{
var obj = _unitOfWork.BTBNewLienOpening.GetFirstOrDefault(c => c.ExpLCNoId == id);
if (obj == null)
{
_logger.LogError($"Invalid Delete Attempt In {nameof(Delete)}");
return BadRequest("Submitted Data Is Invalid");
}
_unitOfWork.BTBNewLienOpening.Remove(obj);
_unitOfWork.Save();
return NoContent();
}
catch (Exception ex)
{
_logger.LogError(ex, $"Something Went Wrong In The {nameof(Delete)}");
return StatusCode(500, "Internal Server Error, Please Try Again Leter!");
}
}
}
Repository (Class) : Here I use the GetAll method and added the include functionality.
public class Repository<T> : IRepository<T> where T : class
{
private readonly ApplicationDbContext _db;
internal DbSet<T> dbSet;
public Repository(ApplicationDbContext db)
{
_db = db;
this.dbSet = _db.Set<T>();
}
public void Add(T entity)
{
dbSet.Add(entity);
}
public IEnumerable<T> GetAll(string? includeProperties = null)
{
IQueryable<T> query = dbSet;
if (includeProperties != null)
{
foreach (var includeProp in includeProperties.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
{
query = query.Include(includeProp);
}
}
return query.ToList();
}
public T GetFirstOrDefault(Expression<Func<T, bool>> filter, string? includeProperties = null)
{
IQueryable<T> query = dbSet;
query = query.Where(filter);
if (includeProperties != null)
{
foreach (var includeProp in includeProperties.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
{
query = query.Include(includeProp);
}
}
return query.FirstOrDefault();
}
public T GetDetails(int id)
{
return dbSet.Find(id);
}
public void Remove(T entity)
{
dbSet.Remove(entity);
}
public void RemoveRange(IEnumerable<T> entity)
{
dbSet.RemoveRange(entity);
}
public IEnumerable<T> GetProp(string? includeProperties = null)
{
IQueryable<T> query = dbSet;
if (includeProperties != null)
{
foreach (var includeProp in includeProperties.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
{
query = query.Include(includeProp);
}
}
return query.ToList();
}
}

Entity Framework Core no duplicate entries with ErrorMessage

What is the best way to avoid duplicate entries with MVC-EFC and ErrorMessage return
Model Test.cs
public class Test
{
public int Id { get; set; }
[Required(ErrorMessage = "Select a Name")]
[StringLength(50, ErrorMessage = "Max 50 character")]
public string Name { get; set; }
[StringLength(100, ErrorMessage = "Max 100 character")]
public string Text { get; set; }
}
I use a ApiController with "ErrorMessage" return.
For column "Name" i do not want duplicates and a ErrorMessage return like "Entry already available!"
What is the best way?
Try to implement custom ValidationAttribute
Customer ValidationAttribute
public class UniqueValidation : ValidationAttribute
{
private readonly string _errorMessage;
public UniqueValidation(string ErrorMessage)
{
_errorMessage = ErrorMessage;
}
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
if (validationContext != null && typeof(IName).IsAssignableFrom(validationContext.ObjectType))
{
ApplicationDbContext db = validationContext.GetService(typeof(ApplicationDbContext)) as ApplicationDbContext;
IQueryable<IName> result = db.GetType().GetMethod("Set").MakeGenericMethod(validationContext.ObjectType).Invoke(db, null) as IQueryable<IName>;
var v = result.FirstOrDefault(u => u.Name == ((IName)validationContext.ObjectInstance).Name);
if (v != null)
{
return new ValidationResult(_errorMessage);
}
}
return ValidationResult.Success;
}
}
Use
public class File: IName
{
public int Id { get; set; }
[UniqueValidation("FileName is exist")]
public string Name { get; set; }
[InverseProperty("Avatar")]
public ICollection<ApplicationUser> Users { get; set; }
}
public interface IName
{
string Name { get; set; }
}

EF Core2.0 dbvalidation errors not displaying all errors

I've Created an EF core 2.0 application and trying to validate the model on Savechanges but its only returning the first validation error.
Here are my Dbcontext and controller
public partial class ProductWarehouseContext : DbContext
{ public List<string> ErrorList=new List<string>();
public ProductWarehouseContext(DbContextOptions<ProductWarehouseContext> options)
: base(options)
{
}
public virtual DbSet<Customer> Customer { get; set; }
public virtual DbSet<Order> Order { get; set; }
public virtual DbSet<OrderItem> OrderItem { get; set; }
public virtual DbSet<Product> Product { get; set; }
public virtual DbSet<Supplier> Supplier { get; set; }
public override int SaveChanges()
{
var entities = from e in ChangeTracker.Entries()
where e.State == EntityState.Added
|| e.State == EntityState.Modified
select e.Entity;
foreach (var entity in entities)
{
var validationContext = new ValidationContext(entity);
Validator.ValidateObject(
entity,
validationContext,
validateAllProperties: true);
}
return base.SaveChanges();}
}
Controller
[HttpPost]
public IActionResult Save([FromBody]CustomerViewModel customer)
{
using (var cont = _context.Database.BeginTransaction())
{
try
{
var cust = new Customer()
{
FirstName = customer.FirstName,
LastName = customer.LastName,
City = customer.City,
Country = customer.Country,
Phone = customer.Phone,
IsSubscribedforAlerts = customer.IsSubscribedforAlerts
};
_context.Customer.Add(cust);
_context.SaveChanges();
cont.Commit();
}
catch (Exception e)
{
Errors.Add(e.Message);
cont.Rollback();
foreach (var err in Errors)
{
ModelState.AddModelError("errors", err);
}
return Ok(ModelState);
}
}
return Ok();
}
Class
public partial class Customer
{
public Customer()
{
Order = new HashSet<Order>();
}
public int Id { get; set; }
[Required(ErrorMessage = "FirstName is required to save a new customer")]
public string FirstName { get; set; }
[Required(ErrorMessage = "LastName is required to save a new customer")]
public string LastName { get; set; }
public string City { get; set; }
public string Country { get; set; }
[Required(ErrorMessage = "PhoneNumber is required to save a new customer")]
public string Phone { get; set; }
public bool? IsSubscribedforAlerts { get; set; }
public ICollection<Order> Order { get; set; }
}
and error is only returnig ""firstname" is required and if I pass the firstname in request object then its returning "lastname" is required.
What should I do to return all the errors how we do it in EF6 using DbEntityValidationException ?
That's because ValidateObject() throws upon first encountering an error. Try using TryValidateObject() instead, and pass it a List<ValidationResult> that accumulate all errors.
Something like:
public class EntityValidationException : Exception
{
public EntityValidationException(IEnumerable<ValidationException> exceptions)
{
this.ValidationErrors = exceptions;
}
public IEnumerable<ValidationException> ValidationErrors { get; }
}
Then in your SaveChanges():
foreach (var entity in entities)
{
var validationContext = new ValidationContext(entity);
var validationResults = new List<ValidationResult>();
Validator.TryValidateObject(entity, validationContext, validationResults);
if (validationResults.Any())
throw new EntityValidationException(validationResults.Select(x => new ValidationException(x, null, null)));
}
Then in your controller/action, you can explicitly handle EntityValidationException:
catch (EntityValidationException validationException)
{
foreach (var err in validationException.ValidationErrors)
{
var validationResult = err.ValidationResult;
ModelState.AddModelError(validationResult.MemberNames.First(), validationResult.ErrorMessage);
}
}

MVC Model Custom Control Attribute

I am using custom uniqueemail confirmation attribute like
public class UniqueEmailAttribute : ValidationAttribute
{
public override bool IsValid(object value)
{
WMContext db = new WMContext();
var userWithTheSameEmail = db.Users.SingleOrDefault(
u => u.email == (string)value);
return userWithTheSameEmail == null;
}
}
It is working fine while inserting user. But, when I try to update user it gives an error.
public class User
{
public int userID { get; set; }
[Required]
[Display(Name = "Name")]
public string name { get; set; }
[Required]
[Display(Name = "Email")]
[UniqueEmail(ErrorMessage = "This email is used by another user")]
public string email { get; set; }
}
Solution : I have changed the IsValid method like this :
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
var model = (User)validationContext.ObjectInstance;
WMContext db = new WMContext();
var userWithTheSameEmail = db.Users.SingleOrDefault(
u => u.email == (string)value && u.userID!=model.userID);
if (userWithTheSameEmail!=null)
{
return new ValidationResult("Bu eposta adresi kullanılıyor.");
}
return ValidationResult.Success;
}

MVC RequiredIf Attribute - IsValid value parameter always null

I am implementing a RequiredIf validation attribute and the value being passed to the IsValid method is always null.
RequiredIfAttribute Class
public class RequiredIfAttribute : ValidationAttribute
{
private RequiredAttribute innerAttribute = new RequiredAttribute();
public string DependentProperty { get; set; }
public object TargetValue { get; set; }
public RequiredIfAttribute(string dependentProperty, object targetValue)
{
this.DependentProperty = dependentProperty;
this.TargetValue = targetValue;
}
public override bool IsValid(object value)
{
return innerAttribute.IsValid(value);
}
}
ViewModel
[Required]
[Display(Name = "Are You A Student?")]
public bool? IsStudent { get; set; }
[RequiredIf("IsStudent", true, ErrorMessage = "You must upload a photo of your student ID if you wish to register as a student.")]
[Display(Name = "Student ID")]
[FileExtensions("jpg|jpeg|png|pdf", ErrorMessage = "File is not in the correct format.")]
[MaxFileSize(2 * 1024 * 1024, ErrorMessage = "You may not upload files larger than 2 MB.")]
public HttpPostedFileBase StudentId { get; set; }
EditorTemplate
#model bool?
#using System.Web.Mvc;
#{
var options = new List<SelectListItem>
{
new SelectListItem { Text = "Yes", Value = "true", Selected = Model.HasValue && Model.Value },
new SelectListItem { Text = "No", Value = "false", Selected = Model.HasValue && Model.Value }
};
string defaultOption = null;
if (ViewData.ModelMetadata.IsNullableValueType)
{
defaultOption = "(Select)";
}
}
#Html.DropDownListFor(m => m, options, defaultOption)
Every time the form is submitted, the RequiredIf error message is thrown and I have a feeling it has to do with the null value I described initially. What am I doing wrong? Thanks!
NOTE: The HTML appears to be rendering properly, so I don't think that's the problem.
<select data-val="true" data-val-required="The Are You A Student? field is required." id="IsStudent" name="IsStudent"><option value="">(Select)</option>
<option value="true">Yes</option>
<option value="false">No</option>
</select>
Because this is your code -
public class RequiredIfAttribute : ValidationAttribute
{
private RequiredAttribute innerAttribute = new RequiredAttribute();
public string DependentProperty { get; set; }
public object TargetValue { get; set; }
public RequiredIfAttribute(string dependentProperty, object targetValue)
{
this.DependentProperty = dependentProperty;
this.TargetValue = targetValue;
}
public override bool IsValid(object value)
{
return innerAttribute.IsValid(value);
}
}
You are using a RequriedAtrribute. So to simulate that it behaves life a RequiredIf you have to implement some logic that will check whether the target property value is true or false. But you are not doing that and returning just from the innerattribute. So it is just a mere Required not RequiredIf -
public override bool IsValid(object value)
{
return innerAttribute.IsValid(value);
}
modify this function to do some checking like -
public override bool IsValid(object value)
{
//if the referred property is true then
return innerAttribute.IsValid(value);
//else
return True
}
I use the following code:
[AttributeUsage(AttributeTargets.Property, AllowMultiple = true)]
public abstract class StefAttribute : ValidationAttribute
{
public WDCIAttribute()
: base()
{
this.ErrorMessageResourceType = typeof(GlobalResources);
}
}
[AttributeUsage(AttributeTargets.Property, AllowMultiple = true, Inherited = true)]
public class StefRequiredIfAttribute : StefAttribute
{
private RequiredAttribute innerAttribute = new RequiredAttribute();
public string DependentProperty { get; set; }
public object TargetValue { get; set; }
public WDCIRequiredIfAttribute()
{
}
public WDCIRequiredIfAttribute(string dependentProperty, object targetValue)
: base()
{
this.DependentProperty = dependentProperty;
this.TargetValue = targetValue;
}
public override bool IsValid(object value)
{
return innerAttribute.IsValid(value);
}
}
public class RequiredIfValidator : DataAnnotationsModelValidator<StefRequiredIfAttribute>
{
public RequiredIfValidator(ModelMetadata metadata, ControllerContext context, StefRequiredIfAttribute attribute)
: base(metadata, context, attribute)
{
}
public override IEnumerable<ModelValidationResult> Validate(object container)
{
// get a reference to the property this validation depends upon
var field = Metadata.ContainerType.GetProperty(Attribute.DependentProperty);
if (field != null)
{
// get the value of the dependent property
object value = field.GetValue(container, null);
// compare the value against the target value
if (IsEqual(value) || (value == null && Attribute.TargetValue == null))
{
// match => means we should try validating this field
if (!Attribute.IsValid(Metadata.Model))
{
// validation failed - return an error
yield return new ModelValidationResult { Message = ErrorMessage };
}
}
}
}
private bool IsEqual(object dependentPropertyValue)
{
bool isEqual = false;
if (Attribute.TargetValue != null && Attribute.TargetValue.GetType().IsArray)
{
foreach (object o in (Array)Attribute.TargetValue)
{
isEqual = o.Equals(dependentPropertyValue);
if (isEqual)
{
break;
}
}
}
else
{
if (Attribute.TargetValue != null)
{
isEqual = Attribute.TargetValue.Equals(dependentPropertyValue);
}
}
return isEqual;
}
}
Which can be used in the model as follows:
public class PersonnelVM : EntityVM
{
// . . .
[DisplayName("Name")]
[StefRequiredIf("IndividualOrBulk", PersonnelType.Bulk, ErrorMessageResourceName = GlobalResourceLiterals.Name_Required)]
public string Name { get; set; }
[DisplayName("PersonnelType")]
public PersonnelType IndividualOrBulk { get; set; }
// . . .
}