我的模型如下所述。我只想为 Application.References 集合中的前 2 个项目提供参考字段的子集。我希望这在客户端和服务器端验证都发生。我有一个工作方法,我将在下面描述,但我觉得客户端相当笨拙,所以我想知道是否有更好的方法来处理这个问题。如果可能的话,我希望是通用的,因为我在 Application 对象中有一些其他集合来验证其中的一个子集。
英孚模型
public class Application
{
//...EF framework code...
public EntityCollection<Reference> References
{
//get, set
}
}
public partial class Reference : EntityObject
{
public global::System.String FullName
{
//get, set
}
public global::System.String Relationship
{
//get, set
}
public global::System.String PhoneNumber
{
//get, set
}
public global::int? RelationshipLength //radio button
{
//get, set
}
public global::int? ReferenceType //radio button
{
//get, set
}
}
参考元数据.cs
[MetadataType(typeof(ReferenceMetadata))]
public partial class Reference
{
}
public class ReferenceMetadata
{
[DisplayFormat(NullDisplayText = "N/A")]
[DisplayName("Full Name")]
public string FullName { get; set; }
[DisplayFormat(NullDisplayText = "N/A")]
[DisplayName("Reference Type")]
public string ReferenceType { get; set; }
[DisplayFormat(NullDisplayText = "N/A")]
[DisplayName("How long have you known this person?")]
public string RelationshipLength { get; set; }
[DisplayFormat(NullDisplayText = "N/A")]
[DisplayName("Relationship")]
public string Relationship { get; set; }
[DisplayFormat(NullDisplayText = "N/A")]
[DisplayName("Phone")]
public string Phone { get; set; }
//...more properites
}
我目前正在使用来自Pro ASP.NET MVC 2 Framework的 Steven Sanderson 的 RuleException 和 RulesViolationExceptionExtensions手动进行服务器端验证,如下所示:
public static class ApplicationBusinessLogic
{
public static void RunServerValidation(Application app)
{
var errors = new RulesException<Application>();
for (int i = 0; i < 3; i ++)
{
if (string.IsNullOrEmpty(app.References.ElementAt(i).FullName))
errors.ErrorFor(x => x.References.ElementAt(i).FullName, "The Full Name for a first and second reference are required.");
if (app.References.ElementAt(i).ReferenceType == null)
errors.ErrorFor(x => x.References.ElementAt(i).ReferenceType, "The Reference Type for a first and second reference are required.");
if (app.References.ElementAt(i).RelationshipLength == null)
errors.ErrorFor(x => x.References.ElementAt(i).RelationshipLength, "The Relationship Length for a first and second reference are required.");
if (string.IsNullOrEmpty(app.References.ElementAt(i).Relationship))
errors.ErrorFor(x => x.References.ElementAt(i).Relationship, "The Relationship for a first and second reference are required.");
if (string.IsNullOrEmpty(app.References.ElementAt(i).Phone))
errors.ErrorFor(x => x.References.ElementAt(i).Relationship, "The Phone Number for a first and second reference are required.");
}
if (errors.Errors.Any())
throw errors;
}
}
我只是从控制器调用 RunServerValidation 方法,捕获异常,然后将它们复制到 ModelState。它工作正常,但我不确定如何在客户端处理这个问题。如果我使用 [Required] 元数据,则集合中的所有 3 个项目都将具有这些字段。我只想要三分之二。
我连接客户端验证的笨拙方式是通过在视图中指定 data-val 和 data-val-required 属性,同时呈现如下输入:
@for (int i = 0; i < 3; i++)
{
ViewData.TemplateInfo.HtmlFieldPrefix = "Application.References[" + i + "]";
<h3>Reference @i</h3>
@Html.ValidationMessageFor(model => model.Application.References.ElementAt(i).FullName)
<div class="editor-label">
@Html.LabelFor(model => model.Application.References.ElementAt(i).FullName)
</div>
<div class="editor-field">
@Html.TextBoxFor(model => model.Application.References.ElementAt(i).FullName, new { maxlength = "100", data_val="true", data_val_required="The Full Name for a first and second reference are required." })
</div>
@* and so on for other properties... *@
}
它有效,但这并不理想。我想也许我可以制作一个通用的 ValidationAttribute,但我想这会很复杂。我正在考虑[RequiredFieldsForFirstXCollectionItems(FirstXItems=2, Fields= new [] {"FullName", "ReferenceType" /* etc */})]
Application.References 成员,但我不确定如何以通用方式做到这一点。我的想法是否正确?然后我可以以这种方式实现客户端和服务器端,但我认为这将是非常复杂的代码。
2011 年 4 月 26 日更新:
我认为使用 $(document).ready 函数中的 jquery.Validation 插件添加客户端验证对我来说可能更好,而不是将 data-val 和 data-val-required html5 属性放在输入标签上。然后至少我有一个集中的地方来进行客户验证。这是我所做的:
@*End of Razor View file*@
<script type="text/javascript>
function addValidationRules() {
//references
for (var i = 0; i < 2; i++) {
$("#Application_References_" + i + "__FullName").rules("add", {
required: true,
messages: {
required: "The Full Name for a first and second reference are required."
}
});
//etc. for other properties
}//end for-loop
}//end addValidationRules()
$(document).ready(function () {
addValidationRules();
//more js code...
});
</script>
当然,当我开始为错误消息使用资源文件时,如果我决定将 javascript 移动到 .js 文件中,可能会有点麻烦。我认为如果我将函数保留在视图中,我应该能够根据需要读取资源文件。