Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-mvc/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Asp.net mvc 如何使用FluentValidation在客户端验证日期?_Asp.net Mvc_Asp.net Mvc 3_Fluentvalidation - Fatal编程技术网

Asp.net mvc 如何使用FluentValidation在客户端验证日期?

Asp.net mvc 如何使用FluentValidation在客户端验证日期?,asp.net-mvc,asp.net-mvc-3,fluentvalidation,Asp.net Mvc,Asp.net Mvc 3,Fluentvalidation,问题 下面的代码在服务器端而不是客户端正常工作。为什么? 当我提交表单时,控件转到BeAValidDate函数检查日期是否有效。是否有任何方法可以验证日期而不使用流畅的验证 脚本 <script src="jquery-1.7.1.min.js" type="text/javascript"></script> <script src="jquery.validate.js" type="text/javascript"></script> &l

问题

下面的代码在服务器端而不是客户端正常工作。为什么?


当我提交表单时,控件转到
BeAValidDate
函数检查日期是否有效。是否有任何方法可以
验证日期而不使用
流畅的验证

脚本

<script src="jquery-1.7.1.min.js" type="text/javascript"></script>
<script src="jquery.validate.js" type="text/javascript"></script>
<script src="jquery.validate.unobtrusive.js" type="text/javascript"></script>
查看

@using (Html.BeginForm("Index", "Person", FormMethod.Post))
{   
    @Html.LabelFor(x => x.FromDate)
    @Html.EditorFor(x => x.FromDate)
    @Html.ValidationMessageFor(x => x.FromDate)

    <input type="submit" name="Submit" value="Submit" />
}
@using (Html.BeginForm("Index", "Person", FormMethod.Post, 
                                                new { id = "FormSubmit" }))
{   
    @Html.Hidden("DateToCompareAgainst", Model.DateToCompareAgainst);      
    @Html.LabelFor(x => x.StartDate)
    @Html.EditorFor(x => x.StartDate)
    @Html.ValidationMessageFor(x => x.StartDate)
    <button type="submit">
        OK</button>
}
@使用(Html.BeginForm(“Index”,“Person”,FormMethod.Post))
{   
@LabelFor(x=>x.FromDate)
@Html.EditorFor(x=>x.FromDate)
@Html.ValidationMessageFor(x=>x.FromDate)
}

在下面的MVC 3中,代码应该可以正常工作

<script src="@Url.Content("~/Scripts/jquery-1.5.1.min.js")" type="text/javascript"></script>
<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>

@using (Html.BeginForm("Index", "Person", FormMethod.Post))
{   
    @Html.LabelFor(x => x.FromDate)
    @Html.EditorFor(x => x.FromDate)
    @Html.ValidationMessageFor(x => x.FromDate)

    <input type="submit" name="Submit" value="Submit" />
}

@使用(Html.BeginForm(“Index”,“Person”,FormMethod.Post))
{   
@LabelFor(x=>x.FromDate)
@Html.EditorFor(x=>x.FromDate)
@Html.ValidationMessageFor(x=>x.FromDate)
}
MVC 4中的简单工作示例

\u Layout.cshtml:

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8" />
        <title>@ViewBag.Title - My ASP.NET MVC Application</title>
        <link href="~/favicon.ico" rel="shortcut icon" type="image/x-icon" />
        <meta name="viewport" content="width=device-width" />


        @Styles.Render("~/Content/css")
        @Scripts.Render("~/bundles/modernizr")
    </head>
    <body>

        <div id="body">
            @RenderSection("featured", required: false)
            <section class="content-wrapper main-content clear-fix">
                @RenderBody()
            </section>
        </div>

        @Scripts.Render("~/bundles/jquery")
        @RenderSection("scripts", required: false)


    </body>
</html>
@model Mvc4Test.Models.Person

@{
    ViewBag.Title = "test";

}

<h2>test</h2>

@using (Html.BeginForm()) {
    @Html.ValidationSummary(true)

    <fieldset>
        <legend>Part</legend>

        <div class="editor-label">
            @Html.LabelFor(model => model.Name)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.Name)
            @Html.ValidationMessageFor(model => model.Name)
        </div>



        <p>
            <input type="submit" value="Create" />
        </p>
    </fieldset>
}

@section Scripts {
    @Scripts.Render("~/bundles/jqueryval")
}

