客户端表单验证不适用于使用MetadataType的jquery向导

时间:2022-12-09 13:36:37

I am using MetadataType to provide my entities with validation capabilities for two separate entities. As a caveat, I am using a client-side wizard using unobtrusive validation with jQuery and JavaScript. The validation seems to work on one entity and not on the other.

我正在使用MetadataType为我的实体提供两个独立实体的验证功能。作为一个警告,我使用客户端向导使用jQuery和JavaScript进行不引人注意的验证。验证似乎适用于一个实体而不是另一个实体。

After further analysis, I noticed the data-val="true" is not rendered for the entity that is not validating. Here is where it get confusing, the Display attribute is not working for either entity and subsequently only the property name renders instead of the display attribute. I don't get it. I have been searching all over the internet for anyone who has encountered this problem and am coming up blank.

在进一步分析之后,我注意到没有为未验证的实体呈现data-val =“true”。这是令人困惑的地方,Display属性不适用于任何一个实体,随后只有属性名称呈现而不是display属性。我不明白。我一直在互联网上搜索任何遇到过这个问题并且空白的人。

AppName.Domain project:
namespace AppName.Domain.MemberDomain
{
     public class Member
     {
         public string EmailAddress { get; set; }

         public string Password { get; set; }

         public string FirstName { get; set; }

         public string MiddleName { get; set; }

         public string LastName { get; set; }
     }
}


namespace AppName.Domain.MetricsDomain
{
     public class Metrics
     {
         public string PersonalView { get; set; }

         public double CurrentWeight { get; set; }

         public double IdealWeight { get; set; }
     }
}


AppName.Web project:
namespace AppName.Models
{
    [MetadataType(typeof(MemberMetaData))]
    public partial class Member
    {
    }

    public class MemberMetaData
    {
        [Required]
        [StringLength(255)]
        [DataType(DataType.EmailAddress)]
        [Display(Name = "Email address")]
        public string EmailAddress { get; set; }

        [Required]
        [StringLength(10)]
        [DataType(DataType.Password)]
        [Display(Name = "Password")]
        public string Password { get; set; }

        [Required]
        [StringLength(10)]
        [DataType(DataType.Password)]
        [Display(Name = "Password")]
        [Compare("Password", ErrorMessage = "The passwords you entered do not match.")]
        public string ConfirmPassword { get; set; }

        [Required]
        [StringLength(20)]
        [DataType(DataType.Text)]
        [Display(Name = "First Name")]
        public string FirstName { get; set; }

        [StringLength(20)]
        [DataType(DataType.Text)]
        [Display(Name = "Middle Name")]
        public string MiddleName { get; set; }

        [Required]
        [StringLength(20)]
        [DataType(DataType.Text)]
        [Display(Name = "Last Name")]
        public string LastName { get; set; }
    }

    [MetadataType(typeof(PersonMetricsMetaData))]
    public partial class Metrics
    {
    }

    PersonMetricsMetaData
    {
         [Required]
         [StringLength(255)]
         [Display(Name = "How do you see yourself?")]
         public string PersonalView { get; set; }

         [Required]
         [RegularExpression(@"[0-9]*\.?[0-9]+", ErrorMessage = "You must enter a valid Number.")]
         [Display(Name = "Current Weight")]
         public double CurrentWeight { get; set; }

         [Required]
         [RegularExpression(@"[0-9]*\.?[0-9]+", ErrorMessage = "You must enter a valid Number.")]
         [Display(Name = "Ideal Weight")]
         public double IdealWeight { get; set; }
    }
}


public class RegisterModel
{
        public MetricsDomain.Metrics Metrics { get; set; }
        public MemberDomain.Member Member { get; set; }    
}

Form element for the Member entity:
<div class="elementContainer">
    <input id="Member_FirstName" name="Member.FirstName" type="text" value="" />
    <span class="field-validation-valid" data-valmsg-for="Member.FirstName" data-valmsg-replace="true"></span>
</div>

