2

我的模型如下所述。我只想为 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 文件中,可能会有点麻烦。我认为如果我将函数保留在视图中,我应该能够根据需要读取资源文件。

4

0 回答 0