@Title-我的ASP.NET MVC应用程序
@style.Render(“~/Content/css”)
@Scripts.Render(“~/bundles/modernizer”)
@渲染部分(“特色”,必填项:false)
@RenderBody()
@Scripts.Render(“~/bundles/jquery”)
@RenderSection(“脚本”,必需:false)
查看:

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8" />
        <title>@ViewBag.Title - My ASP.NET MVC Application</title>
        <link href="~/favicon.ico" rel="shortcut icon" type="image/x-icon" />
        <meta name="viewport" content="width=device-width" />


        @Styles.Render("~/Content/css")
        @Scripts.Render("~/bundles/modernizr")
    </head>
    <body>

        <div id="body">
            @RenderSection("featured", required: false)
            <section class="content-wrapper main-content clear-fix">
                @RenderBody()
            </section>
        </div>

        @Scripts.Render("~/bundles/jquery")
        @RenderSection("scripts", required: false)


    </body>
</html>
@model Mvc4Test.Models.Person

@{
    ViewBag.Title = "test";

}

<h2>test</h2>

@using (Html.BeginForm()) {
    @Html.ValidationSummary(true)

    <fieldset>
        <legend>Part</legend>

        <div class="editor-label">
            @Html.LabelFor(model => model.Name)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.Name)
            @Html.ValidationMessageFor(model => model.Name)
        </div>



        <p>
            <input type="submit" value="Create" />
        </p>
    </fieldset>
}

@section Scripts {
    @Scripts.Render("~/bundles/jqueryval")
}
@model Mvc4Test.Models.Person
@{
ViewBag.Title=“测试”;
}
测试
@使用(Html.BeginForm()){
@Html.ValidationSummary(true)
部分
@LabelFor(model=>model.Name)
@EditorFor(model=>model.Name)
@Html.ValidationMessageFor(model=>model.Name)

} @节脚本{ @Scripts.Render(“~/bundles/jqueryval”) }

关于您的设置和哪些不起作用,我有些不明白。你是说日期必须有效的验证无效,还是要求日期的事实无效

Fluent validation也能够为不引人注目的验证发出代码,因此所需的约束应该能够正常工作。 日期有效的事实完全是另一回事。如果您将FromDate指定为DateTime(您是否将其声明为DateTime或字符串?),则日期的正确性验证将由Mvc框架中包含的其他验证器自动执行,因此您无需在fluent验证规则中重复该验证。但是,在Mvc4之前,此验证检查仅在服务器端执行。使用MVC4,Asp.net Mvc团队修复了这个问题,并在客户端扩展了检查。 然而,在客户端,一切只适用于en-US日期格式,因为不引人注目的验证不能处理全球化。如果您需要其他文化中的日期,则需要使用,并且需要在客户端设置全球化。如果你对全球化感兴趣,你可能会看到。 将自动日期更正也添加到Mvc 3。您必须定义一个扩展的ClientDataTypeModelValidatorProvider,就像Mvc4一样。代码如下:

public class ClientDataTypeModelValidatorProviderExt : ClientDataTypeModelValidatorProvider
{
    public static Type ErrorMessageResources { get; set; }
    public static string NumericErrorKey { get; set; }
    public static string DateTimeErrorKey { get; set; }
    private static readonly HashSet<Type> _numericTypes = new HashSet<Type>(new Type[] {
        typeof(byte), typeof(sbyte),
        typeof(short), typeof(ushort),
        typeof(int), typeof(uint),
        typeof(long), typeof(ulong),
        typeof(float), typeof(double), typeof(decimal)
    });
    private static bool IsNumericType(Type type)
    {
        Type underlyingType = Nullable.GetUnderlyingType(type); // strip off the Nullable<>
        return _numericTypes.Contains(underlyingType ?? type);
    }
    internal sealed class NumericModelValidator : ModelValidator
    {
        public NumericModelValidator(ModelMetadata metadata, ControllerContext controllerContext)
            : base(metadata, controllerContext)
        {
        }

        public override IEnumerable<ModelClientValidationRule> GetClientValidationRules()
        {
            ModelClientValidationRule rule = new ModelClientValidationRule()
            {
                ValidationType = "number",
                ErrorMessage = MakeErrorString(Metadata.GetDisplayName())
            };

            return new ModelClientValidationRule[] { rule };
        }

        private static string MakeErrorString(string displayName)
        {
            // use CurrentCulture since this message is intended for the site visitor
            return String.Format(CultureInfo.CurrentCulture, ErrorMessageResources.GetProperty(NumericErrorKey, System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static).GetValue(null, null) as string, displayName);
        }

