[英]Use foreign key object in form validation in C# MVC
我创建了一个名为Subject
的类,它有Department
作为外键。 ShortNameValidation
是ValidationAttribute
这验证ShortName
的格式(的第三个字符ShortName
必须等于的第一个字符Department
的SingleKey
属性)。 验证在控制器内部使用,该控制器通过键入名称、短名称并从预定义的部门下拉列表中选择部门来创建新主题。
我尝试直接在IsValid
方法中访问subject.Department
,但它是null
。 我目前唯一的解决方案是通过使用DepartmentId
从数据库中手动读取来获取部门。
是否有更优雅的解决方案来自动注入subject.Department
?
代码:
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace Example.Models
{
public class Subject
{
public int Id { get; set; }
[Required]
public int Name { get; set; }
[Required]
[MinLength(4)]
[MaxLength(15)]
[ShortNameValidation]
public string ShortName { get; set; }
[ForeignKey("Department")]
public int DepartmentId { get; set; }
public virtual Department Department { get; set; }
}
internal class ShortNameValidationAttribute : ValidationAttribute
{
private AppContext _appContext = new AppContext();
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
Subject subject = validationContext.ObjectInstance as Subject;
// subject.Department returns null - fetch the department from the database
Department department = _appContext.Departments.Find(subject.DepartmentId);
if (subject.ShortName[2] != department.SingleKey[0])
{
return new ValidationResult("Invalid short name");
}
return ValidationResult.Success;
}
}
}
看法:
@model Example.Models.Subject
@{
ViewBag.Title = "Create";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>Create</h2>
@using (Html.BeginForm())
{
@Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>Subject</h4>
<hr />
@Html.ValidationSummary(true, "", new { @class = "text-danger" })
<div class="form-group">
@Html.LabelFor(model => model.Name, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.Name, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.Name, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.ShortName, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.ShortName, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.ShortName, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.DepartmentId, "DepartmentId", htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.DropDownList("DepartmentId", null, htmlAttributes: new { @class = "form-control" })
@Html.ValidationMessageFor(model => model.DepartmentId, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>
</div>
}
<div>
@Html.ActionLink("Back to List", "Index")
</div>
@section Scripts {
@Scripts.Render("~/bundles/jqueryval")
}
确保您在 GET 上填充 Department
[HttpGet]
public ActionResult Create()
{
// example only
Subject subject = new Subject
{
Id = 1,
DepartmentId = 1,
Name = 1,
Department = new Department() { SingleKey = "Science" },
ShortName = "Science"
};
return View(subject);
}
然后在你的表格中确保你有一个隐藏的Department
属性
@Html.HiddenFor(m => m.Department.SingleKey) // now this will model bind nicely
现在,在您的ShortNameValidationAttribute
发布表单后,您将填充Department
Subject subject = validationContext.ObjectInstance as Subject;
if(subject.Department != null)
{
// do validation
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.