C# 如何根据其他2个属性的值设置1个属性的值?
我在做动物收容所的申请。员工需要能够将新动物添加到数据库中。动物有三个属性:出生日期、年龄和估计数。用户可以输入出生日期字段和估计年龄字段 如果两个字段都有值,我想抛出一个异常。如果它们都没有值,我还想抛出一个异常。如果输入了出生日期,将计算年龄,并且年龄属性将设置为计算值。如果输入了估计年龄,年龄值将设置为估计年龄 我似乎无法在我的域类中找到正确的方法来处理这个问题。目前,如果同时输入了估计年龄和出生日期,它不会抛出异常并将动物添加到数据库中 动物领域类别:C# 如何根据其他2个属性的值设置1个属性的值?,c#,asp.net-mvc,C#,Asp.net Mvc,我在做动物收容所的申请。员工需要能够将新动物添加到数据库中。动物有三个属性:出生日期、年龄和估计数。用户可以输入出生日期字段和估计年龄字段 如果两个字段都有值,我想抛出一个异常。如果它们都没有值,我还想抛出一个异常。如果输入了出生日期,将计算年龄,并且年龄属性将设置为计算值。如果输入了估计年龄,年龄值将设置为估计年龄 我似乎无法在我的域类中找到正确的方法来处理这个问题。目前,如果同时输入了估计年龄和出生日期,它不会抛出异常并将动物添加到数据库中 动物领域类别: public class Anim
public class Animal
{
public int Id { get; set; }
public string Name { get; set; }
public DateTime? Birthdate { get; set; }
private int _age;
public int Age
{
get
{
return _age;
}
set
{
if (EstimatedAge.HasValue && Birthdate.HasValue)
{
throw new InvalidOperationException();
}
else if (!EstimatedAge.HasValue && !Birthdate.HasValue)
{
throw new InvalidOperationException();
}
else if (EstimatedAge.HasValue && !Birthdate.HasValue)
{
_age = (int) EstimatedAge;
}
else
{
_age = CalculateAge(Birthdate);
}
}
}
public int? EstimatedAge { get; set; }
public string Description { get; set; }
public AnimalType Type { get; set; }
public string Breed { get; set; }
public Gender Gender { get; set; }
public string Photo { get; set; }
public DateTime ArrivalDate { get; set; }
public DateTime? AdoptionDate { get; set; }
public DateTime? DeathDate { get; set; }
public bool SterilizedOrCastrated { get; set; }
public bool? ChildFriendly { get; set; }
public string Reason { get; set; }
public bool Adoptable { get; set; } = true;
public string AdoptedBy { get; set; }
public Residence Residence { get; set; }
public int ResidenceId { get; set; }
public ICollection<Treatment> Treatments { get; set; }
public ICollection<Comment> Comments { get; set; }
// Calculates the animal's age based on the entered birthdate.
public int CalculateAge(DateTime? birthdate)
{
// Save today's date.
var today = DateTime.Today;
// Calculate the age.
var age = today.Year - birthdate?.Year;
// Go back to the year in which the person was born in case of a leap year.
if (birthdate?.Date > today.AddYears((int) -age))
{
age--;
}
return (int) age;
}
公共类动物
{
公共int Id{get;set;}
公共字符串名称{get;set;}
公共日期时间?生日{get;set;}
私人互联网;
公共信息
{
得到
{
回归年龄;
}
设置
{
if(EstimatedAge.HasValue&&Birthdate.HasValue)
{
抛出新的InvalidOperationException();
}
如果(!EstimatedAge.HasValue&!Birthdate.HasValue),则为else
{
抛出新的InvalidOperationException();
}
else if(EstimatedAge.HasValue&!Birthdate.HasValue)
{
_年龄=(整数)估计数;
}
其他的
{
_年龄=计算年龄(出生日期);
}
}
}
公共整数?估计数{get;set;}
公共字符串说明{get;set;}
公共动物类型类型{get;set;}
公共字符串{get;set;}
公共性别{get;set;}
公共字符串Photo{get;set;}
公共日期时间到达日期{get;set;}
公共日期时间?采用日期{get;set;}
公共日期时间?死亡日期{get;set;}
公共布尔值{get;set;}
公共布尔?儿童友好型{get;set;}
公共字符串原因{get;set;}
公共bool可采用{get;set;}=true;
{get;set;}采用的公共字符串
公共住宅{get;set;}
公共int驻留ID{get;set;}
公共ICollection处理{get;set;}
公共ICollection注释{get;set;}
//根据输入的出生日期计算动物的年龄。
公共整数计算日期(日期时间?出生日期)
{
//保存今天的日期。
var today=DateTime.today;
//计算年龄。
var age=今天。年-出生日期?年;
//如果是闰年,请回到此人出生的年份。
如果(生日?.Date>today.AddYears((int)-年龄))
{
年龄--;
}
返回(int)年龄;
}
在我的控制器中创建动物的操作方法:
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> NewAnimal(NewAnimalViewModel newAnimal)
{
var animalToCreate = new Animal()
{
Name = newAnimal.Name,
Birthdate = newAnimal.Birthdate,
Age = newAnimal.Age,
EstimatedAge = newAnimal.EstimatedAge,
Description = newAnimal.Description,
Type = newAnimal.Type,
Breed = newAnimal.Breed,
Gender = newAnimal.Gender,
Photo = newAnimal.Photo,
ArrivalDate = newAnimal.ArrivalDate,
SterilizedOrCastrated = newAnimal.SterilizedOrCastrated,
ChildFriendly = newAnimal.ChildFriendly,
Reason = newAnimal.Reason,
Adoptable = newAnimal.Adoptable,
Residence = newAnimal.Residence,
ResidenceId = newAnimal.ResidenceId
};
if (ModelState.IsValid)
{
await _animalRepository.AddAnimal(animalToCreate);
return RedirectToAction("Index");
}
PrefillSelectOptions();
return View(newAnimal);
}
[HttpPost]
[ValidateAntiForgeryToken]
公共异步任务NewAnimal(NewAnimalViewModel NewAnimal)
{
var animalToCreate=新动物()
{
Name=newAnimal.Name,
生日=新动物。生日,
年龄=新动物。年龄,
EstimatedAge=newAnimal.EstimatedAge,
描述=新动物。描述,
Type=newAnimal.Type,
繁殖,繁殖,
性别=新动物。性别,
照片=新动物。照片,
ArrivalDate=newAnimal.ArrivalDate,
灭菌或阉割=新动物。灭菌或阉割,
儿童友好型,
原因=新动物。原因,
可收养的,可收养的,
住所=新动物。住所,
ResidenceId=newAnimal.ResidenceId
};
if(ModelState.IsValid)
{
等待动物库。添加动物(animalToCreate);
返回操作(“索引”);
}
PrefillSelectOptions();
返回视图(新动物);
}
试试这个。创建一个私有方法来验证输入,并从属性的setterBirthdate
和EstimatedAge
调用它。如果条件满足,抛出异常。在您的代码中,只有设置了Age
,并且您说用户只输入Birthdate
和EstimatedAge时才会进行验证e> .问题在于您使用的是字段初始化,它们是按如下顺序设置的:
var animal = new Animal();
animal.Birthdate = newAnimal.Birthdate;
animal.Age = newAnimal.Age;
animal.EstimatedAge = newAnimal.EstimatedAge;
结果是您在设置字段年龄时尚未设置EstimatedAge。因此不会触发年龄设置器内的验证
重新排序这些字段的初始化方式将触发验证。但是让验证依赖于初始化顺序显然是不好的。您可以添加一个“IsValid()方法,但正如@jamice所建议的,您可能应该验证新的AnimalViewModel。您应该在模型上实现IValidatableObject
,然后实现Validate()
method。这是模型级验证的模式,其中“此字段必须大于这两个字段之和”,或其他多属性验证
见:
在您的情况下,验证可能类似于:
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
if (Birthdate.HasValue && Age > 0)
yield return new ValidationResult($"Can't enter both.", new[] { "Birthdate" });
}
公共IEnumerable验证(ValidationContext ValidationContext)
{
如果(Birthdate.HasValue&&Age>0)
yield返回新的ValidationResult($“不能同时输入两个。”,new[]