        public override IEnumerable<ModelValidationResult> Validate(object container)
        {
            // this is not a server-side validator
            return Enumerable.Empty<ModelValidationResult>();
        }
    }
    internal sealed class DateTimeModelValidator : ModelValidator
    {
        public DateTimeModelValidator(ModelMetadata metadata, ControllerContext controllerContext)
            : base(metadata, controllerContext)
        {
        }

        public override IEnumerable<ModelClientValidationRule> GetClientValidationRules()
        {
            ModelClientValidationRule rule = new ModelClientValidationRule()
            {
                ValidationType = "globalizeddate",
                ErrorMessage = MakeErrorString(Metadata.GetDisplayName())
            };

            return new ModelClientValidationRule[] { rule };
        }

        private static string MakeErrorString(string displayName)
        {
            // use CurrentCulture since this message is intended for the site visitor
            return String.Format(CultureInfo.CurrentCulture, ErrorMessageResources.GetProperty(DateTimeErrorKey, System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static).GetValue(null, null) as string, displayName);
        }

        public override IEnumerable<ModelValidationResult> Validate(object container)
        {
            // this is not a server-side validator
            return Enumerable.Empty<ModelValidationResult>();
        }
    }
    public override IEnumerable<ModelValidator> GetValidators(ModelMetadata metadata, ControllerContext context)
    {

        if (metadata == null)
        {
            throw new ArgumentNullException("metadata");
        }
        if (context == null)
        {
            throw new ArgumentNullException("context");
        }
        List<ModelValidator> res = null;
        if (NumericErrorKey == null || ErrorMessageResources == null)
            res = base.GetValidators(metadata, context).ToList();
        else
        {
            res = new List<ModelValidator>();
            if (IsNumericType(metadata.ModelType))
            {
                res.Add(new NumericModelValidator(metadata, context));
            }
        }
        if ( (metadata.ModelType == typeof(DateTime) || metadata.ModelType == typeof(DateTime?)))
        {
            if(ErrorMessageResources != null && DateTimeErrorKey != null)
                res.Add(new DateTimeModelValidator(metadata, context));
        }
        return res;
    }
}
现在,您必须添加在客户端执行控件的javascript片段:

$.validator.addMethod(
"globalizeddate",
 function (value, element, param) {
    if ((!value || !value.length) && this.optional(element)) return true; /*success*/       
    var convertedValue  = Globalize.parseDate(value);
            return !isNaN(convertedValue) && convertedValue;
  },
  "field must be a date/time"
))

在那里,我使用Globalize函数来验证正确的日期。安装它。这是使日期格式与.net格式兼容的唯一方法。此外,它适用于所有.net文化。使用标准javascript日期解析与某些浏览器中.Net接受的格式不兼容。

使用大于等于验证器的技巧。对我有用

Global.asax-应用程序启动事件

FluentValidationModelValidatorProvider.Configure(x =>
{
    x.Add(typeof(GreaterThanOrEqualValidator), 
            (metadata, Context, rule, validator) => 
                new LessThanOrEqualToFluentValidationPropertyValidator
                (
                    metadata, Context, rule, validator
                )
            );
});
<script src="jquery-1.4.1.min.js" type="text/javascript"></script>
<script src="jquery.validate.js" type="text/javascript"></script>
<script src="jquery.validate.unobtrusive.js" type="text/javascript"></script>
<script type="text/javascript">
    (function ($) {
        $.validator.unobtrusive.adapters.add('greaterthanorequaldate', 
                                             ['other'], function (options) {
            var getModelPrefix = function (fieldName) {
                return fieldName.substr(0, fieldName.lastIndexOf(".") + 1);
            };

            var appendModelPrefix = function (value, prefix) {
                if (value.indexOf("*.") === 0) {
                    value = value.replace("*.", prefix);
                }
                return value;
            }

            var prefix          = getModelPrefix(options.element.name),
                other           = options.params.other,
                fullOtherName   = appendModelPrefix(other, prefix),
            element = $(options.form).find(":input[name=" + fullOtherName + 
                                                        "]")[0];

            options.rules['greaterthanorequaldate'] = element;
            if (options.message != null) {
                options.messages['greaterthanorequaldate'] = options.message;
            }
        });
型号

public class PersonValidator : AbstractValidator<Person>
{
    public PersonValidator()
    {
        RuleFor(x => x.FromDate)
            .NotEmpty()
            .WithMessage("Date is required!")
            .Must(BeAValidDate)
            .WithMessage("Invalid Date");
    }

    private bool BeAValidDate(String value)
    {
        DateTime date;
        return DateTime.TryParse(value, out date);
    }
}
[Validator(typeof(MyViewModelValidator))]
public class MyViewModel
{
    [Display(Name = "Start date")]
    [DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", 
                                                  ApplyFormatInEditMode = true)]
    public DateTime StartDate { get; set; }

    [DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", 
                                                  ApplyFormatInEditMode = true)]
    public DateTime DateToCompareAgainst { get; set; }
}
规则

