在我的控制器中,我有一个动作,它接受 3 个参数(primary_key、property 和 value)并使用反射来设置相应模型的值。(通过其主键找到)
我认为如果模型被嵌入,我可以捕捉到模型,ModelState.IsValid
但它的评估结果是真实的。现在它会db.SaveChanges();
抛出异常。
ModelState
是有效的。(显然它不是主键找到的模型实例,实际上是指我的三个输入)。
我想我可以用以下行检查我的模型是否有错误......
if (System.Data.Entity.Validation.DbEntityValidationResult.ValidationErrors.Empty)
但我收到“缺少对象引用”错误。
我不知道那是什么意思。(C# 的新手以及这里的所有其他内容。)有什么帮助吗?
编辑 1 - 显示更多代码:
验证
[Column("pilot_disembarked")]
[IsDateAfter(testedPropertyName: "Undocked",
allowEqualDates: true,
ErrorMessage = "End date needs to be after start date")]
public Nullable<System.DateTime> PilotDisembarked { get; set; }
自定义验证器
public sealed class IsDateAfter : ValidationAttribute, IClientValidatable
{
private readonly string testedPropertyName;
private readonly bool allowEqualDates;
public IsDateAfter(string testedPropertyName, bool allowEqualDates = false)
{
this.testedPropertyName = testedPropertyName;
this.allowEqualDates = allowEqualDates;
}
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
var propertyTestedInfo = validationContext.ObjectType.GetProperty(this.testedPropertyName);
if (propertyTestedInfo == null)
{
return new ValidationResult(string.Format("unknown property {0}", this.testedPropertyName));
}
var propertyTestedValue = propertyTestedInfo.GetValue(validationContext.ObjectInstance, null);
if (value == null || !(value is DateTime))
{
return ValidationResult.Success;
}
if (propertyTestedValue == null || !(propertyTestedValue is DateTime))
{
return ValidationResult.Success;
}
// Compare values
if ((DateTime)value >= (DateTime)propertyTestedValue)
{
if (this.allowEqualDates)
{
return ValidationResult.Success;
}
if ((DateTime)value > (DateTime)propertyTestedValue)
{
return ValidationResult.Success;
}
}
return new ValidationResult(FormatErrorMessage(validationContext.DisplayName));
}
}
控制器动作
[HttpPost]
public ActionResult JsonEdit(string name, int pk, string value)
{
Voyage voyage = db.Voyages.Find(pk);
var property = voyage.GetType().GetProperty(name);
if (Regex.Match(property.PropertyType.ToString(), "DateTime").Success)
{
try
{
if (Regex.Match(value, @"^\d{4}$").Success)
{
var newValue = DateTime.ParseExact(value, "HHmm", System.Globalization.CultureInfo.InvariantCulture);
property.SetValue(voyage, newValue, null);
}
else if (value.Length == 0)
{
property.SetValue(voyage, null, null);
}
else
{
var newValue = DateTime.ParseExact(value, "yyyy/MM/dd HHmm", System.Globalization.CultureInfo.InvariantCulture);
property.SetValue(voyage, newValue, null);
}
}
catch
{
Response.StatusCode = 400;
return Json("Incorrect Time Entry.");
}
}
else
{
var newValue = Convert.ChangeType(value, property.PropertyType);
property.SetValue(voyage, newValue, null);
}
if (ModelState.IsValid)
{
db.SaveChanges();
Response.StatusCode = 200;
return Json("Success!");
}
else
{
Response.StatusCode = 400;
return Json(ModelState.Keys.SelectMany(key => this.ModelState[key].Errors));
}
}