Form element for the Metrics entity:
<div class="elementContainer">
    <input data-val="true" data-val-number="The field Personal View must be a number." data-val-required="The Personal View field is required." id="Metrics_PersonalView" name="Metrics.PersonalView" type="text" value="" />
    <span class="field-validation-valid" data-valmsg-for="Metrics.PersonalView" data-valmsg-replace="true"></span>
</div>

Here is the html:

这是html:

@model AppName.Models.RegisterModel

@{
    ViewBag.Title = "Register";
    Layout = "~/Views/Shared/_OuterLayout.cshtml";
}

<style type="text/css">
    .formContainer { display: none; }
</style>

<script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>
<script type="text/javascript">
    var i = 1;
    var stepCount = 1;

    $(function () {

        $(".formContainer:first").fadeIn(); // show first step
        $("#lblCurrentStep").text(stepCount);
        //$(".buttonContainerBottom").hide();
        //$("#divWizardMenu").hide();

        // attach backStep button handler
        // hide on first step
        $("#previous").hide().click(function () {
            if (stepCount > 0)
                $("#lblCurrentStep").text(--stepCount);

            var $step = $(".formContainer:visible"); // get current step
            if ($step.prev().hasClass("formContainer")) { // is there any previous step?
                $step.hide().prev().fadeIn();  // show it and hide current step

                // disable backstep button?
                if (!$step.prev().prev().hasClass("formContainer")) {
                    $("#previous").hide();
                }
            }
        });


        // attach nextStep button handler       
        $("#next").click(function () {

            if (stepCount < 2)
                $("#lblCurrentStep").text(++stepCount);


            var $step = $(".formContainer:visible"); // get current step

            var validator = $("form").validate(); // obtain validator
            var anyError = false;

            $step.find("input").each(function () {
                if (!validator.element(this)) { // validate every input element inside this step
                    anyError = true;
                }

            });

            if (anyError)
                return false; // exit if any error found

        /*
            if ($step.next().hasClass("confirm")) { // is it confirmation?
                // show confirmation asynchronously
                $.post("/Account/Register", $("form").serialize(), function (r) {
                    // inject response in confirmation step
                    $(".formContainer.confirm").html(r);
                });
            }
        */

            if ($step.next().hasClass("formContainer")) { // is there any next step?
                $step.hide().next().fadeIn();  // show it and hide current step
                $("#previous").show();   // recall to show backStep button
            }

            else { // this is last step, submit form
                $("form").submit();
            }


        });

    });

</script>