public class MyViewModelValidator : AbstractValidator<MyViewModel>
{
    public MyViewModelValidator()
    {
        RuleFor(x => x.StartDate)
            .GreaterThanOrEqualTo(x => x.DateToCompareAgainst)
            .WithMessage("Invalid start date");
    }
}
查看

@using (Html.BeginForm("Index", "Person", FormMethod.Post))
{   
    @Html.LabelFor(x => x.FromDate)
    @Html.EditorFor(x => x.FromDate)
    @Html.ValidationMessageFor(x => x.FromDate)

    <input type="submit" name="Submit" value="Submit" />
}
@using (Html.BeginForm("Index", "Person", FormMethod.Post, 
                                                new { id = "FormSubmit" }))
{   
    @Html.Hidden("DateToCompareAgainst", Model.DateToCompareAgainst);      
    @Html.LabelFor(x => x.StartDate)
    @Html.EditorFor(x => x.StartDate)
    @Html.ValidationMessageFor(x => x.StartDate)
    <button type="submit">
        OK</button>
}
@使用(Html.BeginForm(“Index”、“Person”、FormMethod.Post、,
新的{id=“FormSubmit”})
{   
@隐藏(“DateToCompareAgainst”,Model.DateToCompareAgainst);
@LabelFor(x=>x.StartDate)
@EditorFor(x=>x.StartDate)
@Html.ValidationMessageFor(x=>x.StartDate)
好啊
}
脚本

FluentValidationModelValidatorProvider.Configure(x =>
{
    x.Add(typeof(GreaterThanOrEqualValidator), 
            (metadata, Context, rule, validator) => 
                new LessThanOrEqualToFluentValidationPropertyValidator
                (
                    metadata, Context, rule, validator
                )
            );
});
<script src="jquery-1.4.1.min.js" type="text/javascript"></script>
<script src="jquery.validate.js" type="text/javascript"></script>
<script src="jquery.validate.unobtrusive.js" type="text/javascript"></script>
<script type="text/javascript">
    (function ($) {
        $.validator.unobtrusive.adapters.add('greaterthanorequaldate', 
                                             ['other'], function (options) {
            var getModelPrefix = function (fieldName) {
                return fieldName.substr(0, fieldName.lastIndexOf(".") + 1);
            };

            var appendModelPrefix = function (value, prefix) {
                if (value.indexOf("*.") === 0) {
                    value = value.replace("*.", prefix);
                }
                return value;
            }

            var prefix          = getModelPrefix(options.element.name),
                other           = options.params.other,
                fullOtherName   = appendModelPrefix(other, prefix),
            element = $(options.form).find(":input[name=" + fullOtherName + 
                                                        "]")[0];

            options.rules['greaterthanorequaldate'] = element;
            if (options.message != null) {
                options.messages['greaterthanorequaldate'] = options.message;
            }
        });

(函数($){
$.validator.unobtrusive.adapters.add('greaterthanorequaldate',
['other'],函数(选项){
var getModelPrefix=函数(字段名){
返回fieldName.substr(0,fieldName.lastIndexOf(“.”+1);
};
var appendModelPrefix=函数(值,前缀){
if(value.indexOf(“*”)==0){
值=值。替换(“*”,前缀);
}
返回值;
}
var prefix=getModelPrefix(options.element.name),
其他=options.params.other,
fullOtherName=appendModelPrefix(其他,前缀),
element=$(options.form).find(“:input[name=“+fullOtherName+
"]")[0];
options.rules['greaterthanorequaldate']=元素;
如果(options.message!=null){
options.messages['greaterthanorequaldate']=options.message;
}
});

$.validator.addMethod('greaterthanorequaldate',
函数(值、元素、参数){
var日期=新日期(值);
var dateToCompareAgainst=新日期($(params).val());
if(isNaN(date.getTime())| | isNaN(dateToCompareAgainst.getTime()){
返回false;
}
返回日期>=dateToCompareAgainst;
});
})(jQuery);

您是否在web.config中激活了客户端和非侵入性验证?是否设置了FluentVali