[英]Use foreign key object in form validation in C# MVC
I have created a class named Subject
which has Department
as a foreign key.我创建了一个名为
Subject
的类,它有Department
作为外键。 ShortNameValidation
is a ValidationAttribute
which validates ShortName
's format (the third character of ShortName
must be equals to the first character of Department
's SingleKey
property). ShortNameValidation
是ValidationAttribute
这验证ShortName
的格式(的第三个字符ShortName
必须等于的第一个字符Department
的SingleKey
属性)。 The validation is used inside a controller which creates a new subject by typing a name, a short name and choosing a department from the predefined drop-down list of departments.验证在控制器内部使用,该控制器通过键入名称、短名称并从预定义的部门下拉列表中选择部门来创建新主题。
I tried accessing subject.Department
directly inside IsValid
method, but it was null
.我尝试直接在
IsValid
方法中访问subject.Department
,但它是null
。 The only solution I have at the moment is to fetch the department by reading it manually from the database using the DepartmentId
.我目前唯一的解决方案是通过使用
DepartmentId
从数据库中手动读取来获取部门。
Is there a more elegant solution to inject subject.Department
automatically?是否有更优雅的解决方案来自动注入
subject.Department
?
Code:代码:
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;
}
}
}
View:看法:
@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")
}
Make sure you are populating Department on GET确保您在 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);
}
Then in your form make sure you have a hidden property for Department
然后在你的表格中确保你有一个隐藏的
Department
属性
@Html.HiddenFor(m => m.Department.SingleKey) // now this will model bind nicely
Now after you post your form inside your ShortNameValidationAttribute
you will have Department
populated现在,在您的
ShortNameValidationAttribute
发布表单后,您将填充Department
Subject subject = validationContext.ObjectInstance as Subject;
if(subject.Department != null)
{
// do validation
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.