Проверка формы на стороне клиента не работает для мастера jquery с использованием MetadataType

Я использую MetadataType, чтобы предоставить моим объектам возможности проверки для двух отдельных объектов. В качестве предостережения я использую мастер на стороне клиента, использующий ненавязчивую проверку с помощью jQuery и JavaScript. Проверка, кажется, работает на одном объекте, а не на другом.

После дальнейшего анализа я заметил, что 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>

Вот 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>
}

person user1790300    schedule 07.06.2013    source источник
comment
Вы можете опубликовать свой код просмотра?   -  person karaxuna    schedule 08.06.2013
comment
Я должен быть в состоянии сделать это, дайте мне секунду.   -  person user1790300    schedule 08.06.2013
comment
Я добавил код просмотра.   -  person user1790300    schedule 09.06.2013
comment
Я также замечаю, что, хотя проверка объекта Metrics, кажется, работает; атрибут отображения тоже не работает. По умолчанию используется имя поля для метки, а не отображаемое имя.   -  person user1790300    schedule 09.06.2013


Ответы (2)


У меня была такая же проблема с плагином jquery stepy. Я решил это, добавив правила проверки, когда пользователь меняет страницу.

person jcuriel    schedule 11.06.2013

Наконец-то я нашел проблему и решение. Было несколько проблем. 1) Мои объекты находятся в отдельном проекте от веб-проекта, частичные не могут охватывать несколько проектов. Исправлено это путем частичного наследования от класса сущности. 2) После того, как это было исправлено, я начинаю получать ошибки jquery для поля пароля. По-видимому, у jquery.unobtrusive.validate есть проблема с именованием mvc3 и атрибутом Compare. Мне пришлось исправить файл .js, как описано в этой статье: Сравнить атрибут (пароль) . После этих изменений все работает правильно.

person user1790300    schedule 13.06.2013