@using (Html.BeginForm())
{
    @Html.ValidationSummary(true)
    <div id="divFormContainerMember" class="formContainer">
        <div id="divMemberLeft" class="leftContainer">
            <h1>User, great work.  Tell others about yourself</h1>
        </div>
        <div id="divMemberRight" class="rightContainer">
            <div class="labelContainer">
                @Html.LabelFor(m => m.Member.FirstName)
            </div>
            <div class="elementContainer">
                @Html.TextBoxFor(m => m.Member.FirstName)
                @Html.ValidationMessageFor(m => m.Member.FirstName)
            </div>
            <div class="labelContainer">
                @Html.LabelFor(m => m.Member.MiddleName)
            </div>
            <div class="elementContainer">
                @Html.TextBoxFor(m => m.Member.MiddleName)
                @Html.ValidationMessageFor(m => m.Member.MiddleName)
            </div>
            <div class="labelContainer">
                @Html.LabelFor(m => m.Member.LastName)
            </div>
            <div class="elementContainer">
                @Html.TextBoxFor(m => m.Member.LastName)
                @Html.ValidationMessageFor(m => m.Member.LastName)
            </div>
            <div class="labelContainer">
                @Html.LabelFor(m => m.Member.EmailAddress)
            </div>
            <div class="elementContainer">
                @Html.TextBoxFor(m => m.Member.EmailAddress)
                @Html.ValidationMessageFor(m => m.Member.EmailAddress)
            </div>
            <div class="labelContainer">
                @Html.LabelFor(m => m.Member.Password)
            </div>
            <div class="elementContainer">
                @Html.PasswordFor(m => m.Member.Password)
                @Html.ValidationMessageFor(m => m.Member.Password)
            </div>
            <div class="labelContainer">
                @Html.LabelFor(m => m.Member.NewPassword)
            </div>
            <div class="elementContainer">
                @Html.PasswordFor(m => m.Member.NewPassword)
                @Html.ValidationMessageFor(m => m.Member.NewPassword)
            </div>
        </div>
    </div>
    <div id="divFormContainerMetrics" class="formContainer">
        <div id="divMetricsLeft" class="leftContainer">
            <div class="labelContainer">
                @Html.LabelFor(m => m.Metrics.PersonalView)
            </div>
            <div class="elementContainer">
                @Html.TextBoxFor(m => m.Metrics.PersonalView)
                @Html.ValidationMessageFor(m => m.Metrics.PersonalView)
            </div>
            <div class="labelContainer">
                @Html.LabelFor(m => m.Metrics.CurrentWeight)
            </div>
            <div class="elementContainer">
                @Html.TextBoxFor(m => m.Metrics.CurrentWeight)
                @Html.ValidationMessageFor(m => m.Metrics.CurrentWeight)
            </div>
        <div class="labelContainer">
                @Html.LabelFor(m => m.Metrics.IdealWeight)
            </div>
            <div class="elementContainer">
                @Html.TextBoxFor(m => m.Metrics.IdealWeight)
                @Html.ValidationMessageFor(m => m.Metrics.IdealWeight)
            </div>        
    </div>
        <div id="divMetricsRight" class="rightContainer"> 
        </div>
    </div>
    <div class="buttonContainerBottom">
        <span class="buttonContainerInner">
            &nbsp;<input type="button" id="previous" name="previous" value="Previous" class="orangeButton" />
            <input type="button" id="next" name="next" value="Next" class="orangeButton"/>&nbsp;
            <label id="lblStep" class="wizardStep">Step&nbsp;<label id="lblCurrentStep"></label>&nbsp;of&nbsp;2</label>
        </span>
    </div>
}

2 个解决方案

#1


0  

I've had the same problem with the jquery stepy plugin. I solved it adding the validation rules when the user change the page.

我对jquery stepy插件有同样的问题。当用户更改页面时,我解决了添加验证规则的问题。

#2


0  

I finally found the problem and solution. There were multiple issues. 1) My entities are in a separate project from the web project, partials cannot span multiple projects. Fixed that by making the partial inherit from the entity class. 2) After this was fixed, I begin receiving jquery errors for the password field. Apparently, jquery.unobtrusive.validate has an issue with mvc3 naming and the Compare attribute. I had to perform the fix to the .js file as outlined in this article: Compare (password) attribute. After these changes, things appear to be working correctly.

我终于找到了问题和解决方案。有很多问题。 1)我的实体与Web项目位于一个单独的项目中,partials不能跨越多个项目。修复了通过从实体类进行部分继承的问题。 2)修复此问题后,我开始收到密码字段的jquery错误。显然,jquery.unobtrusive.validate存在mvc3命名和Compare属性的问题。我必须按照本文所述对.js文件执行修复:比较(密码)属性。在这些更改之后,事情似乎正常。

#1


0  

I've had the same problem with the jquery stepy plugin. I solved it adding the validation rules when the user change the page.

我对jquery stepy插件有同样的问题。当用户更改页面时,我解决了添加验证规则的问题。

#2


0  

I finally found the problem and solution. There were multiple issues. 1) My entities are in a separate project from the web project, partials cannot span multiple projects. Fixed that by making the partial inherit from the entity class. 2) After this was fixed, I begin receiving jquery errors for the password field. Apparently, jquery.unobtrusive.validate has an issue with mvc3 naming and the Compare attribute. I had to perform the fix to the .js file as outlined in this article: Compare (password) attribute. After these changes, things appear to be working correctly.

我终于找到了问题和解决方案。有很多问题。 1)我的实体与Web项目位于一个单独的项目中,partials不能跨越多个项目。修复了通过从实体类进行部分继承的问题。 2)修复此问题后,我开始收到密码字段的jquery错误。显然,jquery.unobtrusive.validate存在mvc3命名和Compare属性的问题。我必须按照本文所述对.js文件执行修复:比较(密码)属性。在这些更改之后,事情似乎正常。